diff options
| -rw-r--r-- | boot/parse.c | 500 | ||||
| -rw-r--r-- | boot/transpile.c | 116 | ||||
| -rw-r--r-- | boot/tree.c | 526 | ||||
| -rw-r--r-- | boot/visit.c | 652 |
4 files changed, 897 insertions, 897 deletions
diff --git a/boot/parse.c b/boot/parse.c index ea6b06b..157b73d 100644 --- a/boot/parse.c +++ b/boot/parse.c @@ -379,8 +379,8 @@ parser_panic(struct Parser* p) } } -struct Statement* parser_statement(struct Parser* p, struct Parser_Error* error); -struct Expression* parser_expression(struct Parser* p, struct Parser_Error* error); +struct Tree_Statement* parser_statement(struct Parser* p, struct Parser_Error* error); +struct Tree_Expression* parser_expression(struct Parser* p, struct Parser_Error* error); void parser_end_statement(struct Parser* p, struct Parser_Error* error) @@ -393,24 +393,24 @@ parser_end_statement(struct Parser* p, struct Parser_Error* error) parser_next(p); } -struct Block_Node +struct Tree_Block parser_block_node(struct Parser* p, struct Parser_Error* error) { struct Token start_token = - CHECK_RETURN(parser_need(p, TOKEN_CURLY_OPEN, error), struct Block_Node); + CHECK_RETURN(parser_need(p, TOKEN_CURLY_OPEN, error), struct Tree_Block); parser_unglue(p); - struct Statement* head = nil; - struct Statement* current = nil; + struct Tree_Statement* head = nil; + struct Tree_Statement* current = nil; while (!parser_probe(p, TOKEN_CURLY_CLOSE)) { - struct Statement* statement = CHECK_RETURN(parser_statement(p, error), struct Block_Node); + struct Tree_Statement* statement = CHECK_RETURN(parser_statement(p, error), struct Tree_Block); // statement ending token isn't required when the block ends on the same line, // as in e.g.: `if (true) { print("yes") }` if (!parser_probe(p, TOKEN_CURLY_CLOSE)) - CHECK_RETURN(parser_end_statement(p, error), struct Block_Node); + CHECK_RETURN(parser_end_statement(p, error), struct Tree_Block); if (!head) { head = statement; @@ -421,25 +421,25 @@ parser_block_node(struct Parser* p, struct Parser_Error* error) } struct Token end_token = - CHECK_RETURN(parser_need(p, TOKEN_CURLY_CLOSE, error), struct Block_Node); + CHECK_RETURN(parser_need(p, TOKEN_CURLY_CLOSE, error), struct Tree_Block); struct Span span = span_merge(start_token.span, end_token.span); - return (struct Block_Node){ + return (struct Tree_Block){ .statements = head, .span = span, .location = start_token.location, }; } -struct Type_Node* parser_node_type(struct Parser* p, struct Parser_Error* error); +struct Tree_Type* parser_node_type(struct Parser* p, struct Parser_Error* error); -struct Function_Header_Node +struct Tree_Function_Header parser_function_header_node(struct Parser* p, struct Parser_Error* error) { struct Token open_parameters_token = - CHECK_RETURN(parser_need(p, TOKEN_ROUND_OPEN, error), struct Function_Header_Node); + CHECK_RETURN(parser_need(p, TOKEN_ROUND_OPEN, error), struct Tree_Function_Header); - struct Function_Header_Node header = { 0 }; + struct Tree_Function_Header header = { 0 }; while (!parser_probe(p, TOKEN_ROUND_CLOSE)) { // TODO: correctly output parameter spans bool variadic = false; @@ -449,14 +449,14 @@ parser_function_header_node(struct Parser* p, struct Parser_Error* error) } struct Token name_token = - CHECK_RETURN(parser_need(p, TOKEN_NAME, error), struct Function_Header_Node); + CHECK_RETURN(parser_need(p, TOKEN_NAME, error), struct Tree_Function_Header); struct String name = name_token.value.name; - struct Type_Node* type; + struct Tree_Type* type; if (!parser_probe(p, TOKEN_ROUND_CLOSE) && !parser_probe(p, TOKEN_COMMA)) { - type = CHECK_RETURN(parser_node_type(p, error), struct Function_Header_Node); + type = CHECK_RETURN(parser_node_type(p, error), struct Tree_Function_Header); } else { - type = type_node_none(name_token.span, name_token.location); + type = tree_type_none(name_token.span, name_token.location); } type->value_name = name; @@ -489,18 +489,18 @@ parser_function_header_node(struct Parser* p, struct Parser_Error* error) // check away. if (token_is(&next, TOKEN_CURLY_OPEN) && token_is(&further, TOKEN_NEWLINE)) return header; - header.return_type = CHECK_RETURN(parser_node_type(p, error), struct Function_Header_Node); + header.return_type = CHECK_RETURN(parser_node_type(p, error), struct Tree_Function_Header); header.span = span_merge(header.span, header.return_type->span); } return header; } -struct Argument_Group_Node +struct Tree_Argument_Group parser_argument_group_node(struct Parser* p, struct Parser_Error* error) { Array(struct String) argument_names = array_new(struct String, 32); - struct Expression *arguments_head = nil, *arguments_current = nil; + struct Tree_Expression *arguments_head = nil, *arguments_current = nil; for (;;) { // check if we have a named argument. struct String name = string_empty(); @@ -511,8 +511,8 @@ parser_argument_group_node(struct Parser* p, struct Parser_Error* error) name = name_token.value.name; } - struct Expression* argument = - CHECK_RETURN(parser_expression(p, error), struct Argument_Group_Node); + struct Tree_Expression* argument = + CHECK_RETURN(parser_expression(p, error), struct Tree_Argument_Group); if (!arguments_head) arguments_head = argument; else @@ -530,12 +530,12 @@ parser_argument_group_node(struct Parser* p, struct Parser_Error* error) } } - return (struct Argument_Group_Node){ + return (struct Tree_Argument_Group){ .arguments = arguments_head, .argument_names = argument_names }; } -struct Bare_Declaration_Node +struct Tree_Bare_Declaration parser_bare_declaration_node(struct Parser* p, struct Parser_Error* error) { Array(struct String) names = array_new(struct String, 16); @@ -544,7 +544,7 @@ parser_bare_declaration_node(struct Parser* p, struct Parser_Error* error) struct Cursor location = parser_peek(p).location; for (;;) { struct Token name_token = - CHECK_RETURN(parser_need(p, TOKEN_NAME, error), struct Bare_Declaration_Node); + CHECK_RETURN(parser_need(p, TOKEN_NAME, error), struct Tree_Bare_Declaration); span = span_is_empty(span) ? name_token.span : span_merge(span, name_token.span); array_push(&names, &name_token.value.name); @@ -555,12 +555,12 @@ parser_bare_declaration_node(struct Parser* p, struct Parser_Error* error) } // for now, type is always required. - struct Type_Node* type = CHECK_RETURN(parser_node_type(p, error), struct Bare_Declaration_Node); - CHECK_RETURN(parser_need(p, TOKEN_ASSIGN, error), struct Bare_Declaration_Node); - struct Expression* initializer = - CHECK_RETURN(parser_expression(p, error), struct Bare_Declaration_Node); + struct Tree_Type* type = CHECK_RETURN(parser_node_type(p, error), struct Tree_Bare_Declaration); + CHECK_RETURN(parser_need(p, TOKEN_ASSIGN, error), struct Tree_Bare_Declaration); + struct Tree_Expression* initializer = + CHECK_RETURN(parser_expression(p, error), struct Tree_Bare_Declaration); - return (struct Bare_Declaration_Node){ + return (struct Tree_Bare_Declaration){ .names = names, .initializer = initializer, .type = type, @@ -570,27 +570,27 @@ parser_bare_declaration_node(struct Parser* p, struct Parser_Error* error) }; } -struct Type_Node* +struct Tree_Type* parser_node_type_name(struct Parser* p, struct Parser_Error* error) { struct Token name_token = CHECK(parser_need(p, TOKEN_NAME, error)); - return type_node_new( - TYPE_NODE_NAME, (union Type_Node_Value){ .name = { name_token.value.name } }, + return tree_type_new( + TREE_TYPE_NAME, (union Tree_Type_Value){ .name = { name_token.value.name } }, name_token.span, name_token.location); } -struct Type_Node* +struct Tree_Type* parser_node_type_structure(struct Parser* p, struct Parser_Error* error) { struct Token open_token = CHECK(parser_need(p, TOKEN_CURLY_OPEN, error)); parser_unglue(p); - struct Type_Node *head = nil, *current = nil; + struct Tree_Type *head = nil, *current = nil; while (!parser_probe(p, TOKEN_CURLY_CLOSE)) { struct Token field_name_token = CHECK(parser_need(p, TOKEN_NAME, error)); - struct Type_Node* field_type = CHECK(parser_node_type(p, error)); + struct Tree_Type* field_type = CHECK(parser_node_type(p, error)); field_type->value_name = field_name_token.value.name; if (!head) @@ -607,12 +607,12 @@ parser_node_type_structure(struct Parser* p, struct Parser_Error* error) struct Token close_token = CHECK(parser_need(p, TOKEN_CURLY_CLOSE, error)); struct Span span = span_merge(open_token.span, close_token.span); - return type_node_new( - TYPE_NODE_STRUCTURE, (union Type_Node_Value){ .structure = { head } }, span, + return tree_type_new( + TREE_TYPE_STRUCTURE, (union Tree_Type_Value){ .structure = { head } }, span, open_token.location); } -struct Type_Node* +struct Tree_Type* parser_node_type_variant(struct Parser* p, struct Parser_Error* error) { struct Token variant_token = CHECK(parser_need(p, TOKEN_WORD_VARIANT, error)); @@ -620,12 +620,12 @@ parser_node_type_variant(struct Parser* p, struct Parser_Error* error) parser_unglue(p); - struct Type_Node *head = nil, *current = nil; + struct Tree_Type *head = nil, *current = nil; while (!parser_probe(p, TOKEN_CURLY_CLOSE)) { struct Token variant_name_token = CHECK(parser_need(p, TOKEN_NAME, error)); struct String variant_name = variant_name_token.value.name; - struct Type_Node* backing_type = nil; + struct Tree_Type* backing_type = nil; struct Token next = parser_peek(p); bool has_backing_type = @@ -635,7 +635,7 @@ parser_node_type_variant(struct Parser* p, struct Parser_Error* error) if (has_backing_type) { backing_type = CHECK(parser_node_type(p, error)); } else { - backing_type = type_node_none(variant_name_token.span, variant_name_token.location); + backing_type = tree_type_none(variant_name_token.span, variant_name_token.location); } backing_type->value_name = variant_name; @@ -654,24 +654,24 @@ parser_node_type_variant(struct Parser* p, struct Parser_Error* error) struct Token close_token = CHECK(parser_need(p, TOKEN_CURLY_CLOSE, error)); struct Span span = span_merge(variant_token.span, close_token.span); - return type_node_new( - TYPE_NODE_VARIANT, (union Type_Node_Value){ .variant = { head } }, span, + return tree_type_new( + TREE_TYPE_VARIANT, (union Tree_Type_Value){ .variant = { head } }, span, variant_token.location); } -struct Type_Node* +struct Tree_Type* parser_node_type_function(struct Parser* p, struct Parser_Error* error) { struct Token fun_token = CHECK(parser_need(p, TOKEN_WORD_FUN, error)); - struct Function_Header_Node header = CHECK(parser_function_header_node(p, error)); + struct Tree_Function_Header header = CHECK(parser_function_header_node(p, error)); struct Span span = span_merge(fun_token.span, header.span); - return type_node_new( - TYPE_NODE_FUNCTION, (union Type_Node_Value){ .function = { header } }, span, + return tree_type_new( + TREE_TYPE_FUNCTION, (union Tree_Type_Value){ .function = { header } }, span, fun_token.location); } -struct Type_Node* +struct Tree_Type* parser_node_type_class(struct Parser* p, struct Parser_Error* error) { struct Token class_token = CHECK(parser_need(p, TOKEN_WORD_CLASS, error)); @@ -679,16 +679,16 @@ parser_node_type_class(struct Parser* p, struct Parser_Error* error) parser_unglue(p); - struct Type_Node *head = nil, *current = nil; + struct Tree_Type *head = nil, *current = nil; while (!parser_probe(p, TOKEN_CURLY_CLOSE)) { struct Token method_name_token = CHECK(parser_need(p, TOKEN_NAME, error)); struct String method_name = method_name_token.value.name; - struct Function_Header_Node header = CHECK(parser_function_header_node(p, error)); + struct Tree_Function_Header header = CHECK(parser_function_header_node(p, error)); // allocate a new type node for the method type, // for the sake of consistency and the built-in type node linked list. - struct Type_Node* method_type = type_node_new( - TYPE_NODE_FUNCTION, (union Type_Node_Value){ .function = { header } }, header.span, + struct Tree_Type* method_type = tree_type_new( + TREE_TYPE_FUNCTION, (union Tree_Type_Value){ .function = { header } }, header.span, header.location); method_type->value_name = method_name; @@ -705,18 +705,18 @@ parser_node_type_class(struct Parser* p, struct Parser_Error* error) struct Token close_token = CHECK(parser_need(p, TOKEN_CURLY_CLOSE, error)); struct Span span = span_merge(class_token.span, close_token.span); - return type_node_new( - TYPE_NODE_CLASS, (union Type_Node_Value){ .class = { head } }, span, class_token.location); + return tree_type_new( + TREE_TYPE_CLASS, (union Tree_Type_Value){ .class = { head } }, span, class_token.location); } -struct Type_Node* +struct Tree_Type* parser_node_type_tuple(struct Parser* p, struct Parser_Error* error) { struct Token open_token = CHECK(parser_need(p, TOKEN_ROUND_OPEN, error)); - struct Type_Node *head = nil, *current = nil; + struct Tree_Type *head = nil, *current = nil; while (!parser_probe(p, TOKEN_ROUND_CLOSE)) { - struct Type_Node* type = CHECK(parser_node_type(p, error)); + struct Tree_Type* type = CHECK(parser_node_type(p, error)); if (!head) head = type; @@ -732,69 +732,69 @@ parser_node_type_tuple(struct Parser* p, struct Parser_Error* error) struct Token close_token = CHECK(parser_need(p, TOKEN_ROUND_CLOSE, error)); struct Span span = span_merge(open_token.span, close_token.span); - return type_node_new( - TYPE_NODE_TUPLE, (union Type_Node_Value){ .tuple = { head } }, span, open_token.location); + return tree_type_new( + TREE_TYPE_TUPLE, (union Tree_Type_Value){ .tuple = { head } }, span, open_token.location); } -struct Type_Node* +struct Tree_Type* parser_node_type_array_or_map(struct Parser* p, struct Parser_Error* error) { struct Token open_token = CHECK(parser_need(p, TOKEN_SQUARE_OPEN, error)); - struct Type_Node* element_or_key_type = parser_node_type(p, error); + struct Tree_Type* element_or_key_type = parser_node_type(p, error); if (!element_or_key_type) { parser_error_wrap(error, PARSER_ERROR_EXPECTED_TYPE); return nil; } - enum Type_Node_Type type; - union Type_Node_Value value; + enum Tree_Type_Type type; + union Tree_Type_Value value; if (parser_probe(p, TOKEN_ASSIGN)) { // this is a map type, e.g. `[string = int]` parser_next(p); // consume the assignment token - struct Type_Node* key_type = element_or_key_type; - struct Type_Node* value_type = parser_node_type(p, error); + struct Tree_Type* key_type = element_or_key_type; + struct Tree_Type* value_type = parser_node_type(p, error); if (!value_type) { parser_error_wrap(error, PARSER_ERROR_EXPECTED_TYPE); return nil; } - type = TYPE_NODE_MAP; - value.map = (struct Type_Node_Map){ + type = TREE_TYPE_MAP; + value.map = (struct Tree_Type_Map){ .key_type = key_type, .value_type = value_type, }; } else { // this is an array type, e.g. `[int]` - type = TYPE_NODE_ARRAY; - value.array = (struct Type_Node_Array){ .element_type = element_or_key_type }; + type = TREE_TYPE_ARRAY; + value.array = (struct Tree_Type_Array){ .element_type = element_or_key_type }; } struct Token close_token = CHECK(parser_need(p, TOKEN_SQUARE_CLOSE, error)); struct Span span = span_merge(open_token.span, close_token.span); - return type_node_new(type, value, span, open_token.location); + return tree_type_new(type, value, span, open_token.location); } -struct Type_Node* +struct Tree_Type* parser_node_type_reference(struct Parser* p, struct Parser_Error* error) { struct Token ampersand_token = CHECK(parser_need(p, TOKEN_AMPERSAND, error)); - struct Type_Node* referenced_type = CHECK(parser_node_type(p, error)); + struct Tree_Type* referenced_type = CHECK(parser_node_type(p, error)); if (!referenced_type) { parser_error(error, PARSER_ERROR_EXPECTED_TYPE, ampersand_token); return nil; } struct Span span = span_merge(ampersand_token.span, referenced_type->span); - return type_node_new( - TYPE_NODE_REFERENCE, (union Type_Node_Value){ .reference = { referenced_type } }, span, + return tree_type_new( + TREE_TYPE_REFERENCE, (union Tree_Type_Value){ .reference = { referenced_type } }, span, ampersand_token.location); } -struct Type_Node* +struct Tree_Type* parser_node_type_inner(struct Parser* p, struct Parser_Error* error) { struct Token token = parser_peek(p); @@ -821,34 +821,34 @@ parser_node_type_inner(struct Parser* p, struct Parser_Error* error) } } -struct Type_Node* +struct Tree_Type* parser_node_type(struct Parser* p, struct Parser_Error* error) { - struct Type_Node* type = CHECK(parser_node_type_inner(p, error)); + struct Tree_Type* type = CHECK(parser_node_type_inner(p, error)); // check if the type is followed by a `?`, which means it may be nil. if (parser_probe(p, TOKEN_QUESTION)) { parser_next(p); // consume the question mark - type = type_node_new( - TYPE_NODE_MAYBE, (union Type_Node_Value){ .maybe = { type } }, type->span, + type = tree_type_new( + TREE_TYPE_MAYBE, (union Tree_Type_Value){ .maybe = { type } }, type->span, type->location); } return type; } -struct Pragma_Node* +struct Tree_Pragma* parser_pragma_node(struct Parser* p, struct Parser_Error* error) { // `| c_header "stdio.h"` // `| clone always, printable CHECK(parser_need(p, TOKEN_PIPE, error)); - struct Pragma_Node *head = nil, *current = nil; + struct Tree_Pragma *head = nil, *current = nil; struct Token token = parser_peek(p); while (!token_ends_statement(&token)) { struct Token pragma_token = CHECK(parser_need(p, TOKEN_NAME, error)); - enum Pragma_Type pragma_type = pragma_type_from_string(pragma_token.value.name); + enum Tree_Pragma_Type pragma_type = tree_pragma_type_from_string(pragma_token.value.name); if (!pragma_type) { parser_error(error, PARSER_ERROR_EXPECTED_PRAGMA, pragma_token); return nil; @@ -859,29 +859,29 @@ parser_pragma_node(struct Parser* p, struct Parser_Error* error) // parse the arguments until either statement end or comma // arguments can either be numbers, names or strings. uint argument_index = 0; - struct Pragma_Argument arguments[PRAGMA_ARGUMENT_MAX] = { 0 }; + struct Tree_Pragma_Argument arguments[TREE_PRAGMA_ARGUMENT_MAX] = { 0 }; token = parser_peek(p); while (!token_ends_statement(&token)) { - check(argument_index < PRAGMA_ARGUMENT_MAX, "too many pragma arguments"); - struct Pragma_Argument* argument = &arguments[argument_index]; + check(argument_index < TREE_PRAGMA_ARGUMENT_MAX, "too many pragma arguments"); + struct Tree_Pragma_Argument* argument = &arguments[argument_index]; union Token_Value* v = &token.value; switch (token.kind) { case TOKEN_LITERAL_INTEGER: - argument->type = PRAGMA_ARGUMENT_NUMBER; + argument->type = TREE_PRAGMA_ARGUMENT_NUMBER; argument->value.number = v->literal_integer; break; case TOKEN_LITERAL_FLOAT: - argument->type = PRAGMA_ARGUMENT_DECIMAL; + argument->type = TREE_PRAGMA_ARGUMENT_DECIMAL; argument->value.decimal = v->literal_float; break; case TOKEN_LITERAL_STRING: - argument->type = PRAGMA_ARGUMENT_NAME_OR_STRING; + argument->type = TREE_PRAGMA_ARGUMENT_NAME_OR_STRING; argument->value.name_or_string = v->literal_string; break; case TOKEN_NAME: - argument->type = PRAGMA_ARGUMENT_NAME_OR_STRING; + argument->type = TREE_PRAGMA_ARGUMENT_NAME_OR_STRING; argument->value.name_or_string = v->name; break; default: @@ -901,7 +901,7 @@ parser_pragma_node(struct Parser* p, struct Parser_Error* error) if (token_ends_statement(&token)) { break; } } - struct Pragma_Node* pragma = pragma_node_new(pragma_type, span, pragma_token.location); + struct Tree_Pragma* pragma = tree_pragma_new(pragma_type, span, pragma_token.location); pragma->argument_count = argument_index; memcpy(pragma->arguments, arguments, sizeof(arguments)); @@ -916,81 +916,81 @@ parser_pragma_node(struct Parser* p, struct Parser_Error* error) return head; } -struct Expression* +struct Tree_Expression* parser_expression_primary_name(struct Parser* p, struct Parser_Error* error) { struct Token token = CHECK(parser_need(p, TOKEN_NAME, error)); - union Expression_Value value = { .name = { token.value.name } }; - return expression_new(EXPRESSION_NAME, value, token.span, token.location); + union Tree_Expression_Value value = { .name = { token.value.name } }; + return tree_expression_new(TREE_EXPRESSION_NAME, value, token.span, token.location); } -struct Expression* +struct Tree_Expression* parser_expression_primary_integer(struct Parser* p, struct Parser_Error* error) { struct Token token = CHECK(parser_need(p, TOKEN_LITERAL_INTEGER, error)); - union Expression_Value value = { .integer_literal = { token.value.literal_integer } }; - return expression_new(EXPRESSION_INTEGER_LITERAL, value, token.span, token.location); + union Tree_Expression_Value value = { .integer_literal = { token.value.literal_integer } }; + return tree_expression_new(TREE_EXPRESSION_INTEGER_LITERAL, value, token.span, token.location); } -struct Expression* +struct Tree_Expression* parser_expression_primary_float(struct Parser* p, struct Parser_Error* error) { struct Token token = CHECK(parser_need(p, TOKEN_LITERAL_FLOAT, error)); - union Expression_Value value = { .float_literal = { token.value.literal_float } }; - return expression_new(EXPRESSION_FLOAT_LITERAL, value, token.span, token.location); + union Tree_Expression_Value value = { .float_literal = { token.value.literal_float } }; + return tree_expression_new(TREE_EXPRESSION_FLOAT_LITERAL, value, token.span, token.location); } -struct Expression* +struct Tree_Expression* parser_expression_primary_string(struct Parser* p, struct Parser_Error* error) { struct Token token = CHECK(parser_need(p, TOKEN_LITERAL_STRING, error)); - union Expression_Value value = { .string_literal = { token.value.literal_string } }; - return expression_new(EXPRESSION_STRING_LITERAL, value, token.span, token.location); + union Tree_Expression_Value value = { .string_literal = { token.value.literal_string } }; + return tree_expression_new(TREE_EXPRESSION_STRING_LITERAL, value, token.span, token.location); } -struct Expression* +struct Tree_Expression* parser_expression_primary_boolean(struct Parser* p, struct Parser_Error* error) { struct Token token = parser_next(p); check(token.kind == TOKEN_WORD_TRUE || token.kind == TOKEN_WORD_FALSE, "expected boolean literal"); bool literal = token.kind == TOKEN_WORD_TRUE; - union Expression_Value expr_value = { .bool_literal = { literal } }; - return expression_new(EXPRESSION_BOOLEAN_LITERAL, expr_value, token.span, token.location); + union Tree_Expression_Value expr_value = { .bool_literal = { literal } }; + return tree_expression_new(TREE_EXPRESSION_BOOLEAN_LITERAL, expr_value, token.span, token.location); } -struct Expression* +struct Tree_Expression* parser_expression_primary_group(struct Parser* p, struct Parser_Error* error) { struct Token start_token = CHECK(parser_need(p, TOKEN_ROUND_OPEN, error)); - struct Expression* expression = CHECK(parser_expression(p, error)); + struct Tree_Expression* expression = CHECK(parser_expression(p, error)); struct Token end_token = CHECK(parser_need(p, TOKEN_ROUND_CLOSE, error)); struct Span span = span_merge(start_token.span, end_token.span); - union Expression_Value value = { .group = { expression } }; - return expression_new(EXPRESSION_GROUP, value, span, start_token.location); + union Tree_Expression_Value value = { .group = { expression } }; + return tree_expression_new(TREE_EXPRESSION_GROUP, value, span, start_token.location); } -struct Expression* +struct Tree_Expression* parser_expression_function(struct Parser* p, struct Parser_Error* error) { struct Token fun_token = CHECK(parser_need(p, TOKEN_WORD_FUN, error)); - struct Expression_Function fun = { 0 }; + struct Tree_Expression_Function fun = { 0 }; fun.header = CHECK(parser_function_header_node(p, error)); fun.body = CHECK(parser_block_node(p, error)); - return expression_new( - EXPRESSION_FUNCTION, (union Expression_Value){ .function = fun }, + return tree_expression_new( + TREE_EXPRESSION_FUNCTION, (union Tree_Expression_Value){ .function = fun }, span_merge(fun_token.span, fun.body.span), fun_token.location); } -struct Expression* +struct Tree_Expression* parser_expression_type(struct Parser* p, struct Parser_Error* error) { struct Token start_token = parser_peek(p); - struct Type_Node* type = nil; + struct Tree_Type* type = nil; switch (start_token.kind) { case TOKEN_WORD_TYPE: parser_next(p); // skip the `type` keyword. @@ -1007,11 +1007,11 @@ parser_expression_type(struct Parser* p, struct Parser_Error* error) } struct Span span = span_merge(start_token.span, type->span); - return expression_new( - EXPRESSION_TYPE, (union Expression_Value){ .type = { type } }, span, start_token.location); + return tree_expression_new( + TREE_EXPRESSION_TYPE, (union Tree_Expression_Value){ .type = { type } }, span, start_token.location); } -struct Expression* +struct Tree_Expression* parser_expression_primary(struct Parser* p, struct Parser_Error* error) { struct Token token = parser_peek(p); @@ -1043,9 +1043,9 @@ parser_expression_primary(struct Parser* p, struct Parser_Error* error) } } -struct Expression* +struct Tree_Expression* parser_expression_postfix_member( - struct Parser* p, struct Expression* subject, struct Parser_Error* error) + struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error) { CHECK(parser_need(p, TOKEN_DOT, error)); @@ -1053,18 +1053,18 @@ parser_expression_postfix_member( struct String name = name_token.value.name; struct Span span = span_merge(subject->span, name_token.span); - union Expression_Value value = { .member = { subject, name } }; - return expression_new(EXPRESSION_MEMBER, value, span, name_token.location); + union Tree_Expression_Value value = { .member = { subject, name } }; + return tree_expression_new(TREE_EXPRESSION_MEMBER, value, span, name_token.location); } -struct Expression* +struct Tree_Expression* parser_expression_postfix_call( - struct Parser* p, struct Expression* subject, struct Parser_Error* error) + struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error) { CHECK(parser_need(p, TOKEN_ROUND_OPEN, error)); parser_unglue(p); - struct Argument_Group_Node argument_group = parser_argument_group_node(p, error); + struct Tree_Argument_Group argument_group = parser_argument_group_node(p, error); if (!parser_error_is_none(error)) { parser_error_wrap(error, PARSER_ERROR_EXPECTED_ARGUMENTS); return nil; @@ -1074,18 +1074,18 @@ parser_expression_postfix_call( struct Token close_token = CHECK(parser_need(p, TOKEN_ROUND_CLOSE, error)); struct Span span = span_merge(subject->span, close_token.span); - union Expression_Value value = { .call = { subject, argument_group } }; - return expression_new(EXPRESSION_CALL, value, span, close_token.location); + union Tree_Expression_Value value = { .call = { subject, argument_group } }; + return tree_expression_new(TREE_EXPRESSION_CALL, value, span, close_token.location); } -struct Expression* +struct Tree_Expression* parser_expression_postfix_construct( - struct Parser* p, struct Expression* subject, struct Parser_Error* error) + struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error) { CHECK(parser_need(p, TOKEN_CURLY_OPEN, error)); parser_unglue(p); - struct Argument_Group_Node argument_group = parser_argument_group_node(p, error); + struct Tree_Argument_Group argument_group = parser_argument_group_node(p, error); if (!parser_error_is_none(error)) { parser_error_wrap(error, PARSER_ERROR_EXPECTED_ARGUMENTS); return nil; @@ -1096,68 +1096,68 @@ parser_expression_postfix_construct( struct Span span = span_merge(subject->span, token.span); // TODO: convert the `subject` expression to a type node? somehow? - union Expression_Value value = { .construct = { subject, argument_group } }; - return expression_new(EXPRESSION_CONSTRUCT, value, span, token.location); + union Tree_Expression_Value value = { .construct = { subject, argument_group } }; + return tree_expression_new(TREE_EXPRESSION_CONSTRUCT, value, span, token.location); } -struct Expression* +struct Tree_Expression* parser_expression_postfix_subscript( - struct Parser* p, struct Expression* subject, struct Parser_Error* error) + struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error) { CHECK(parser_need(p, TOKEN_SQUARE_OPEN, error)); - struct Expression* index = CHECK(parser_expression(p, error)); + struct Tree_Expression* index = CHECK(parser_expression(p, error)); struct Token token = CHECK(parser_need(p, TOKEN_SQUARE_CLOSE, error)); struct Span span = span_merge(subject->span, span_merge(index->span, token.span)); - union Expression_Value value = { .subscript = { subject, index } }; - return expression_new(EXPRESSION_SUBSCRIPT, value, span, token.location); + union Tree_Expression_Value value = { .subscript = { subject, index } }; + return tree_expression_new(TREE_EXPRESSION_SUBSCRIPT, value, span, token.location); } -struct Expression* +struct Tree_Expression* parser_expression_postfix_increment_decrement( - struct Parser* p, struct Expression* subject, struct Parser_Error* error) + struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error) { struct Token token = parser_peek(p); enum Increment_Decrement_Operation operation = increment_decrement_operation_from_token(&token); - struct Expression_Increment_Decrement inc_dec = { + struct Tree_Expression_Increment_Decrement inc_dec = { .prefix = false, .subject = subject, .operation = operation, }; struct Span span = span_merge(subject->span, token.span); - union Expression_Value value = { .increment_decrement = inc_dec }; - return expression_new(EXPRESSION_INCREMENT_DECREMENT, value, span, token.location); + union Tree_Expression_Value value = { .increment_decrement = inc_dec }; + return tree_expression_new(TREE_EXPRESSION_INCREMENT_DECREMENT, value, span, token.location); } -struct Expression* +struct Tree_Expression* parser_expression_postfix_try( - struct Parser* p, struct Expression* subject, struct Parser_Error* error) + struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error) { struct Token question_token = parser_next(p); struct Span span = span_merge(subject->span, question_token.span); - union Expression_Value value = { .try = { subject } }; - return expression_new(EXPRESSION_TRY, value, span, subject->location); + union Tree_Expression_Value value = { .try = { subject } }; + return tree_expression_new(TREE_EXPRESSION_TRY, value, span, subject->location); } -struct Expression* +struct Tree_Expression* parser_expression_postfix_must( - struct Parser* p, struct Expression* subject, struct Parser_Error* error) + struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error) { struct Token bang_token = CHECK(parser_need(p, TOKEN_BANG, error)); struct Span span = span_merge(subject->span, bang_token.span); - union Expression_Value value = { .try = { subject } }; - return expression_new(EXPRESSION_MUST, value, span, subject->location); + union Tree_Expression_Value value = { .try = { subject } }; + return tree_expression_new(TREE_EXPRESSION_MUST, value, span, subject->location); } -struct Expression* +struct Tree_Expression* parser_expression_postfix(struct Parser* p, struct Parser_Error* error) { - struct Expression* expression = CHECK(parser_expression_primary(p, error)); + struct Tree_Expression* expression = CHECK(parser_expression_primary(p, error)); // NOTE: we have to parse all subsequent postfix expressions non-recursively. for (;;) { @@ -1190,16 +1190,16 @@ parser_expression_postfix(struct Parser* p, struct Parser_Error* error) increment_decrement_operation_from_token(&token); if (inc_dec_op) { parser_next(p); - struct Expression_Increment_Decrement inc_dec = { + struct Tree_Expression_Increment_Decrement inc_dec = { .prefix = false, .subject = expression, .operation = inc_dec_op, }; struct Span span = span_merge(expression->span, token.span); - union Expression_Value value = { .increment_decrement = inc_dec }; + union Tree_Expression_Value value = { .increment_decrement = inc_dec }; expression = - expression_new(EXPRESSION_INCREMENT_DECREMENT, value, span, token.location); + tree_expression_new(TREE_EXPRESSION_INCREMENT_DECREMENT, value, span, token.location); continue; } @@ -1207,34 +1207,34 @@ parser_expression_postfix(struct Parser* p, struct Parser_Error* error) } } -struct Expression* +struct Tree_Expression* parser_expression_unary_operation(struct Parser* p, struct Parser_Error* error) { struct Token token = parser_peek(p); enum Unary_Operation operation = unary_operation_from_token(&token); if (operation) { parser_next(p); - struct Expression* operand = CHECK(parser_expression_unary_operation(p, error)); + struct Tree_Expression* operand = CHECK(parser_expression_unary_operation(p, error)); struct Span span = span_merge(token.span, operand->span); - union Expression_Value value = { .unary_operator = { operation, operand } }; - return expression_new(EXPRESSION_UNARY_OPERATION, value, span, token.location); + union Tree_Expression_Value value = { .unary_operator = { operation, operand } }; + return tree_expression_new(TREE_EXPRESSION_UNARY_OPERATION, value, span, token.location); } enum Increment_Decrement_Operation inc_dec_op = increment_decrement_operation_from_token(&token); if (inc_dec_op) { parser_next(p); - struct Expression* subject = CHECK(parser_expression_unary_operation(p, error)); - struct Expression_Increment_Decrement inc_dec = { + struct Tree_Expression* subject = CHECK(parser_expression_unary_operation(p, error)); + struct Tree_Expression_Increment_Decrement inc_dec = { .prefix = true, .subject = subject, .operation = inc_dec_op, }; struct Span span = span_merge(token.span, inc_dec.subject->span); - union Expression_Value value = { .increment_decrement = inc_dec }; - return expression_new(EXPRESSION_INCREMENT_DECREMENT, value, span, token.location); + union Tree_Expression_Value value = { .increment_decrement = inc_dec }; + return tree_expression_new(TREE_EXPRESSION_INCREMENT_DECREMENT, value, span, token.location); } return parser_expression_postfix(p, error); @@ -1243,16 +1243,16 @@ parser_expression_unary_operation(struct Parser* p, struct Parser_Error* error) // given two expressions and some kind of binary operation between them, // merge them into a single binary expression, with attention to operator precedence // and associativity. -struct Expression_Binary_Operator +struct Tree_Expression_Binary_Operator parser_merge_into_single_binary_expression( - struct Parser* p, struct Expression* left, enum Binary_Operation operation, - struct Expression* right) + struct Parser* p, struct Tree_Expression* left, enum Binary_Operation operation, + struct Tree_Expression* right) { // NOTE: due to the parser structure, the left expression is never a binary operation // so we can worry about fixing up the right side only. - check(left->kind != EXPRESSION_BINARY_OPERATION, "left expression is a binary operation"); - if (right->kind == EXPRESSION_BINARY_OPERATION) { - struct Expression_Binary_Operator right_binary = right->value.binary_operator; + check(left->kind != TREE_EXPRESSION_BINARY_OPERATION, "left expression is a binary operation"); + if (right->kind == TREE_EXPRESSION_BINARY_OPERATION) { + struct Tree_Expression_Binary_Operator right_binary = right->value.binary_operator; uint right_precedence = binary_operation_precedence(right_binary.operation); uint precedence = binary_operation_precedence(operation); @@ -1268,15 +1268,15 @@ parser_merge_into_single_binary_expression( // since we only use static memory, we need to switch the operands around // without allocating more expressions, thus we have to reuse the allocation // slots of the previous expressions. - struct Expression* operands[3] = { + struct Tree_Expression* operands[3] = { left, right_binary.left_operand, right_binary.right_operand }; - struct Expression* slots[2] = { right, right_binary.right_operand }; + struct Tree_Expression* slots[2] = { right, right_binary.right_operand }; - struct Expression_Binary_Operator new_binary_operator = + struct Tree_Expression_Binary_Operator new_binary_operator = parser_merge_into_single_binary_expression(p, operands[0], operation, operands[1]); - *slots[0] = (struct Expression){ - .kind = EXPRESSION_BINARY_OPERATION, + *slots[0] = (struct Tree_Expression){ + .kind = TREE_EXPRESSION_BINARY_OPERATION, .value = { .binary_operator = new_binary_operator }, .span = span_merge(left->span, right->span), .location = left->location @@ -1290,103 +1290,103 @@ parser_merge_into_single_binary_expression( } } - return (struct Expression_Binary_Operator){ + return (struct Tree_Expression_Binary_Operator){ .operation = operation, .left_operand = left, .right_operand = right, }; } -struct Expression* +struct Tree_Expression* parser_expression_binary_operation(struct Parser* p, struct Parser_Error* error) { - struct Expression* left = CHECK(parser_expression_unary_operation(p, error)); + struct Tree_Expression* left = CHECK(parser_expression_unary_operation(p, error)); struct Token token = parser_peek(p); enum Binary_Operation operation = binary_operation_from_token(&token); if (operation) { parser_next(p); - struct Expression* right = CHECK(parser_expression_binary_operation(p, error)); + struct Tree_Expression* right = CHECK(parser_expression_binary_operation(p, error)); struct Span span = span_merge(left->span, right->span); - struct Expression_Binary_Operator binary_value = + struct Tree_Expression_Binary_Operator binary_value = parser_merge_into_single_binary_expression(p, left, operation, right); - union Expression_Value value = { .binary_operator = binary_value }; - return expression_new(EXPRESSION_BINARY_OPERATION, value, span, left->location); + union Tree_Expression_Value value = { .binary_operator = binary_value }; + return tree_expression_new(TREE_EXPRESSION_BINARY_OPERATION, value, span, left->location); } return left; } -struct Expression* +struct Tree_Expression* parser_expression(struct Parser* p, struct Parser_Error* error) { return parser_expression_binary_operation(p, error); } -struct Statement* +struct Tree_Statement* parser_statement_declaration(struct Parser* p, struct Parser_Error* error) { struct Token declaration_token = parser_next(p); - enum Statement_Declaration_Kind declaration_kind = - statement_declaration_kind_from_token(&declaration_token); + enum Tree_Statement_Declaration_Kind declaration_kind = + tree_statement_declaration_kind_from_token(&declaration_token); check(declaration_kind, "expected valid declaration token"); - struct Bare_Declaration_Node inner = CHECK(parser_bare_declaration_node(p, error)); + struct Tree_Bare_Declaration inner = CHECK(parser_bare_declaration_node(p, error)); struct Span span = span_merge(declaration_token.span, inner.span); - union Statement_Value value = { + union Tree_Statement_Value value = { .declaration = { .kind = declaration_kind, .inner = inner, }, }; - return statement_new(STATEMENT_DECLARATION, value, span, declaration_token.location); + return tree_statement_new(TREE_STATEMENT_DECLARATION, value, span, declaration_token.location); } -struct Statement* +struct Tree_Statement* parser_statement_conditional(struct Parser* p, struct Parser_Error* error) { - struct Statement_Value_Conditional conditional = { 0 }; + struct Tree_Statement_Value_Conditional conditional = { 0 }; struct Token if_token = parser_need(p, TOKEN_WORD_IF, error); // primary if condition + block. CONTEXT_START(in_statement_clause); - struct Expression* if_condition = CHECK(parser_expression(p, error)); + struct Tree_Expression* if_condition = CHECK(parser_expression(p, error)); CONTEXT_END(in_statement_clause); - struct Block_Node then_block = CHECK(parser_block_node(p, error)); - conditional.conditions[conditional.condition_count++] = (struct Statement_Conditional_Branch){ + struct Tree_Block then_block = CHECK(parser_block_node(p, error)); + conditional.conditions[conditional.condition_count++] = (struct Tree_Statement_Conditional_Branch){ .when = if_condition, .then = then_block, }; struct Span span = span_merge(if_token.span, then_block.span); while (parser_probe(p, TOKEN_WORD_ELSE)) { - check(conditional.condition_count < STATEMENT_VALUE_CONDITIONAL_MAX, + check(conditional.condition_count < TREE_STATEMENT_VALUE_CONDITIONAL_MAX, "too many conditional branches"); parser_next(p); - struct Statement_Conditional_Branch branch = { 0 }; + struct Tree_Statement_Conditional_Branch branch = { 0 }; if (parser_probe(p, TOKEN_WORD_IF)) { // else if condition + block. parser_next(p); CONTEXT_START(in_statement_clause); - struct Expression* else_condition = CHECK(parser_expression(p, error)); + struct Tree_Expression* else_condition = CHECK(parser_expression(p, error)); CONTEXT_END(in_statement_clause); - struct Block_Node else_block = CHECK(parser_block_node(p, error)); + struct Tree_Block else_block = CHECK(parser_block_node(p, error)); - branch = (struct Statement_Conditional_Branch){ + branch = (struct Tree_Statement_Conditional_Branch){ .when = else_condition, .then = else_block, }; } else { // else block. - struct Block_Node else_block = CHECK(parser_block_node(p, error)); - branch = (struct Statement_Conditional_Branch){ + struct Tree_Block else_block = CHECK(parser_block_node(p, error)); + branch = (struct Tree_Statement_Conditional_Branch){ .when = nil, .then = else_block, }; @@ -1396,12 +1396,12 @@ parser_statement_conditional(struct Parser* p, struct Parser_Error* error) span = span_merge(span, branch.then.span); } - return statement_new( - STATEMENT_CONDITIONAL, (union Statement_Value){ .conditional = conditional }, span, + return tree_statement_new( + TREE_STATEMENT_CONDITIONAL, (union Tree_Statement_Value){ .conditional = conditional }, span, if_token.location); } -struct Statement* +struct Tree_Statement* parser_statement_for(struct Parser* p, struct Parser_Error* error) { struct Token for_token = CHECK(parser_need(p, TOKEN_WORD_FOR, error)); @@ -1412,13 +1412,13 @@ parser_statement_for(struct Parser* p, struct Parser_Error* error) // a declaration without a signifier like `var` or `let`. CONTEXT_START(in_statement_clause); - struct Bare_Declaration_Node declaration = CHECK(parser_bare_declaration_node(p, error)); + struct Tree_Bare_Declaration declaration = CHECK(parser_bare_declaration_node(p, error)); CONTEXT_END(in_statement_clause); - enum Statement_Loop_Style style = STATEMENT_LOOP_STYLE_FOR_EACH; + enum Tree_Statement_Loop_Style style = TREE_STATEMENT_LOOP_STYLE_FOR_EACH; // c-style semi-semi loop. - struct Expression *condition = nil, *iteration = nil; + struct Tree_Expression *condition = nil, *iteration = nil; if (parser_probe(p, TOKEN_COMMA)) { parser_next(p); condition = CHECK(parser_expression(p, error)); @@ -1428,13 +1428,13 @@ parser_statement_for(struct Parser* p, struct Parser_Error* error) iteration = CHECK(parser_expression(p, error)); CONTEXT_END(in_statement_clause) - style = STATEMENT_LOOP_STYLE_C; + style = TREE_STATEMENT_LOOP_STYLE_C; } - struct Block_Node body = CHECK(parser_block_node(p, error)); + struct Tree_Block body = CHECK(parser_block_node(p, error)); struct Span span = span_merge(for_token.span, body.span); - union Statement_Value value = { + union Tree_Statement_Value value = { .loop = { .style = style, .declaration = declaration, @@ -1443,113 +1443,113 @@ parser_statement_for(struct Parser* p, struct Parser_Error* error) .body = body, }, }; - return statement_new(STATEMENT_LOOP, value, span, for_token.location); + return tree_statement_new(TREE_STATEMENT_LOOP, value, span, for_token.location); } -struct Statement* +struct Tree_Statement* parser_statement_while(struct Parser* p, struct Parser_Error* error) { struct Token while_token = CHECK(parser_need(p, TOKEN_WORD_WHILE, error)); - enum Statement_Loop_Style style = STATEMENT_LOOP_STYLE_ENDLESS; - struct Expression* condition = nil; + enum Tree_Statement_Loop_Style style = TREE_STATEMENT_LOOP_STYLE_ENDLESS; + struct Tree_Expression* condition = nil; if (!parser_probe(p, TOKEN_CURLY_OPEN)) { CONTEXT_START(in_statement_clause); condition = CHECK(parser_expression(p, error)); CONTEXT_END(in_statement_clause); - style = STATEMENT_LOOP_STYLE_WHILE; + style = TREE_STATEMENT_LOOP_STYLE_WHILE; } - struct Block_Node body = CHECK(parser_block_node(p, error)); + struct Tree_Block body = CHECK(parser_block_node(p, error)); struct Span span = span_merge(while_token.span, body.span); - union Statement_Value value = { + union Tree_Statement_Value value = { .loop = { .style = style, .condition = condition, .body = body } }; - return statement_new(STATEMENT_LOOP, value, span, while_token.location); + return tree_statement_new(TREE_STATEMENT_LOOP, value, span, while_token.location); } -struct Statement* +struct Tree_Statement* parser_statement_block(struct Parser* p, struct Parser_Error* error) { - struct Block_Node block = CHECK(parser_block_node(p, error)); - return statement_new( - STATEMENT_BLOCK, (union Statement_Value){ .block = { block } }, block.span, block.location); + struct Tree_Block block = CHECK(parser_block_node(p, error)); + return tree_statement_new( + TREE_STATEMENT_BLOCK, (union Tree_Statement_Value){ .block = { block } }, block.span, block.location); } -struct Statement* +struct Tree_Statement* parser_statement_return(struct Parser* p, struct Parser_Error* error) { struct Token return_token = CHECK(parser_need(p, TOKEN_WORD_RETURN, error)); - struct Expression* value = nil; + struct Tree_Expression* value = nil; if (!token_ends_statement(&return_token)) { value = CHECK(parser_expression(p, error)); } struct Span span = value ? return_token.span : span_merge(return_token.span, value->span); - union Statement_Value statement_value = { .return_value = { value } }; - return statement_new(STATEMENT_RETURN, statement_value, span, return_token.location); + union Tree_Statement_Value statement_value = { .return_value = { value } }; + return tree_statement_new(TREE_STATEMENT_RETURN, statement_value, span, return_token.location); } -struct Statement* +struct Tree_Statement* parser_statement_break(struct Parser* p, struct Parser_Error* error) { struct Token break_token = CHECK(parser_need(p, TOKEN_WORD_BREAK, error)); struct Span span = break_token.span; - return statement_new(STATEMENT_BREAK, (union Statement_Value){ 0 }, span, break_token.location); + return tree_statement_new(TREE_STATEMENT_BREAK, (union Tree_Statement_Value){ 0 }, span, break_token.location); } -struct Statement* +struct Tree_Statement* parser_statement_continue(struct Parser* p, struct Parser_Error* error) { struct Token continue_token = CHECK(parser_need(p, TOKEN_WORD_CONTINUE, error)); struct Span span = continue_token.span; - return statement_new( - STATEMENT_CONTINUE, (union Statement_Value){ 0 }, span, continue_token.location); + return tree_statement_new( + TREE_STATEMENT_CONTINUE, (union Tree_Statement_Value){ 0 }, span, continue_token.location); } -struct Statement* +struct Tree_Statement* parser_statement_defer(struct Parser* p, struct Parser_Error* error) { struct Token defer_token = CHECK(parser_need(p, TOKEN_WORD_DEFER, error)); struct Span span = defer_token.span; - struct Statement_Value_Defer defer = { 0 }; + struct Tree_Statement_Value_Defer defer = { 0 }; if (parser_probe(p, TOKEN_CURLY_OPEN)) { - struct Block_Node block = CHECK(parser_block_node(p, error)); + struct Tree_Block block = CHECK(parser_block_node(p, error)); span = span_merge(span, block.span); defer.block = block; } else { - struct Expression* expression = CHECK(parser_expression(p, error)); + struct Tree_Expression* expression = CHECK(parser_expression(p, error)); span = span_merge(span, expression->span); defer.expression = expression; } - union Statement_Value value = { .defer = defer }; - return statement_new(STATEMENT_DEFER, value, span, defer_token.location); + union Tree_Statement_Value value = { .defer = defer }; + return tree_statement_new(TREE_STATEMENT_DEFER, value, span, defer_token.location); } -struct Statement* +struct Tree_Statement* parser_statement_pragma(struct Parser* p, struct Parser_Error* error) { struct Token pipe_token = parser_peek(p); - struct Pragma_Node* pragma_node = parser_pragma_node(p, error); + struct Tree_Pragma* tree_pragma = parser_pragma_node(p, error); if (!parser_error_is_none(error)) { parser_error_wrap(error, PARSER_ERROR_EXPECTED_PRAGMA); return nil; } struct Span span = {}; - FOR_EACH (struct Pragma_Node*, node, pragma_node) { + FOR_EACH (struct Tree_Pragma*, node, tree_pragma) { span = span_is_empty(span) ? node->span : span_merge(span, node->span); } - union Statement_Value value = { .pragma.inner = pragma_node }; - return statement_new(STATEMENT_PRAGMA, value, span, pipe_token.location); + union Tree_Statement_Value value = { .pragma.inner = tree_pragma }; + return tree_statement_new(TREE_STATEMENT_PRAGMA, value, span, pipe_token.location); } -struct Statement* +struct Tree_Statement* parser_statement(struct Parser* p, struct Parser_Error* error) { struct Token token = parser_peek(p); @@ -1586,12 +1586,12 @@ parser_statement(struct Parser* p, struct Parser_Error* error) break; } - struct Expression* expression = CHECK(parser_expression(p, error)); + struct Tree_Expression* expression = CHECK(parser_expression(p, error)); // expand by one byte to include the statement terminator. struct Span span = span_expand(expression->span, 1); - union Statement_Value value = { .expression.inner = expression }; - return statement_new(STATEMENT_EXPRESSION, value, span, expression->location); + union Tree_Statement_Value value = { .expression.inner = expression }; + return tree_statement_new(TREE_STATEMENT_EXPRESSION, value, span, expression->location); } void @@ -1613,10 +1613,10 @@ parser_do_your_thing(struct Parser* p, struct Tree* tree) struct Parser_Error error; parser_error_none(&error); - struct Statement* head = nil; - struct Statement* current = nil; + struct Tree_Statement* head = nil; + struct Tree_Statement* current = nil; while (!parser_reached_end(p)) { - struct Statement* next = parser_statement(p, &error); + struct Tree_Statement* next = parser_statement(p, &error); parser_handle_error(p, &error); if (next) { diff --git a/boot/transpile.c b/boot/transpile.c index 05aa5c4..798be85 100644 --- a/boot/transpile.c +++ b/boot/transpile.c @@ -130,17 +130,17 @@ transpiler_new(struct Transpiler* transpiler, struct Transpile_Output output) } void -transpiler_visit_type_node(struct Visit* visit, struct Type_Node* node) +transpiler_visit_type_node(struct Tree_Visit* visit, struct Tree_Type* node) { TRANSPILER_PREAMBLE - if (!node || node->type == TYPE_NODE_NONE) { + if (!node || node->type == TREE_TYPE_NONE) { TRANSPILE_WRITE("void"); return; } switch (node->type) { - case TYPE_NODE_NAME: { + case TREE_TYPE_NAME: { struct String name = node->value.name.name; if (strcmp(name.data, "int") == 0) { TRANSPILE_WRITE("integer"); @@ -168,12 +168,12 @@ transpiler_visit_type_node(struct Visit* visit, struct Type_Node* node) } void -transpiler_visit_function_header_node(struct Visit* visit, struct Function_Header_Node* header) +transpiler_visit_function_header_node(struct Tree_Visit* visit, struct Tree_Function_Header* header) { TRANSPILER_PREAMBLE TRANSPILE_WRITE("("); - struct Type_Node* param = header->parameters_type_and_name; + struct Tree_Type* param = header->parameters_type_and_name; if (!param) { TRANSPILE_WRITE("void"); } else { @@ -190,21 +190,21 @@ transpiler_visit_function_header_node(struct Visit* visit, struct Function_Heade } void -transpiler_visit_block_node(struct Visit* visit, struct Block_Node* node) +transpiler_visit_block_node(struct Tree_Visit* visit, struct Tree_Block* node) { TRANSPILER_PREAMBLE TRANSPILE_WRITE("{\n"); - FOR_EACH (struct Statement*, statement, node->statements) { VISIT(visit_statement, statement); } + FOR_EACH (struct Tree_Statement*, statement, node->statements) { VISIT(visit_statement, statement); } TRANSPILE_WRITE("}\n"); } void -transpiler_visit_argument_group_node(struct Visit* visit, struct Argument_Group_Node* node) +transpiler_visit_argument_group_node(struct Tree_Visit* visit, struct Tree_Argument_Group* node) { TRANSPILER_PREAMBLE - struct Expression* arg = node->arguments; + struct Tree_Expression* arg = node->arguments; bool first = true; while (arg) { if (!first) { TRANSPILE_WRITE(", "); } @@ -215,16 +215,16 @@ transpiler_visit_argument_group_node(struct Visit* visit, struct Argument_Group_ } void -transpiler_visit_statement_declaration(struct Visit* visit, struct Statement* stmt) +transpiler_visit_statement_declaration(struct Tree_Visit* visit, struct Tree_Statement* stmt) { TRANSPILER_PREAMBLE - struct Statement_Value_Declaration* declaration = &stmt->value.declaration; - struct Expression* initializer = declaration->inner.initializer; + struct Tree_Statement_Value_Declaration* declaration = &stmt->value.declaration; + struct Tree_Expression* initializer = declaration->inner.initializer; - if (initializer && initializer->kind == EXPRESSION_FUNCTION) { - struct Expression_Function* fun = &initializer->value.function; - struct Function_Header_Node* header = &fun->header; + if (initializer && initializer->kind == TREE_EXPRESSION_FUNCTION) { + struct Tree_Expression_Function* fun = &initializer->value.function; + struct Tree_Function_Header* header = &fun->header; VISIT(visit_type_node, header->return_type); struct String name = *array_at(struct String, &declaration->inner.names, 0); @@ -233,7 +233,7 @@ transpiler_visit_statement_declaration(struct Visit* visit, struct Statement* st TRANSPILE_WRITE(" "); VISIT(visit_block_node, &fun->body); } else { - if (declaration->kind == STATEMENT_DECLARATION_CONSTANT) { + if (declaration->kind == TREE_STATEMENT_DECLARATION_CONSTANT) { TRANSPILE_WRITE("const "); } VISIT(visit_type_node, declaration->inner.type); @@ -247,7 +247,7 @@ transpiler_visit_statement_declaration(struct Visit* visit, struct Statement* st } void -transpiler_visit_statement_return(struct Visit* visit, struct Statement* stmt) +transpiler_visit_statement_return(struct Tree_Visit* visit, struct Tree_Statement* stmt) { TRANSPILER_PREAMBLE @@ -259,13 +259,13 @@ transpiler_visit_statement_return(struct Visit* visit, struct Statement* stmt) } void -transpiler_visit_statement_conditional(struct Visit* visit, struct Statement* stmt) +transpiler_visit_statement_conditional(struct Tree_Visit* visit, struct Tree_Statement* stmt) { TRANSPILER_PREAMBLE - struct Statement_Value_Conditional* conditional = &stmt->value.conditional; + struct Tree_Statement_Value_Conditional* conditional = &stmt->value.conditional; for (uint i = 0; i < conditional->condition_count; ++i) { - struct Statement_Conditional_Branch* branch = &conditional->conditions[i]; + struct Tree_Statement_Conditional_Branch* branch = &conditional->conditions[i]; if (i > 0) { TRANSPILE_WRITE("else "); } if (branch->when) { TRANSPILE_WRITE("if ("); @@ -277,34 +277,34 @@ transpiler_visit_statement_conditional(struct Visit* visit, struct Statement* st } void -transpiler_visit_statement(struct Visit* visit, struct Statement* statement) +transpiler_visit_statement(struct Tree_Visit* visit, struct Tree_Statement* statement) { TRANSPILER_PREAMBLE switch (statement->kind) { - case STATEMENT_EXPRESSION: + case TREE_STATEMENT_EXPRESSION: VISIT(visit_expression, statement->value.expression.inner); if (transpiler->context.in_function) TRANSPILE_WRITE(";\n"); break; - case STATEMENT_DECLARATION: + case TREE_STATEMENT_DECLARATION: VISIT(visit_statement_declaration, statement); if (transpiler->context.in_function) TRANSPILE_WRITE(";\n"); break; - case STATEMENT_RETURN: + case TREE_STATEMENT_RETURN: VISIT(visit_statement_return, statement); if (transpiler->context.in_function) TRANSPILE_WRITE(";\n"); break; - case STATEMENT_BLOCK: + case TREE_STATEMENT_BLOCK: VISIT(visit_block_node, &statement->value.block.inner); break; default: - walk_statement(visit, statement); + tree_walk_statement(visit, statement); break; } } void -transpiler_visit_expression_integer_literal(struct Visit* visit, struct Expression* expr) +transpiler_visit_expression_integer_literal(struct Tree_Visit* visit, struct Tree_Expression* expr) { TRANSPILER_PREAMBLE @@ -312,7 +312,7 @@ transpiler_visit_expression_integer_literal(struct Visit* visit, struct Expressi } void -transpiler_visit_expression_float_literal(struct Visit* visit, struct Expression* expr) +transpiler_visit_expression_float_literal(struct Tree_Visit* visit, struct Tree_Expression* expr) { TRANSPILER_PREAMBLE @@ -320,7 +320,7 @@ transpiler_visit_expression_float_literal(struct Visit* visit, struct Expression } void -transpiler_visit_expression_string_literal(struct Visit* visit, struct Expression* expr) +transpiler_visit_expression_string_literal(struct Tree_Visit* visit, struct Tree_Expression* expr) { TRANSPILER_PREAMBLE @@ -329,7 +329,7 @@ transpiler_visit_expression_string_literal(struct Visit* visit, struct Expressio } void -transpiler_visit_expression_boolean_literal(struct Visit* visit, struct Expression* expr) +transpiler_visit_expression_boolean_literal(struct Tree_Visit* visit, struct Tree_Expression* expr) { TRANSPILER_PREAMBLE @@ -337,7 +337,7 @@ transpiler_visit_expression_boolean_literal(struct Visit* visit, struct Expressi } void -transpiler_visit_expression_name(struct Visit* visit, struct Expression* expr) +transpiler_visit_expression_name(struct Tree_Visit* visit, struct Tree_Expression* expr) { TRANSPILER_PREAMBLE @@ -345,7 +345,7 @@ transpiler_visit_expression_name(struct Visit* visit, struct Expression* expr) } void -transpiler_visit_expression_unary_operation(struct Visit* visit, struct Expression* expr) +transpiler_visit_expression_unary_operation(struct Tree_Visit* visit, struct Tree_Expression* expr) { TRANSPILER_PREAMBLE @@ -355,23 +355,23 @@ transpiler_visit_expression_unary_operation(struct Visit* visit, struct Expressi } void -transpiler_visit_expression_binary_operation(struct Visit* visit, struct Expression* expr) +transpiler_visit_expression_binary_operation(struct Tree_Visit* visit, struct Tree_Expression* expr) { TRANSPILER_PREAMBLE - struct Expression_Binary_Operator* bin_op = &expr->value.binary_operator; + struct Tree_Expression_Binary_Operator* bin_op = &expr->value.binary_operator; - if (bin_op->operation == BINARY_ASSIGN && bin_op->right_operand->kind == EXPRESSION_FUNCTION) { - struct Expression* fun_expr = bin_op->right_operand; - struct Expression_Function* fun = &fun_expr->value.function; - struct Function_Header_Node* header = &fun->header; - struct Expression* name_expr = bin_op->left_operand; + if (bin_op->operation == BINARY_ASSIGN && bin_op->right_operand->kind == TREE_EXPRESSION_FUNCTION) { + struct Tree_Expression* fun_expr = bin_op->right_operand; + struct Tree_Expression_Function* fun = &fun_expr->value.function; + struct Tree_Function_Header* header = &fun->header; + struct Tree_Expression* name_expr = bin_op->left_operand; VISIT(visit_type_node, header->return_type); TRANSPILE_WRITE(" "); // check if this is a main function assignment - if (name_expr && name_expr->kind == EXPRESSION_NAME) { - struct Expression_Name* name = &name_expr->value.name; + if (name_expr && name_expr->kind == TREE_EXPRESSION_NAME) { + struct Tree_Expression_Name* name = &name_expr->value.name; if (string_equals_c_str(name->name, "main")) { transpiler->context.main_function_found = true; transpiler->context.main_function_takes_args = @@ -413,7 +413,7 @@ transpiler_visit_expression_binary_operation(struct Visit* visit, struct Express } void -transpiler_visit_expression_call(struct Visit* visit, struct Expression* expr) +transpiler_visit_expression_call(struct Tree_Visit* visit, struct Tree_Expression* expr) { TRANSPILER_PREAMBLE @@ -424,43 +424,43 @@ transpiler_visit_expression_call(struct Visit* visit, struct Expression* expr) } void -transpiler_visit_expression(struct Visit* visit, struct Expression* expression) +transpiler_visit_expression(struct Tree_Visit* visit, struct Tree_Expression* expression) { TRANSPILER_PREAMBLE switch (expression->kind) { - case EXPRESSION_INTEGER_LITERAL: + case TREE_EXPRESSION_INTEGER_LITERAL: VISIT(visit_expression_integer_literal, expression); break; - case EXPRESSION_FLOAT_LITERAL: + case TREE_EXPRESSION_FLOAT_LITERAL: VISIT(visit_expression_float_literal, expression); break; - case EXPRESSION_STRING_LITERAL: + case TREE_EXPRESSION_STRING_LITERAL: VISIT(visit_expression_string_literal, expression); break; - case EXPRESSION_BOOLEAN_LITERAL: + case TREE_EXPRESSION_BOOLEAN_LITERAL: VISIT(visit_expression_boolean_literal, expression); break; - case EXPRESSION_NAME: + case TREE_EXPRESSION_NAME: VISIT(visit_expression_name, expression); break; - case EXPRESSION_UNARY_OPERATION: + case TREE_EXPRESSION_UNARY_OPERATION: VISIT(visit_expression_unary_operation, expression); break; - case EXPRESSION_BINARY_OPERATION: + case TREE_EXPRESSION_BINARY_OPERATION: VISIT(visit_expression_binary_operation, expression); break; - case EXPRESSION_CALL: + case TREE_EXPRESSION_CALL: VISIT(visit_expression_call, expression); break; default: - walk_expression(visit, expression); + tree_walk_expression(visit, expression); break; } } void -transpiler_visit_tree(struct Visit* visit, struct Tree* tree) +transpiler_visit_tree(struct Tree_Visit* visit, struct Tree* tree) { TRANSPILER_PREAMBLE @@ -475,7 +475,7 @@ transpiler_visit_tree(struct Visit* visit, struct Tree* tree) // this executable and then write them out into the temporary build directory. TRANSPILE_WRITE("#include \"core.c\"\n"); - FOR_EACH (struct Statement*, statement, tree->top_level_statements) { + FOR_EACH (struct Tree_Statement*, statement, tree->top_level_statements) { VISIT(visit_statement, statement); } @@ -490,7 +490,7 @@ transpiler_visit_tree(struct Visit* visit, struct Tree* tree) } } -struct Visit_Table transpiler_visit_functions = { +struct Tree_Visit_Table transpiler_visit_functions = { .visit_tree = transpiler_visit_tree, .visit_statement = transpiler_visit_statement, .visit_statement_declaration = transpiler_visit_statement_declaration, @@ -514,10 +514,10 @@ struct Visit_Table transpiler_visit_functions = { int transpiler_catskill_to_c(struct Transpiler* transpiler, struct Tree* tree) { - struct Visit visit = { .table = &transpiler_visit_functions, .user_data = transpiler }; - visit_table_fill_defaults(visit.table); + struct Tree_Visit visit = { .table = &transpiler_visit_functions, .user_data = transpiler }; + tree_visit_table_fill_defaults(visit.table); - walk(&visit, tree); + tree_walk(&visit, tree); return 0; } diff --git a/boot/tree.c b/boot/tree.c index 751cf02..07b96a3 100644 --- a/boot/tree.c +++ b/boot/tree.c @@ -398,26 +398,26 @@ increment_decrement_operation_to_string(enum Increment_Decrement_Operation opera } } -// nodes are parts of the syntax tree that are reused often -// and in different places. +// these nodes outside of the expression/statement hierarchy are parts of +// the syntax tree that are reused often and in different places. // a block of code, enclosed in curly braces. // represents a sequence of statements that are executed in order. -struct Block_Node +struct Tree_Block { - struct Statement* statements; + struct Tree_Statement* statements; struct Span span; struct Cursor location; }; // a function header, describing the parameters and return type of function. // used both as a type and in full function definitions. -struct Function_Header_Node +struct Tree_Function_Header { // linked list of parameters. // name, if given, is included in the type node. - struct Type_Node* parameters_type_and_name; - struct Type_Node* return_type; + struct Tree_Type* parameters_type_and_name; + struct Tree_Type* return_type; struct Span span; struct Cursor location; @@ -427,10 +427,10 @@ struct Function_Header_Node // constructions. // styled as either `1, 2, 3` or, when optional names // are given `a = 1, b = 2, c = 3`. -struct Argument_Group_Node +struct Tree_Argument_Group { // linked list of argument expressions. - struct Expression* arguments; + struct Tree_Expression* arguments; // names of the arguments, if given. // an unnamed argument is represented as an empty string. Array(struct String) argument_names; @@ -440,101 +440,101 @@ struct Argument_Group_Node // signifier, like `let` or `var`. // the mutability is determined by some outside context, where // a bare declaration in a for-loop, for example, is always mutable. -struct Bare_Declaration_Node +struct Tree_Bare_Declaration { Array(struct String) names; - struct Expression* initializer; - struct Type_Node* type; + struct Tree_Expression* initializer; + struct Tree_Type* type; struct Span span; struct Cursor location; }; -enum Type_Node_Type +enum Tree_Type_Type { - TYPE_NODE_NONE, + TREE_TYPE_NONE, - TYPE_NODE_NAME, - TYPE_NODE_ARRAY, // an array of a type, `[int]`. - TYPE_NODE_REFERENCE, // a reference to a type, `&int`. - TYPE_NODE_MAYBE, // a type that may be null, `int?`. - TYPE_NODE_TUPLE, // a tuple type, `(int string)`. - TYPE_NODE_MAP, // a map type, `[string = int]`. + TREE_TYPE_NAME, + TREE_TYPE_ARRAY, // an array of a type, `[int]`. + TREE_TYPE_REFERENCE, // a reference to a type, `&int`. + TREE_TYPE_MAYBE, // a type that may be null, `int?`. + TREE_TYPE_TUPLE, // a tuple type, `(int string)`. + TREE_TYPE_MAP, // a map type, `[string = int]`. - TYPE_NODE_FUNCTION, // a function type, `fun (int) int`. - TYPE_NODE_STRUCTURE, // a struct, invoked either with `type` or with `{}` when a type is inline. - TYPE_NODE_VARIANT, // a tagged union. - TYPE_NODE_CLASS, // a class of types, a.k.a. an interface. + TREE_TYPE_FUNCTION, // a function type, `fun (int) int`. + TREE_TYPE_STRUCTURE, // a struct, invoked either with `type` or with `{}` when a type is inline. + TREE_TYPE_VARIANT, // a tagged union. + TREE_TYPE_CLASS, // a class of types, a.k.a. an interface. }; -struct Type_Node_Name +struct Tree_Type_Name { struct String name; }; -struct Type_Node_Array +struct Tree_Type_Array { - struct Type_Node* element_type; + struct Tree_Type* element_type; }; -struct Type_Node_Reference +struct Tree_Type_Reference { - struct Type_Node* referenced_type; + struct Tree_Type* referenced_type; }; -struct Type_Node_Maybe +struct Tree_Type_Maybe { - struct Type_Node* inner_type; + struct Tree_Type* inner_type; }; -struct Type_Node_Tuple +struct Tree_Type_Tuple { - struct Type_Node* head; // the first type in the tuple, if any. + struct Tree_Type* head; // the first type in the tuple, if any. }; -struct Type_Node_Map +struct Tree_Type_Map { - struct Type_Node* key_type; - struct Type_Node* value_type; + struct Tree_Type* key_type; + struct Tree_Type* value_type; }; -struct Type_Node_Function +struct Tree_Type_Function { - struct Function_Header_Node header; + struct Tree_Function_Header header; }; -struct Type_Node_Structure +struct Tree_Type_Structure { // the fields of the structure, linked list of types and (required) names. - struct Type_Node* fields; + struct Tree_Type* fields; }; -struct Type_Node_Variant +struct Tree_Type_Variant { // the variants of the tagged union, linked list of (required) variant names and backing types. - // if a variant has no backing type, it is TYPE_NODE_NONE. - struct Type_Node* variants; + // if a variant has no backing type, it is TREE_TYPE_NONE. + struct Tree_Type* variants; }; -struct Type_Node_Class +struct Tree_Type_Class { // linked list of the types of methods required to implement the class. - // each node is required to have a name and be of TYPE_NODE_FUNCTION. - struct Type_Node* methods; + // each node is required to have a name and be of TREE_TYPE_FUNCTION. + struct Tree_Type* methods; }; -union Type_Node_Value -{ - struct Type_Node_Name name; - struct Type_Node_Array array; - struct Type_Node_Reference reference; - struct Type_Node_Maybe maybe; - struct Type_Node_Tuple tuple; - struct Type_Node_Map map; - struct Type_Node_Function function; - struct Type_Node_Structure structure; - struct Type_Node_Variant variant; - struct Type_Node_Class class; +union Tree_Type_Value +{ + struct Tree_Type_Name name; + struct Tree_Type_Array array; + struct Tree_Type_Reference reference; + struct Tree_Type_Maybe maybe; + struct Tree_Type_Tuple tuple; + struct Tree_Type_Map map; + struct Tree_Type_Function function; + struct Tree_Type_Structure structure; + struct Tree_Type_Variant variant; + struct Tree_Type_Class class; }; // a type node represents a type in the syntax tree. @@ -542,10 +542,10 @@ union Type_Node_Value // or null types. // also includes the name of the field, member, parameter, etc., for which // the type is defined. -struct Type_Node +struct Tree_Type { - enum Type_Node_Type type; - union Type_Node_Value value; + enum Tree_Type_Type type; + union Tree_Type_Value value; // note: we could also just include the token here i think? struct Span span; struct Cursor location; @@ -560,19 +560,19 @@ struct Type_Node // if type is within a group of multiple types, // points to the next type within the group. - struct Type_Node* next; + struct Tree_Type* next; }; -REGION(struct Type_Node, type_node) +REGION(struct Tree_Type, tree_type) // allocates a new type node in the global type node region. -struct Type_Node* -type_node_new( - enum Type_Node_Type type, union Type_Node_Value value, struct Span span, struct Cursor location) +struct Tree_Type* +tree_type_new( + enum Tree_Type_Type type, union Tree_Type_Value value, struct Span span, struct Cursor location) { - check(region_type_node_cursor < REGION_SIZE, "out of type node memory"); - struct Type_Node* type_node = ®ion_type_node[region_type_node_cursor++]; - *type_node = (struct Type_Node){ + check(region_tree_type_cursor < REGION_SIZE, "out of type node memory"); + struct Tree_Type* tree_type = ®ion_tree_type[region_tree_type_cursor++]; + *tree_type = (struct Tree_Type){ .type = type, .value = value, .span = span, @@ -581,29 +581,29 @@ type_node_new( .value_name = string_empty(), .next = nil, }; - return type_node; + return tree_type; } // allocates a new type node with no value, used for `none` types. // this is used for types that are not specified, note that it is still // fully allocated and can be used in the syntax tree. -struct Type_Node* -type_node_none(struct Span span, struct Cursor location) +struct Tree_Type* +tree_type_none(struct Span span, struct Cursor location) { - return type_node_new(TYPE_NODE_NONE, (union Type_Node_Value){ 0 }, span, location); + return tree_type_new(TREE_TYPE_NONE, (union Tree_Type_Value){ 0 }, span, location); } bool -type_node_is_none(const struct Type_Node* type_node) +tree_type_is_none(const struct Tree_Type* tree_type) { - return type_node->type == TYPE_NODE_NONE; + return tree_type->type == TREE_TYPE_NONE; } -enum Pragma_Type +enum Tree_Pragma_Type { - PRAGMA_NONE, - PRAGMA_UNKNOWN, - PRAGMA_C_HEADER, + TREE_PRAGMA_NONE, + TREE_PRAGMA_UNKNOWN, + TREE_PRAGMA_C_HEADER, // TODO: further pragma types. // NOTE: there would be plenty of use for user-defined pragmas, @@ -612,19 +612,19 @@ enum Pragma_Type // but it's something to definitely consider in the future. }; -#define PRAGMA_ARGUMENT_MAX 3 +#define TREE_PRAGMA_ARGUMENT_MAX 3 -struct Pragma_Argument +struct Tree_Pragma_Argument { - enum Pragma_Argument_Type + enum Tree_Pragma_Argument_Type { - PRAGMA_ARGUMENT_NONE, - PRAGMA_ARGUMENT_NAME_OR_STRING, - PRAGMA_ARGUMENT_NUMBER, - PRAGMA_ARGUMENT_DECIMAL, + TREE_PRAGMA_ARGUMENT_NONE, + TREE_PRAGMA_ARGUMENT_NAME_OR_STRING, + TREE_PRAGMA_ARGUMENT_NUMBER, + TREE_PRAGMA_ARGUMENT_DECIMAL, } type; - union Pragma_Argument_Value + union Tree_Pragma_Argument_Value { struct String name_or_string; int64 number; @@ -639,26 +639,26 @@ struct Pragma_Argument // behaviour, to including different C compilation units and other catskill modules. // pragmas are parsed as lone statements in the source code at first, but are then // "attached" to the relevant nodes of the type the pragma is relevant to. -struct Pragma_Node +struct Tree_Pragma { - enum Pragma_Type type; - struct Pragma_Argument arguments[PRAGMA_ARGUMENT_MAX]; + enum Tree_Pragma_Type type; + struct Tree_Pragma_Argument arguments[TREE_PRAGMA_ARGUMENT_MAX]; uint argument_count; struct Span span; struct Cursor location; - struct Pragma_Node* next; // further pragmas on the same line. + struct Tree_Pragma* next; // further pragmas on the same line. }; -REGION(struct Pragma_Node, pragma_node) +REGION(struct Tree_Pragma, tree_pragma) -struct Pragma_Node* -pragma_node_new(enum Pragma_Type type, struct Span span, struct Cursor location) +struct Tree_Pragma* +tree_pragma_new(enum Tree_Pragma_Type type, struct Span span, struct Cursor location) { - check(region_pragma_node_cursor < REGION_SIZE, "out of pragma node memory"); - struct Pragma_Node* pragma = ®ion_pragma_node[region_pragma_node_cursor++]; - *pragma = (struct Pragma_Node){ + check(region_tree_pragma_cursor < REGION_SIZE, "out of pragma node memory"); + struct Tree_Pragma* pragma = ®ion_tree_pragma[region_tree_pragma_cursor++]; + *pragma = (struct Tree_Pragma){ .type = type, .arguments = {}, .argument_count = 0, @@ -669,202 +669,202 @@ pragma_node_new(enum Pragma_Type type, struct Span span, struct Cursor location) return pragma; } -enum Pragma_Type -pragma_type_from_string(struct String name) +enum Tree_Pragma_Type +tree_pragma_type_from_string(struct String name) { // look up hash values with: // `echo -ne "string to hash" | cksum` uint32 hash = crc32_posix(name); switch (hash) { case 2852954401: // "c_header" - return PRAGMA_C_HEADER; + return TREE_PRAGMA_C_HEADER; default: - return PRAGMA_UNKNOWN; + return TREE_PRAGMA_UNKNOWN; } } const ascii* -pragma_type_to_string(enum Pragma_Type type) +tree_pragma_type_to_string(enum Tree_Pragma_Type type) { switch (type) { - case PRAGMA_C_HEADER: + case TREE_PRAGMA_C_HEADER: return "c_header"; - case PRAGMA_UNKNOWN: + case TREE_PRAGMA_UNKNOWN: return "unknown"; default: - failure("unexpected pragma type passed to `pragma_type_to_string`"); + failure("unexpected pragma type passed to `tree_pragma_type_to_string`"); return nil; } } -enum Expression_Kind +enum Tree_Expression_Kind { - EXPRESSION_NONE, + TREE_EXPRESSION_NONE, - EXPRESSION_INTEGER_LITERAL, - EXPRESSION_FLOAT_LITERAL, - EXPRESSION_STRING_LITERAL, - EXPRESSION_BOOLEAN_LITERAL, - EXPRESSION_NAME, + TREE_EXPRESSION_INTEGER_LITERAL, + TREE_EXPRESSION_FLOAT_LITERAL, + TREE_EXPRESSION_STRING_LITERAL, + TREE_EXPRESSION_BOOLEAN_LITERAL, + TREE_EXPRESSION_NAME, - EXPRESSION_UNARY_OPERATION, - EXPRESSION_BINARY_OPERATION, + TREE_EXPRESSION_UNARY_OPERATION, + TREE_EXPRESSION_BINARY_OPERATION, - EXPRESSION_GROUP, - EXPRESSION_CONSTRUCT, - EXPRESSION_CALL, - EXPRESSION_SUBSCRIPT, - EXPRESSION_MEMBER, - EXPRESSION_INCREMENT_DECREMENT, - EXPRESSION_TRY, - EXPRESSION_MUST, + TREE_EXPRESSION_GROUP, + TREE_EXPRESSION_CONSTRUCT, + TREE_EXPRESSION_CALL, + TREE_EXPRESSION_SUBSCRIPT, + TREE_EXPRESSION_MEMBER, + TREE_EXPRESSION_INCREMENT_DECREMENT, + TREE_EXPRESSION_TRY, + TREE_EXPRESSION_MUST, - EXPRESSION_FUNCTION, - EXPRESSION_TYPE, + TREE_EXPRESSION_FUNCTION, + TREE_EXPRESSION_TYPE, }; -struct Expression_Integer_Literal +struct Tree_Expression_Integer_Literal { int64 value; // might not fit entire number given in source. }; -struct Expression_Float_Literal +struct Tree_Expression_Float_Literal { float64 value; }; -struct Expression_String_Literal +struct Tree_Expression_String_Literal { struct String value; }; -struct Expression_Bool_Literal +struct Tree_Expression_Bool_Literal { bool value; }; -struct Expression_Name +struct Tree_Expression_Name { struct String name; }; -struct Expression_Unary_Operator +struct Tree_Expression_Unary_Operator { enum Unary_Operation operation; - struct Expression* operand; + struct Tree_Expression* operand; }; -struct Expression_Binary_Operator +struct Tree_Expression_Binary_Operator { enum Binary_Operation operation; - struct Expression* left_operand; - struct Expression* right_operand; + struct Tree_Expression* left_operand; + struct Tree_Expression* right_operand; }; -struct Expression_Group +struct Tree_Expression_Group { - struct Expression* inner_expression; + struct Tree_Expression* inner_expression; }; -struct Expression_Call +struct Tree_Expression_Call { - struct Expression* subject; - struct Argument_Group_Node argument_group; + struct Tree_Expression* subject; + struct Tree_Argument_Group argument_group; }; -struct Expression_Construct +struct Tree_Expression_Construct { // this should be the type to construct, e.g. `int` or `string` or a generic like `Maybe(X)` // right now, we can't guarantee it fully. - struct Expression* subject; - struct Argument_Group_Node argument_group; + struct Tree_Expression* subject; + struct Tree_Argument_Group argument_group; }; -struct Expression_Subscript +struct Tree_Expression_Subscript { - struct Expression* subject; - struct Expression* index; + struct Tree_Expression* subject; + struct Tree_Expression* index; }; -struct Expression_Member +struct Tree_Expression_Member { - struct Expression* subject; + struct Tree_Expression* subject; struct String name; }; -struct Expression_Increment_Decrement +struct Tree_Expression_Increment_Decrement { // whether the increment/decrement is a prefix or postfix operation. bool prefix; - struct Expression* subject; + struct Tree_Expression* subject; enum Increment_Decrement_Operation operation; }; -struct Expression_Try +struct Tree_Expression_Try { - struct Expression* expression; + struct Tree_Expression* expression; }; -struct Expression_Must +struct Tree_Expression_Must { - struct Expression* expression; + struct Tree_Expression* expression; }; -struct Expression_Function +struct Tree_Expression_Function { - struct Function_Header_Node header; - struct Block_Node body; + struct Tree_Function_Header header; + struct Tree_Block body; }; -struct Expression_Type +struct Tree_Expression_Type { - struct Type_Node* type; + struct Tree_Type* type; }; -union Expression_Value -{ - struct Expression_Integer_Literal integer_literal; - struct Expression_Float_Literal float_literal; - struct Expression_String_Literal string_literal; - struct Expression_Bool_Literal bool_literal; - struct Expression_Name name; - struct Expression_Unary_Operator unary_operator; - struct Expression_Binary_Operator binary_operator; - struct Expression_Group group; - struct Expression_Call call; - struct Expression_Construct construct; - struct Expression_Subscript subscript; - struct Expression_Member member; - struct Expression_Increment_Decrement increment_decrement; - struct Expression_Try try; - struct Expression_Must must; - struct Expression_Function function; - struct Expression_Type type; +union Tree_Expression_Value +{ + struct Tree_Expression_Integer_Literal integer_literal; + struct Tree_Expression_Float_Literal float_literal; + struct Tree_Expression_String_Literal string_literal; + struct Tree_Expression_Bool_Literal bool_literal; + struct Tree_Expression_Name name; + struct Tree_Expression_Unary_Operator unary_operator; + struct Tree_Expression_Binary_Operator binary_operator; + struct Tree_Expression_Group group; + struct Tree_Expression_Call call; + struct Tree_Expression_Construct construct; + struct Tree_Expression_Subscript subscript; + struct Tree_Expression_Member member; + struct Tree_Expression_Increment_Decrement increment_decrement; + struct Tree_Expression_Try try; + struct Tree_Expression_Must must; + struct Tree_Expression_Function function; + struct Tree_Expression_Type type; }; -struct Expression +struct Tree_Expression { - enum Expression_Kind kind; - union Expression_Value value; + enum Tree_Expression_Kind kind; + union Tree_Expression_Value value; struct Span span; struct Cursor location; // if expression is within a group of multiple expressions, // points to the next expression within it. - struct Expression* next; + struct Tree_Expression* next; }; -REGION(struct Expression, expression) +REGION(struct Tree_Expression, tree_expression) -struct Expression* -expression_new( - enum Expression_Kind kind, union Expression_Value value, struct Span span, +struct Tree_Expression* +tree_expression_new( + enum Tree_Expression_Kind kind, union Tree_Expression_Value value, struct Span span, struct Cursor location) { - check(region_expression_cursor < REGION_SIZE, "out of expression memory"); - struct Expression* expression = ®ion_expression[region_expression_cursor++]; - *expression = (struct Expression){ + check(region_tree_expression_cursor < REGION_SIZE, "out of expression memory"); + struct Tree_Expression* expression = ®ion_tree_expression[region_tree_expression_cursor++]; + *expression = (struct Tree_Expression){ .kind = kind, .value = value, .span = span, @@ -874,146 +874,146 @@ expression_new( return expression; } -enum Statement_Kind +enum Tree_Statement_Kind { - STATEMENT_NONE, - STATEMENT_EXPRESSION, - STATEMENT_DECLARATION, + TREE_STATEMENT_NONE, + TREE_STATEMENT_EXPRESSION, + TREE_STATEMENT_DECLARATION, // NOTE: a block could be an expression in the future. - STATEMENT_BLOCK, - STATEMENT_CONDITIONAL, - STATEMENT_LOOP, - STATEMENT_RETURN, - STATEMENT_BREAK, - STATEMENT_CONTINUE, - STATEMENT_DEFER, - - STATEMENT_PRAGMA, + TREE_STATEMENT_BLOCK, + TREE_STATEMENT_CONDITIONAL, + TREE_STATEMENT_LOOP, + TREE_STATEMENT_RETURN, + TREE_STATEMENT_BREAK, + TREE_STATEMENT_CONTINUE, + TREE_STATEMENT_DEFER, + + TREE_STATEMENT_PRAGMA, }; -struct Statement_Value_Expression +struct Tree_Statement_Value_Expression { - struct Expression* inner; + struct Tree_Expression* inner; }; -enum Statement_Declaration_Kind +enum Tree_Statement_Declaration_Kind { - STATEMENT_DECLARATION_NONE, - STATEMENT_DECLARATION_VARIABLE, - STATEMENT_DECLARATION_CONSTANT, + TREE_STATEMENT_DECLARATION_NONE, + TREE_STATEMENT_DECLARATION_VARIABLE, + TREE_STATEMENT_DECLARATION_CONSTANT, }; -enum Statement_Declaration_Kind -statement_declaration_kind_from_token(const struct Token* token) +enum Tree_Statement_Declaration_Kind +tree_statement_declaration_kind_from_token(const struct Token* token) { switch (token->kind) { case TOKEN_WORD_VAR: - return STATEMENT_DECLARATION_VARIABLE; + return TREE_STATEMENT_DECLARATION_VARIABLE; case TOKEN_WORD_LET: - return STATEMENT_DECLARATION_CONSTANT; + return TREE_STATEMENT_DECLARATION_CONSTANT; default: - return STATEMENT_DECLARATION_NONE; + return TREE_STATEMENT_DECLARATION_NONE; } } -struct Statement_Value_Declaration +struct Tree_Statement_Value_Declaration { - enum Statement_Declaration_Kind kind; - struct Bare_Declaration_Node inner; + enum Tree_Statement_Declaration_Kind kind; + struct Tree_Bare_Declaration inner; }; -struct Statement_Value_Block +struct Tree_Statement_Value_Block { - struct Block_Node inner; // the block of statements. + struct Tree_Block inner; // the block of statements. }; -#define STATEMENT_VALUE_CONDITIONAL_MAX 8 +#define TREE_STATEMENT_VALUE_CONDITIONAL_MAX 8 -struct Statement_Value_Conditional +struct Tree_Statement_Value_Conditional { - struct Statement_Conditional_Branch + struct Tree_Statement_Conditional_Branch { // if nil, the condition is always true. - struct Expression* when; - struct Block_Node then; - } conditions[STATEMENT_VALUE_CONDITIONAL_MAX]; + struct Tree_Expression* when; + struct Tree_Block then; + } conditions[TREE_STATEMENT_VALUE_CONDITIONAL_MAX]; uint condition_count; }; -enum Statement_Loop_Style +enum Tree_Statement_Loop_Style { - STATEMENT_LOOP_STYLE_NONE, - STATEMENT_LOOP_STYLE_C, // for i int = 0; i < 10; ++i {} - STATEMENT_LOOP_STYLE_FOR_EACH, // for x Obj = list {} - STATEMENT_LOOP_STYLE_WHILE, // while true {} - STATEMENT_LOOP_STYLE_ENDLESS, // while {} + TREE_STATEMENT_LOOP_STYLE_NONE, + TREE_STATEMENT_LOOP_STYLE_C, // for i int = 0; i < 10; ++i {} + TREE_STATEMENT_LOOP_STYLE_FOR_EACH, // for x Obj = list {} + TREE_STATEMENT_LOOP_STYLE_WHILE, // while true {} + TREE_STATEMENT_LOOP_STYLE_ENDLESS, // while {} }; // stands for both `for` and `while` loops. -struct Statement_Value_Loop +struct Tree_Statement_Value_Loop { - enum Statement_Loop_Style style; - struct Bare_Declaration_Node declaration; - struct Expression* condition; - struct Expression* iteration; + enum Tree_Statement_Loop_Style style; + struct Tree_Bare_Declaration declaration; + struct Tree_Expression* condition; + struct Tree_Expression* iteration; - struct Block_Node body; + struct Tree_Block body; }; -struct Statement_Value_Return +struct Tree_Statement_Value_Return { // nil if there is no return value. - struct Expression* value; + struct Tree_Expression* value; }; -struct Statement_Value_Defer +struct Tree_Statement_Value_Defer { // either a simple expression, or, if expression is nil, // a block of code to execute. - struct Expression* expression; - struct Block_Node block; + struct Tree_Expression* expression; + struct Tree_Block block; }; -struct Statement_Value_Pragma +struct Tree_Statement_Value_Pragma { - struct Pragma_Node* inner; + struct Tree_Pragma* inner; }; -union Statement_Value +union Tree_Statement_Value { - struct Statement_Value_Expression expression; - struct Statement_Value_Declaration declaration; - struct Statement_Value_Block block; - struct Statement_Value_Conditional conditional; - struct Statement_Value_Loop loop; - struct Statement_Value_Return return_value; - struct Statement_Value_Defer defer; - struct Statement_Value_Pragma pragma; + struct Tree_Statement_Value_Expression expression; + struct Tree_Statement_Value_Declaration declaration; + struct Tree_Statement_Value_Block block; + struct Tree_Statement_Value_Conditional conditional; + struct Tree_Statement_Value_Loop loop; + struct Tree_Statement_Value_Return return_value; + struct Tree_Statement_Value_Defer defer; + struct Tree_Statement_Value_Pragma pragma; }; -struct Statement +struct Tree_Statement { - enum Statement_Kind kind; - union Statement_Value value; + enum Tree_Statement_Kind kind; + union Tree_Statement_Value value; struct Span span; struct Cursor location; // if statement is within a group of multiple statements, // points to the next statement within it. - struct Statement* next; + struct Tree_Statement* next; }; -REGION(struct Statement, statement) +REGION(struct Tree_Statement, tree_statement) -struct Statement* -statement_new( - enum Statement_Kind kind, union Statement_Value value, struct Span span, struct Cursor location) +struct Tree_Statement* +tree_statement_new( + enum Tree_Statement_Kind kind, union Tree_Statement_Value value, struct Span span, struct Cursor location) { - check(region_statement_cursor < REGION_SIZE, "out of statement memory"); - struct Statement* statement = ®ion_statement[region_statement_cursor++]; - *statement = (struct Statement){ + check(region_tree_statement_cursor < REGION_SIZE, "out of statement memory"); + struct Tree_Statement* statement = ®ion_tree_statement[region_tree_statement_cursor++]; + *statement = (struct Tree_Statement){ .kind = kind, .value = value, .span = span, @@ -1026,5 +1026,5 @@ statement_new( // the top-level tree of a single catskill source file. struct Tree { - struct Statement* top_level_statements; + struct Tree_Statement* top_level_statements; }; diff --git a/boot/visit.c b/boot/visit.c index f9ad51c..83de09a 100644 --- a/boot/visit.c +++ b/boot/visit.c @@ -13,60 +13,60 @@ #include "catboot.h" -struct Visit +struct Tree_Visit { - struct Visit_Table* table; + struct Tree_Visit_Table* table; void* user_data; }; -struct Visit_Table -{ - void (*visit_tree)(struct Visit* visitor, struct Tree* tree); - - void (*visit_statement)(struct Visit* visitor, struct Statement* stmt); - void (*visit_statement_declaration)(struct Visit* visitor, struct Statement* stmt); - void (*visit_statement_conditional)(struct Visit* visitor, struct Statement* stmt); - void (*visit_statement_loop)(struct Visit* visitor, struct Statement* stmt); - void (*visit_statement_return)(struct Visit* visitor, struct Statement* stmt); - void (*visit_statement_break)(struct Visit* visitor, struct Statement* stmt); - void (*visit_statement_continue)(struct Visit* visitor, struct Statement* stmt); - void (*visit_statement_defer)(struct Visit* visitor, struct Statement* stmt); - - void (*visit_expression)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_integer_literal)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_float_literal)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_string_literal)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_boolean_literal)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_name)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_unary_operation)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_binary_operation)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_group)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_call)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_construct)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_subscript)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_member)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_increment_decrement)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_try)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_must)(struct Visit* visitor, struct Expression* expr); - void (*visit_expression_function)(struct Visit* visitor, struct Expression* expr); - - void (*visit_type_node)(struct Visit* visitor, struct Type_Node* node); - void (*visit_type_node_name)(struct Visit* visitor, struct Type_Node* node); - void (*visit_type_node_array)(struct Visit* visitor, struct Type_Node* node); - void (*visit_type_node_reference)(struct Visit* visitor, struct Type_Node* node); - void (*visit_type_node_maybe)(struct Visit* visitor, struct Type_Node* node); - void (*visit_type_node_tuple)(struct Visit* visitor, struct Type_Node* node); - void (*visit_type_node_map)(struct Visit* visitor, struct Type_Node* node); - void (*visit_type_node_function)(struct Visit* visitor, struct Type_Node* node); - void (*visit_type_node_structure)(struct Visit* visitor, struct Type_Node* node); - void (*visit_type_node_variant)(struct Visit* visitor, struct Type_Node* node); - void (*visit_type_node_class)(struct Visit* visitor, struct Type_Node* node); - - void (*visit_block_node)(struct Visit* visitor, struct Block_Node* node); - void (*visit_bare_declaration_node)(struct Visit* visitor, struct Bare_Declaration_Node* node); - void (*visit_function_header_node)(struct Visit* visitor, struct Function_Header_Node* header); - void (*visit_argument_group_node)(struct Visit* visitor, struct Argument_Group_Node* node); - void (*visit_pragma_node)(struct Visit* visitor, struct Pragma_Node* node); +struct Tree_Visit_Table +{ + void (*visit_tree)(struct Tree_Visit* visitor, struct Tree* tree); + + void (*visit_statement)(struct Tree_Visit* visitor, struct Tree_Statement* stmt); + void (*visit_statement_declaration)(struct Tree_Visit* visitor, struct Tree_Statement* stmt); + void (*visit_statement_conditional)(struct Tree_Visit* visitor, struct Tree_Statement* stmt); + void (*visit_statement_loop)(struct Tree_Visit* visitor, struct Tree_Statement* stmt); + void (*visit_statement_return)(struct Tree_Visit* visitor, struct Tree_Statement* stmt); + void (*visit_statement_break)(struct Tree_Visit* visitor, struct Tree_Statement* stmt); + void (*visit_statement_continue)(struct Tree_Visit* visitor, struct Tree_Statement* stmt); + void (*visit_statement_defer)(struct Tree_Visit* visitor, struct Tree_Statement* stmt); + + void (*visit_expression)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_integer_literal)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_float_literal)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_string_literal)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_boolean_literal)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_name)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_unary_operation)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_binary_operation)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_group)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_call)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_construct)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_subscript)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_member)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_increment_decrement)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_try)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_must)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + void (*visit_expression_function)(struct Tree_Visit* visitor, struct Tree_Expression* expr); + + void (*visit_type_node)(struct Tree_Visit* visitor, struct Tree_Type* node); + void (*visit_type_node_name)(struct Tree_Visit* visitor, struct Tree_Type* node); + void (*visit_type_node_array)(struct Tree_Visit* visitor, struct Tree_Type* node); + void (*visit_type_node_reference)(struct Tree_Visit* visitor, struct Tree_Type* node); + void (*visit_type_node_maybe)(struct Tree_Visit* visitor, struct Tree_Type* node); + void (*visit_type_node_tuple)(struct Tree_Visit* visitor, struct Tree_Type* node); + void (*visit_type_node_map)(struct Tree_Visit* visitor, struct Tree_Type* node); + void (*visit_type_node_function)(struct Tree_Visit* visitor, struct Tree_Type* node); + void (*visit_type_node_structure)(struct Tree_Visit* visitor, struct Tree_Type* node); + void (*visit_type_node_variant)(struct Tree_Visit* visitor, struct Tree_Type* node); + void (*visit_type_node_class)(struct Tree_Visit* visitor, struct Tree_Type* node); + + void (*visit_block_node)(struct Tree_Visit* visitor, struct Tree_Block* node); + void (*visit_bare_declaration_node)(struct Tree_Visit* visitor, struct Tree_Bare_Declaration* node); + void (*visit_function_header_node)(struct Tree_Visit* visitor, struct Tree_Function_Header* header); + void (*visit_argument_group_node)(struct Tree_Visit* visitor, struct Tree_Argument_Group* node); + void (*visit_pragma_node)(struct Tree_Visit* visitor, struct Tree_Pragma* node); }; #define VISIT(visit_function, node) visit->table->visit_function(visit, node); @@ -78,76 +78,76 @@ struct Visit_Table type* name = (type*)visit->user_data; \ if (!name) { failure("visit user data is NULL for " #name); } -// walk functions are the default traversal mechanism +// tree_walk functions are the default traversal mechanism -// define a walk function which goes nowhere. -#define WALK_LEAF_FUNCTION(name, type) \ - void name(struct Visit* visit, type node) {} +// define a tree_walk function which goes nowhere. +#define TREE_WALK_LEAF_FUNCTION(name, type) \ + void name(struct Tree_Visit* visit, type node) {} -// top-level walk function for beginning the visit flow. +// top-level tree_walk function for beginning the visit flow. void -walk(struct Visit* visit, struct Tree* tree) +tree_walk(struct Tree_Visit* visit, struct Tree* tree) { VISIT(visit_tree, tree); } void -walk_tree(struct Visit* visit, struct Tree* tree) +tree_walk_tree(struct Tree_Visit* visit, struct Tree* tree) { - FOR_EACH (struct Statement*, statement, tree->top_level_statements) { + FOR_EACH (struct Tree_Statement*, statement, tree->top_level_statements) { VISIT(visit_statement, statement); } } void -walk_statement(struct Visit* visit, struct Statement* statement) +tree_walk_statement(struct Tree_Visit* visit, struct Tree_Statement* statement) { switch (statement->kind) { - case STATEMENT_EXPRESSION: + case TREE_STATEMENT_EXPRESSION: VISIT(visit_expression, statement->value.expression.inner); break; - case STATEMENT_DECLARATION: + case TREE_STATEMENT_DECLARATION: VISIT(visit_statement_declaration, statement); break; - case STATEMENT_BLOCK: + case TREE_STATEMENT_BLOCK: VISIT(visit_block_node, &statement->value.block.inner); break; - case STATEMENT_CONDITIONAL: + case TREE_STATEMENT_CONDITIONAL: VISIT(visit_statement_conditional, statement); break; - case STATEMENT_LOOP: + case TREE_STATEMENT_LOOP: VISIT(visit_statement_loop, statement); break; - case STATEMENT_RETURN: + case TREE_STATEMENT_RETURN: VISIT(visit_statement_return, statement); break; - case STATEMENT_BREAK: + case TREE_STATEMENT_BREAK: VISIT(visit_statement_break, statement); break; - case STATEMENT_CONTINUE: + case TREE_STATEMENT_CONTINUE: VISIT(visit_statement_continue, statement); break; - case STATEMENT_DEFER: + case TREE_STATEMENT_DEFER: VISIT(visit_statement_defer, statement); break; - case STATEMENT_PRAGMA: + case TREE_STATEMENT_PRAGMA: VISIT(visit_pragma_node, statement->value.pragma.inner); break; default: - failure("unexpected statement kind in `walk_statement`"); + failure("unexpected statement kind in `tree_walk_statement`"); } } void -walk_statement_declaration(struct Visit* visit, struct Statement* statement) +tree_walk_statement_declaration(struct Tree_Visit* visit, struct Tree_Statement* statement) { VISIT(visit_bare_declaration_node, &statement->value.declaration.inner); } void -walk_statement_conditional(struct Visit* visit, struct Statement* statement) +tree_walk_statement_conditional(struct Tree_Visit* visit, struct Tree_Statement* statement) { - struct Statement_Value_Conditional* conditional = &statement->value.conditional; + struct Tree_Statement_Value_Conditional* conditional = &statement->value.conditional; for (uint i = 0; i < conditional->condition_count; ++i) { VISIT_MAYBE(visit_expression, conditional->conditions[i].when); VISIT(visit_block_node, &conditional->conditions[i].then); @@ -155,16 +155,16 @@ walk_statement_conditional(struct Visit* visit, struct Statement* statement) } void -walk_statement_loop(struct Visit* visit, struct Statement* statement) +tree_walk_statement_loop(struct Tree_Visit* visit, struct Tree_Statement* statement) { - struct Statement_Value_Loop* loop = &statement->value.loop; + struct Tree_Statement_Value_Loop* loop = &statement->value.loop; VISIT_MAYBE(visit_expression, loop->condition); VISIT_MAYBE(visit_expression, loop->iteration); VISIT(visit_block_node, &loop->body); } void -walk_statement_return(struct Visit* visit, struct Statement* statement) +tree_walk_statement_return(struct Tree_Visit* visit, struct Tree_Statement* statement) { VISIT_MAYBE(visit_expression, statement->value.return_value.value); } @@ -172,358 +172,358 @@ walk_statement_return(struct Visit* visit, struct Statement* statement) // although.. maybe with `break` we could make a loop become an expression, // this returning the break value as the value of the loop? // something to think about. -WALK_LEAF_FUNCTION(walk_statement_break, struct Statement*); +TREE_WALK_LEAF_FUNCTION(tree_walk_statement_break, struct Tree_Statement*); -WALK_LEAF_FUNCTION(walk_statement_continue, struct Statement*); +TREE_WALK_LEAF_FUNCTION(tree_walk_statement_continue, struct Tree_Statement*); void -walk_statement_defer(struct Visit* visit, struct Statement* statement) +tree_walk_statement_defer(struct Tree_Visit* visit, struct Tree_Statement* statement) { VISIT_MAYBE(visit_expression, statement->value.defer.expression); VISIT(visit_block_node, &statement->value.defer.block); } void -walk_expression(struct Visit* visit, struct Expression* expression) +tree_walk_expression(struct Tree_Visit* visit, struct Tree_Expression* expression) { switch (expression->kind) { - case EXPRESSION_INTEGER_LITERAL: + case TREE_EXPRESSION_INTEGER_LITERAL: VISIT(visit_expression_integer_literal, expression); break; - case EXPRESSION_FLOAT_LITERAL: + case TREE_EXPRESSION_FLOAT_LITERAL: VISIT(visit_expression_float_literal, expression); break; - case EXPRESSION_STRING_LITERAL: + case TREE_EXPRESSION_STRING_LITERAL: VISIT(visit_expression_string_literal, expression); break; - case EXPRESSION_BOOLEAN_LITERAL: + case TREE_EXPRESSION_BOOLEAN_LITERAL: VISIT(visit_expression_boolean_literal, expression); break; - case EXPRESSION_NAME: + case TREE_EXPRESSION_NAME: VISIT(visit_expression_name, expression); break; - case EXPRESSION_UNARY_OPERATION: + case TREE_EXPRESSION_UNARY_OPERATION: VISIT(visit_expression_unary_operation, expression); break; - case EXPRESSION_BINARY_OPERATION: + case TREE_EXPRESSION_BINARY_OPERATION: VISIT(visit_expression_binary_operation, expression); break; - case EXPRESSION_GROUP: + case TREE_EXPRESSION_GROUP: VISIT(visit_expression_group, expression); break; - case EXPRESSION_CALL: + case TREE_EXPRESSION_CALL: VISIT(visit_expression_call, expression); break; - case EXPRESSION_CONSTRUCT: + case TREE_EXPRESSION_CONSTRUCT: VISIT(visit_expression_construct, expression); break; - case EXPRESSION_SUBSCRIPT: + case TREE_EXPRESSION_SUBSCRIPT: VISIT(visit_expression_subscript, expression); break; - case EXPRESSION_MEMBER: + case TREE_EXPRESSION_MEMBER: VISIT(visit_expression_member, expression); break; - case EXPRESSION_INCREMENT_DECREMENT: + case TREE_EXPRESSION_INCREMENT_DECREMENT: VISIT(visit_expression_increment_decrement, expression); break; - case EXPRESSION_TRY: + case TREE_EXPRESSION_TRY: VISIT(visit_expression_try, expression); break; - case EXPRESSION_MUST: + case TREE_EXPRESSION_MUST: VISIT(visit_expression_must, expression); break; - case EXPRESSION_FUNCTION: + case TREE_EXPRESSION_FUNCTION: VISIT(visit_expression_function, expression); break; - case EXPRESSION_TYPE: + case TREE_EXPRESSION_TYPE: VISIT(visit_type_node, expression->value.type.type); break; default: - failure("unexpected expression kind in `walk_expression`"); + failure("unexpected expression kind in `tree_walk_expression`"); } } -WALK_LEAF_FUNCTION(walk_expression_integer_literal, struct Expression*); +TREE_WALK_LEAF_FUNCTION(tree_walk_expression_integer_literal, struct Tree_Expression*); -WALK_LEAF_FUNCTION(walk_expression_float_literal, struct Expression*); +TREE_WALK_LEAF_FUNCTION(tree_walk_expression_float_literal, struct Tree_Expression*); -WALK_LEAF_FUNCTION(walk_expression_string_literal, struct Expression*); +TREE_WALK_LEAF_FUNCTION(tree_walk_expression_string_literal, struct Tree_Expression*); -WALK_LEAF_FUNCTION(walk_expression_boolean_literal, struct Expression*); +TREE_WALK_LEAF_FUNCTION(tree_walk_expression_boolean_literal, struct Tree_Expression*); -WALK_LEAF_FUNCTION(walk_expression_name, struct Expression*); +TREE_WALK_LEAF_FUNCTION(tree_walk_expression_name, struct Tree_Expression*); void -walk_expression_unary_operation(struct Visit* visit, struct Expression* expression) +tree_walk_expression_unary_operation(struct Tree_Visit* visit, struct Tree_Expression* expression) { VISIT(visit_expression, expression->value.unary_operator.operand); } void -walk_expression_binary_operation(struct Visit* visit, struct Expression* expression) +tree_walk_expression_binary_operation(struct Tree_Visit* visit, struct Tree_Expression* expression) { VISIT(visit_expression, expression->value.binary_operator.left_operand); VISIT(visit_expression, expression->value.binary_operator.right_operand); } void -walk_expression_group(struct Visit* visit, struct Expression* expression) +tree_walk_expression_group(struct Tree_Visit* visit, struct Tree_Expression* expression) { VISIT(visit_expression, expression->value.group.inner_expression); } void -walk_expression_call(struct Visit* visit, struct Expression* expression) +tree_walk_expression_call(struct Tree_Visit* visit, struct Tree_Expression* expression) { - struct Expression_Call* call = &expression->value.call; + struct Tree_Expression_Call* call = &expression->value.call; VISIT(visit_expression, call->subject); VISIT(visit_argument_group_node, &call->argument_group); } void -walk_expression_construct(struct Visit* visit, struct Expression* expression) +tree_walk_expression_construct(struct Tree_Visit* visit, struct Tree_Expression* expression) { - struct Expression_Construct* construct = &expression->value.construct; + struct Tree_Expression_Construct* construct = &expression->value.construct; VISIT(visit_expression, construct->subject); VISIT(visit_argument_group_node, &construct->argument_group); } void -walk_expression_subscript(struct Visit* visit, struct Expression* expression) +tree_walk_expression_subscript(struct Tree_Visit* visit, struct Tree_Expression* expression) { VISIT(visit_expression, expression->value.subscript.subject); VISIT(visit_expression, expression->value.subscript.index); } void -walk_expression_member(struct Visit* visit, struct Expression* expression) +tree_walk_expression_member(struct Tree_Visit* visit, struct Tree_Expression* expression) { VISIT(visit_expression, expression->value.member.subject); } void -walk_expression_increment_decrement(struct Visit* visit, struct Expression* expression) +tree_walk_expression_increment_decrement(struct Tree_Visit* visit, struct Tree_Expression* expression) { VISIT(visit_expression, expression->value.increment_decrement.subject); } -WALK_LEAF_FUNCTION(walk_expression_try, struct Expression*); +TREE_WALK_LEAF_FUNCTION(tree_walk_expression_try, struct Tree_Expression*); -WALK_LEAF_FUNCTION(walk_expression_must, struct Expression*); +TREE_WALK_LEAF_FUNCTION(tree_walk_expression_must, struct Tree_Expression*); void -walk_expression_function(struct Visit* visit, struct Expression* expression) +tree_walk_expression_function(struct Tree_Visit* visit, struct Tree_Expression* expression) { VISIT(visit_function_header_node, &expression->value.function.header); VISIT(visit_block_node, &expression->value.function.body); } void -walk_type_node(struct Visit* visit, struct Type_Node* node) +tree_walk_type(struct Tree_Visit* visit, struct Tree_Type* node) { switch (node->type) { - case TYPE_NODE_NONE: + case TREE_TYPE_NONE: break; - case TYPE_NODE_NAME: + case TREE_TYPE_NAME: VISIT(visit_type_node_name, node); break; - case TYPE_NODE_ARRAY: + case TREE_TYPE_ARRAY: VISIT(visit_type_node_array, node); break; - case TYPE_NODE_REFERENCE: + case TREE_TYPE_REFERENCE: VISIT(visit_type_node_reference, node); break; - case TYPE_NODE_MAYBE: + case TREE_TYPE_MAYBE: VISIT(visit_type_node_maybe, node); break; - case TYPE_NODE_TUPLE: + case TREE_TYPE_TUPLE: VISIT(visit_type_node_tuple, node); break; - case TYPE_NODE_MAP: + case TREE_TYPE_MAP: VISIT(visit_type_node_map, node); break; - case TYPE_NODE_FUNCTION: + case TREE_TYPE_FUNCTION: VISIT(visit_type_node_function, node); break; - case TYPE_NODE_STRUCTURE: + case TREE_TYPE_STRUCTURE: VISIT(visit_type_node_structure, node); break; - case TYPE_NODE_VARIANT: + case TREE_TYPE_VARIANT: VISIT(visit_type_node_variant, node); break; - case TYPE_NODE_CLASS: + case TREE_TYPE_CLASS: VISIT(visit_type_node_class, node); break; default: - failure("unexpected type node kind in `walk_type_node`"); + failure("unexpected type node kind in `tree_walk_type`"); } } -WALK_LEAF_FUNCTION(walk_type_node_name, struct Type_Node*); +TREE_WALK_LEAF_FUNCTION(tree_walk_type_name, struct Tree_Type*); void -walk_type_node_array(struct Visit* visit, struct Type_Node* node) +tree_walk_type_array(struct Tree_Visit* visit, struct Tree_Type* node) { VISIT(visit_type_node, node->value.array.element_type); } void -walk_type_node_reference(struct Visit* visit, struct Type_Node* node) +tree_walk_type_reference(struct Tree_Visit* visit, struct Tree_Type* node) { VISIT(visit_type_node, node->value.reference.referenced_type); } void -walk_type_node_maybe(struct Visit* visit, struct Type_Node* node) +tree_walk_type_maybe(struct Tree_Visit* visit, struct Tree_Type* node) { VISIT(visit_type_node, node->value.maybe.inner_type); } void -walk_type_node_tuple(struct Visit* visit, struct Type_Node* node) +tree_walk_type_tuple(struct Tree_Visit* visit, struct Tree_Type* node) { - FOR_EACH (struct Type_Node*, current, node->value.tuple.head) { + FOR_EACH (struct Tree_Type*, current, node->value.tuple.head) { VISIT(visit_type_node, current); } } void -walk_type_node_map(struct Visit* visit, struct Type_Node* node) +tree_walk_type_map(struct Tree_Visit* visit, struct Tree_Type* node) { VISIT(visit_type_node, node->value.map.key_type); VISIT(visit_type_node, node->value.map.value_type); } void -walk_type_node_function(struct Visit* visit, struct Type_Node* node) +tree_walk_type_function(struct Tree_Visit* visit, struct Tree_Type* node) { VISIT(visit_function_header_node, &node->value.function.header); } void -walk_type_node_structure(struct Visit* visit, struct Type_Node* node) +tree_walk_type_structure(struct Tree_Visit* visit, struct Tree_Type* node) { - FOR_EACH (struct Type_Node*, field, node->value.structure.fields) { + FOR_EACH (struct Tree_Type*, field, node->value.structure.fields) { VISIT(visit_type_node, field); } } void -walk_type_node_variant(struct Visit* visit, struct Type_Node* node) +tree_walk_type_variant(struct Tree_Visit* visit, struct Tree_Type* node) { - FOR_EACH (struct Type_Node*, method, node->value.variant.variants) { + FOR_EACH (struct Tree_Type*, method, node->value.variant.variants) { VISIT(visit_type_node, method); } } void -walk_type_node_class(struct Visit* visit, struct Type_Node* node) +tree_walk_type_class(struct Tree_Visit* visit, struct Tree_Type* node) { - FOR_EACH (struct Type_Node*, method, node->value.class.methods) { + FOR_EACH (struct Tree_Type*, method, node->value.class.methods) { VISIT(visit_type_node, method); } } void -walk_block_node(struct Visit* visit, struct Block_Node* node) +tree_walk_block(struct Tree_Visit* visit, struct Tree_Block* node) { - FOR_EACH (struct Statement*, statement, node->statements) { VISIT(visit_statement, statement); } + FOR_EACH (struct Tree_Statement*, statement, node->statements) { VISIT(visit_statement, statement); } } void -walk_bare_declaration_node(struct Visit* visit, struct Bare_Declaration_Node* node) +tree_walk_bare_declaration(struct Tree_Visit* visit, struct Tree_Bare_Declaration* node) { VISIT_MAYBE(visit_type_node, node->type); VISIT(visit_expression, node->initializer); } void -walk_function_header_node(struct Visit* visit, struct Function_Header_Node* header) +tree_walk_function_header(struct Tree_Visit* visit, struct Tree_Function_Header* header) { - FOR_EACH (struct Type_Node*, param_type, header->parameters_type_and_name) { + FOR_EACH (struct Tree_Type*, param_type, header->parameters_type_and_name) { VISIT(visit_type_node, param_type); } VISIT_MAYBE(visit_type_node, header->return_type); } void -walk_argument_group_node(struct Visit* visit, struct Argument_Group_Node* node) +tree_walk_argument_group(struct Tree_Visit* visit, struct Tree_Argument_Group* node) { - FOR_EACH (struct Expression*, argument, node->arguments) { VISIT(visit_expression, argument); } + FOR_EACH (struct Tree_Expression*, argument, node->arguments) { VISIT(visit_expression, argument); } } void -walk_pragma_node(struct Visit* visit, struct Pragma_Node* node) +tree_walk_pragma(struct Tree_Visit* visit, struct Tree_Pragma* node) { // visit each pragma node in the linked list. VISIT_MAYBE(visit_pragma_node, node->next); } -struct Visit_Table walk_functions = { - .visit_tree = walk_tree, - - .visit_statement = walk_statement, - .visit_statement_declaration = walk_statement_declaration, - .visit_statement_conditional = walk_statement_conditional, - .visit_statement_loop = walk_statement_loop, - .visit_statement_return = walk_statement_return, - .visit_statement_break = walk_statement_break, - .visit_statement_continue = walk_statement_continue, - .visit_statement_defer = walk_statement_defer, - - .visit_expression = walk_expression, - .visit_expression_integer_literal = walk_expression_integer_literal, - .visit_expression_float_literal = walk_expression_float_literal, - .visit_expression_string_literal = walk_expression_string_literal, - .visit_expression_boolean_literal = walk_expression_boolean_literal, - .visit_expression_name = walk_expression_name, - .visit_expression_unary_operation = walk_expression_unary_operation, - .visit_expression_binary_operation = walk_expression_binary_operation, - .visit_expression_group = walk_expression_group, - .visit_expression_call = walk_expression_call, - .visit_expression_construct = walk_expression_construct, - .visit_expression_subscript = walk_expression_subscript, - .visit_expression_member = walk_expression_member, - .visit_expression_increment_decrement = walk_expression_increment_decrement, - .visit_expression_function = walk_expression_function, - - .visit_type_node = walk_type_node, - .visit_type_node_name = walk_type_node_name, - .visit_type_node_array = walk_type_node_array, - .visit_type_node_reference = walk_type_node_reference, - .visit_type_node_maybe = walk_type_node_maybe, - .visit_type_node_tuple = walk_type_node_tuple, - .visit_type_node_map = walk_type_node_map, - .visit_type_node_function = walk_type_node_function, - .visit_type_node_structure = walk_type_node_structure, - .visit_type_node_variant = walk_type_node_variant, - .visit_type_node_class = walk_type_node_class, - - .visit_block_node = walk_block_node, - .visit_bare_declaration_node = walk_bare_declaration_node, - .visit_function_header_node = walk_function_header_node, - .visit_argument_group_node = walk_argument_group_node, - .visit_pragma_node = walk_pragma_node, +struct Tree_Visit_Table tree_walk_functions = { + .visit_tree = tree_walk_tree, + + .visit_statement = tree_walk_statement, + .visit_statement_declaration = tree_walk_statement_declaration, + .visit_statement_conditional = tree_walk_statement_conditional, + .visit_statement_loop = tree_walk_statement_loop, + .visit_statement_return = tree_walk_statement_return, + .visit_statement_break = tree_walk_statement_break, + .visit_statement_continue = tree_walk_statement_continue, + .visit_statement_defer = tree_walk_statement_defer, + + .visit_expression = tree_walk_expression, + .visit_expression_integer_literal = tree_walk_expression_integer_literal, + .visit_expression_float_literal = tree_walk_expression_float_literal, + .visit_expression_string_literal = tree_walk_expression_string_literal, + .visit_expression_boolean_literal = tree_walk_expression_boolean_literal, + .visit_expression_name = tree_walk_expression_name, + .visit_expression_unary_operation = tree_walk_expression_unary_operation, + .visit_expression_binary_operation = tree_walk_expression_binary_operation, + .visit_expression_group = tree_walk_expression_group, + .visit_expression_call = tree_walk_expression_call, + .visit_expression_construct = tree_walk_expression_construct, + .visit_expression_subscript = tree_walk_expression_subscript, + .visit_expression_member = tree_walk_expression_member, + .visit_expression_increment_decrement = tree_walk_expression_increment_decrement, + .visit_expression_function = tree_walk_expression_function, + + .visit_type_node = tree_walk_type, + .visit_type_node_name = tree_walk_type_name, + .visit_type_node_array = tree_walk_type_array, + .visit_type_node_reference = tree_walk_type_reference, + .visit_type_node_maybe = tree_walk_type_maybe, + .visit_type_node_tuple = tree_walk_type_tuple, + .visit_type_node_map = tree_walk_type_map, + .visit_type_node_function = tree_walk_type_function, + .visit_type_node_structure = tree_walk_type_structure, + .visit_type_node_variant = tree_walk_type_variant, + .visit_type_node_class = tree_walk_type_class, + + .visit_block_node = tree_walk_block, + .visit_bare_declaration_node = tree_walk_bare_declaration, + .visit_function_header_node = tree_walk_function_header, + .visit_argument_group_node = tree_walk_argument_group, + .visit_pragma_node = tree_walk_pragma, }; -// fills in the visit table with default walk functions +// fills in the visit table with default tree_walk functions void -visit_table_fill_defaults(struct Visit_Table* table) +tree_visit_table_fill_defaults(struct Tree_Visit_Table* table) { // not portable, nor safe, but sometimes you need to have a bit of fun! :3 // assumptions: - // - sizeof(struct Visit_Table) is a multiple of the size of a function pointer, + // - sizeof(struct Tree_Visit_Table) is a multiple of the size of a function pointer, // with no padding between function pointers. // - the size of a function pointer is the same across all platforms we care about. - // - casting struct Visit_Table to a function pointer array is undefined, but safe. - const uint function_count = sizeof(struct Visit_Table) / sizeof(void (*)()); + // - casting struct Tree_Visit_Table to a function pointer array is undefined, but safe. + const uint function_count = sizeof(struct Tree_Visit_Table) / sizeof(void (*)()); typedef void (*Function_Ptr)(); for (uint fi = 0; fi < function_count; ++fi) { Function_Ptr* function_slot = &((Function_Ptr*)table)[fi]; - Function_Ptr* walk = &((Function_Ptr*)&walk_functions)[fi]; - if (!*function_slot) *function_slot = *walk; + Function_Ptr* tree_walk = &((Function_Ptr*)&tree_walk_functions)[fi]; + if (!*function_slot) *function_slot = *tree_walk; } } @@ -572,33 +572,33 @@ tree_printer_indent(struct Tree_Printer* printer) } void -printer_visit_tree(struct Visit* visit, struct Tree* tree) +tree_printer_visit_tree(struct Tree_Visit* visit, struct Tree* tree) { TREE_PRINTER_PREAMBLE - FOR_EACH (struct Statement*, statement, tree->top_level_statements) { + FOR_EACH (struct Tree_Statement*, statement, tree->top_level_statements) { VISIT(visit_statement, statement); PRINT("\n"); } } void -printer_visit_statement(struct Visit* visit, struct Statement* statement) +tree_printer_visit_statement(struct Tree_Visit* visit, struct Tree_Statement* statement) { TREE_PRINTER_PREAMBLE tree_printer_indent(printer); - walk_statement(visit, statement); + tree_walk_statement(visit, statement); } void -printer_visit_statement_declaration(struct Visit* visit, struct Statement* stmt) +tree_printer_visit_statement_declaration(struct Tree_Visit* visit, struct Tree_Statement* stmt) { TREE_PRINTER_PREAMBLE - if (stmt->value.declaration.kind == STATEMENT_DECLARATION_VARIABLE) + if (stmt->value.declaration.kind == TREE_STATEMENT_DECLARATION_VARIABLE) PRINT("(variable "); - else if (stmt->value.declaration.kind == STATEMENT_DECLARATION_CONSTANT) + else if (stmt->value.declaration.kind == TREE_STATEMENT_DECLARATION_CONSTANT) PRINT("(constant "); VISIT(visit_bare_declaration_node, &stmt->value.declaration.inner); @@ -606,13 +606,13 @@ printer_visit_statement_declaration(struct Visit* visit, struct Statement* stmt) } void -printer_visit_statement_conditional(struct Visit* visit, struct Statement* stmt) +tree_printer_visit_statement_conditional(struct Tree_Visit* visit, struct Tree_Statement* stmt) { TREE_PRINTER_PREAMBLE PRINT("(conditional"); for (uint i = 0; i < stmt->value.conditional.condition_count; ++i) { - const struct Statement_Conditional_Branch* branch = &stmt->value.conditional.conditions[i]; + const struct Tree_Statement_Conditional_Branch* branch = &stmt->value.conditional.conditions[i]; PRINT(" "); if (branch->when) { PRINT("(when "); @@ -621,20 +621,20 @@ printer_visit_statement_conditional(struct Visit* visit, struct Statement* stmt) } else { PRINT("(always) "); } - VISIT(visit_block_node, (struct Block_Node*)&branch->then); + VISIT(visit_block_node, (struct Tree_Block*)&branch->then); } PRINT(")"); } void -printer_visit_statement_loop(struct Visit* visit, struct Statement* stmt) +tree_printer_visit_statement_loop(struct Tree_Visit* visit, struct Tree_Statement* stmt) { TREE_PRINTER_PREAMBLE PRINT("(loop "); switch (stmt->value.loop.style) { - case STATEMENT_LOOP_STYLE_C: + case TREE_STATEMENT_LOOP_STYLE_C: PRINT("c-style "); VISIT(visit_bare_declaration_node, &stmt->value.loop.declaration); PRINT(" (condition "); @@ -643,21 +643,21 @@ printer_visit_statement_loop(struct Visit* visit, struct Statement* stmt) VISIT(visit_expression, stmt->value.loop.iteration); PRINT(") "); break; - case STATEMENT_LOOP_STYLE_FOR_EACH: + case TREE_STATEMENT_LOOP_STYLE_FOR_EACH: PRINT("for-each "); VISIT(visit_bare_declaration_node, &stmt->value.loop.declaration); PRINT(" "); break; - case STATEMENT_LOOP_STYLE_WHILE: + case TREE_STATEMENT_LOOP_STYLE_WHILE: PRINT("while (condition "); VISIT(visit_expression, stmt->value.loop.condition); PRINT(") "); break; - case STATEMENT_LOOP_STYLE_ENDLESS: + case TREE_STATEMENT_LOOP_STYLE_ENDLESS: PRINT("endless "); break; default: - fprintf(stderr, "unexpected loop style in `printer_visit_statement_loop`"); + fprintf(stderr, "unexpected loop style in `tree_printer_visit_statement_loop`"); break; } @@ -666,7 +666,7 @@ printer_visit_statement_loop(struct Visit* visit, struct Statement* stmt) } void -printer_visit_statement_return(struct Visit* visit, struct Statement* stmt) +tree_printer_visit_statement_return(struct Tree_Visit* visit, struct Tree_Statement* stmt) { TREE_PRINTER_PREAMBLE @@ -679,7 +679,7 @@ printer_visit_statement_return(struct Visit* visit, struct Statement* stmt) } void -printer_visit_statement_break(struct Visit* visit, struct Statement* stmt) +tree_printer_visit_statement_break(struct Tree_Visit* visit, struct Tree_Statement* stmt) { TREE_PRINTER_PREAMBLE @@ -687,7 +687,7 @@ printer_visit_statement_break(struct Visit* visit, struct Statement* stmt) } void -printer_visit_statement_continue(struct Visit* visit, struct Statement* stmt) +tree_printer_visit_statement_continue(struct Tree_Visit* visit, struct Tree_Statement* stmt) { TREE_PRINTER_PREAMBLE @@ -695,7 +695,7 @@ printer_visit_statement_continue(struct Visit* visit, struct Statement* stmt) } void -printer_visit_statement_defer(struct Visit* visit, struct Statement* stmt) +tree_printer_visit_statement_defer(struct Tree_Visit* visit, struct Tree_Statement* stmt) { TREE_PRINTER_PREAMBLE @@ -709,16 +709,16 @@ printer_visit_statement_defer(struct Visit* visit, struct Statement* stmt) } void -printer_visit_expression(struct Visit* visit, struct Expression* expression) +tree_printer_visit_expression(struct Tree_Visit* visit, struct Tree_Expression* expression) { TREE_PRINTER_PREAMBLE PRINT("(expr "); - walk_expression(visit, expression); + tree_walk_expression(visit, expression); PRINT(")"); } void -printer_visit_expression_integer_literal(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_integer_literal(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -726,7 +726,7 @@ printer_visit_expression_integer_literal(struct Visit* visit, struct Expression* } void -printer_visit_expression_float_literal(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_float_literal(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -734,7 +734,7 @@ printer_visit_expression_float_literal(struct Visit* visit, struct Expression* e } void -printer_visit_expression_string_literal(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_string_literal(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -742,7 +742,7 @@ printer_visit_expression_string_literal(struct Visit* visit, struct Expression* } void -printer_visit_expression_boolean_literal(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_boolean_literal(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -750,7 +750,7 @@ printer_visit_expression_boolean_literal(struct Visit* visit, struct Expression* } void -printer_visit_expression_name(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_name(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -758,7 +758,7 @@ printer_visit_expression_name(struct Visit* visit, struct Expression* expr) } void -printer_visit_expression_unary_operation(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_unary_operation(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -768,7 +768,7 @@ printer_visit_expression_unary_operation(struct Visit* visit, struct Expression* } void -printer_visit_expression_binary_operation(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_binary_operation(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -780,7 +780,7 @@ printer_visit_expression_binary_operation(struct Visit* visit, struct Expression } void -printer_visit_expression_group(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_group(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -790,11 +790,11 @@ printer_visit_expression_group(struct Visit* visit, struct Expression* expr) } void -printer_visit_expression_call(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_call(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE - struct Expression_Call* call = &expr->value.call; + struct Tree_Expression_Call* call = &expr->value.call; PRINT("(call "); VISIT(visit_expression, call->subject); VISIT(visit_argument_group_node, &call->argument_group); @@ -803,11 +803,11 @@ printer_visit_expression_call(struct Visit* visit, struct Expression* expr) } void -printer_visit_expression_construct(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_construct(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE - struct Expression_Construct* construct = &expr->value.construct; + struct Tree_Expression_Construct* construct = &expr->value.construct; PRINT("(construct "); VISIT(visit_expression, construct->subject); VISIT(visit_argument_group_node, &construct->argument_group); @@ -816,7 +816,7 @@ printer_visit_expression_construct(struct Visit* visit, struct Expression* expr) } void -printer_visit_expression_subscript(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_subscript(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -828,7 +828,7 @@ printer_visit_expression_subscript(struct Visit* visit, struct Expression* expr) } void -printer_visit_expression_member(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_member(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -838,11 +838,11 @@ printer_visit_expression_member(struct Visit* visit, struct Expression* expr) } void -printer_visit_expression_increment_decrement(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_increment_decrement(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE - const struct Expression_Increment_Decrement* inc_dec = &expr->value.increment_decrement; + const struct Tree_Expression_Increment_Decrement* inc_dec = &expr->value.increment_decrement; const ascii* prefix_or_postfix = inc_dec->prefix ? "prefix" : "postfix"; PRINT("(increment/decrement %s %s ", increment_decrement_operation_to_string(inc_dec->operation), prefix_or_postfix); @@ -851,7 +851,7 @@ printer_visit_expression_increment_decrement(struct Visit* visit, struct Express } void -printer_visit_expression_try(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_try(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -861,7 +861,7 @@ printer_visit_expression_try(struct Visit* visit, struct Expression* expr) } void -printer_visit_expression_must(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_must(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE @@ -871,30 +871,30 @@ printer_visit_expression_must(struct Visit* visit, struct Expression* expr) } void -printer_visit_expression_function(struct Visit* visit, struct Expression* expr) +tree_printer_visit_expression_function(struct Tree_Visit* visit, struct Tree_Expression* expr) { TREE_PRINTER_PREAMBLE - struct Expression_Function* fun = &expr->value.function; + struct Tree_Expression_Function* fun = &expr->value.function; PRINT("(function "); VISIT(visit_function_header_node, &fun->header); PRINT_WHITESPACE_IF_NEEDED(" "); - VISIT(visit_block_node, (struct Block_Node*)&fun->body); + VISIT(visit_block_node, (struct Tree_Block*)&fun->body); PRINT(")"); } void -printer_visit_type_node(struct Visit* visit, struct Type_Node* node) +tree_printer_visit_type(struct Tree_Visit* visit, struct Tree_Type* node) { TREE_PRINTER_PREAMBLE PRINT("(type "); if (node->variadic) PRINT("variadic "); - walk_type_node(visit, node); + tree_walk_type(visit, node); PRINT(")"); } void -printer_visit_type_node_name(struct Visit* visit, struct Type_Node* node) +tree_printer_visit_type_name(struct Tree_Visit* visit, struct Tree_Type* node) { TREE_PRINTER_PREAMBLE @@ -902,7 +902,7 @@ printer_visit_type_node_name(struct Visit* visit, struct Type_Node* node) } void -printer_visit_type_node_array(struct Visit* visit, struct Type_Node* node) +tree_printer_visit_type_array(struct Tree_Visit* visit, struct Tree_Type* node) { TREE_PRINTER_PREAMBLE @@ -911,7 +911,7 @@ printer_visit_type_node_array(struct Visit* visit, struct Type_Node* node) } void -printer_visit_type_node_reference(struct Visit* visit, struct Type_Node* node) +tree_printer_visit_type_reference(struct Tree_Visit* visit, struct Tree_Type* node) { TREE_PRINTER_PREAMBLE @@ -920,7 +920,7 @@ printer_visit_type_node_reference(struct Visit* visit, struct Type_Node* node) } void -printer_visit_type_node_maybe(struct Visit* visit, struct Type_Node* node) +tree_printer_visit_type_maybe(struct Tree_Visit* visit, struct Tree_Type* node) { TREE_PRINTER_PREAMBLE @@ -929,19 +929,19 @@ printer_visit_type_node_maybe(struct Visit* visit, struct Type_Node* node) } void -printer_visit_type_node_tuple(struct Visit* visit, struct Type_Node* node) +tree_printer_visit_type_tuple(struct Tree_Visit* visit, struct Tree_Type* node) { TREE_PRINTER_PREAMBLE PRINT("tuple"); - FOR_EACH (struct Type_Node*, current, node->value.tuple.head) { + FOR_EACH (struct Tree_Type*, current, node->value.tuple.head) { PRINT(" "); VISIT(visit_type_node, current); } } void -printer_visit_type_node_map(struct Visit* visit, struct Type_Node* node) +tree_printer_visit_type_map(struct Tree_Visit* visit, struct Tree_Type* node) { TREE_PRINTER_PREAMBLE @@ -952,7 +952,7 @@ printer_visit_type_node_map(struct Visit* visit, struct Type_Node* node) } void -printer_visit_type_node_function(struct Visit* visit, struct Type_Node* node) +tree_printer_visit_type_function(struct Tree_Visit* visit, struct Tree_Type* node) { TREE_PRINTER_PREAMBLE @@ -961,25 +961,25 @@ printer_visit_type_node_function(struct Visit* visit, struct Type_Node* node) } void -printer_visit_type_node_structure(struct Visit* visit, struct Type_Node* node) +tree_printer_visit_type_structure(struct Tree_Visit* visit, struct Tree_Type* node) { TREE_PRINTER_PREAMBLE PRINT("structure"); - FOR_EACH (struct Type_Node*, current, node->value.structure.fields) { + FOR_EACH (struct Tree_Type*, current, node->value.structure.fields) { PRINT(" (field %s) ", current->value_name.data); VISIT(visit_type_node, current); } } void -printer_visit_type_node_variant(struct Visit* visit, struct Type_Node* node) +tree_printer_visit_type_variant(struct Tree_Visit* visit, struct Tree_Type* node) { TREE_PRINTER_PREAMBLE PRINT("variant"); - FOR_EACH (struct Type_Node*, current, node->value.variant.variants) { - if (current->type == TYPE_NODE_NONE) { + FOR_EACH (struct Tree_Type*, current, node->value.variant.variants) { + if (current->type == TREE_TYPE_NONE) { PRINT(" (variant %s)", current->value_name.data); } else { PRINT(" (variant %s of ", current->value_name.data); @@ -990,12 +990,12 @@ printer_visit_type_node_variant(struct Visit* visit, struct Type_Node* node) } void -printer_visit_type_node_class(struct Visit* visit, struct Type_Node* node) +tree_printer_visit_type_class(struct Tree_Visit* visit, struct Tree_Type* node) { TREE_PRINTER_PREAMBLE PRINT("class"); - FOR_EACH (struct Type_Node*, current, node->value.class.methods) { + FOR_EACH (struct Tree_Type*, current, node->value.class.methods) { PRINT(" (method %s ", current->value_name.data); VISIT(visit_function_header_node, ¤t->value.function.header); PRINT(")"); @@ -1003,7 +1003,7 @@ printer_visit_type_node_class(struct Visit* visit, struct Type_Node* node) } void -printer_visit_block_node(struct Visit* visit, struct Block_Node* node) +tree_printer_visit_block(struct Tree_Visit* visit, struct Tree_Block* node) { TREE_PRINTER_PREAMBLE @@ -1011,7 +1011,7 @@ printer_visit_block_node(struct Visit* visit, struct Block_Node* node) if (node->statements) { PRINT("\n"); printer->indentation_level++; - FOR_EACH (struct Statement*, statement, node->statements) { + FOR_EACH (struct Tree_Statement*, statement, node->statements) { VISIT(visit_statement, statement); PRINT("\n"); } @@ -1022,7 +1022,7 @@ printer_visit_block_node(struct Visit* visit, struct Block_Node* node) } void -printer_visit_bare_declaration_node(struct Visit* visit, struct Bare_Declaration_Node* node) +tree_printer_visit_bare_declaration(struct Tree_Visit* visit, struct Tree_Bare_Declaration* node) { TREE_PRINTER_PREAMBLE @@ -1031,7 +1031,7 @@ printer_visit_bare_declaration_node(struct Visit* visit, struct Bare_Declaration PRINT("%s ", name.data); }) - if (node->type && node->type->type != TYPE_NODE_NONE) { + if (node->type && node->type->type != TREE_TYPE_NONE) { VISIT(visit_type_node, node->type); PRINT(" "); } @@ -1045,11 +1045,11 @@ printer_visit_bare_declaration_node(struct Visit* visit, struct Bare_Declaration } void -printer_visit_function_header(struct Visit* visit, struct Function_Header_Node* header) +printer_visit_function_header(struct Tree_Visit* visit, struct Tree_Function_Header* header) { TREE_PRINTER_PREAMBLE - FOR_EACH (struct Type_Node*, current, header->parameters_type_and_name) { + FOR_EACH (struct Tree_Type*, current, header->parameters_type_and_name) { // if (current != header->parameters_type_and_name) PRINT(" "); PRINT_WHITESPACE_IF_NEEDED(" "); @@ -1071,27 +1071,27 @@ printer_visit_function_header(struct Visit* visit, struct Function_Header_Node* } void -printer_visit_pragma_node(struct Visit* visit, struct Pragma_Node* node) +tree_printer_visit_pragma(struct Tree_Visit* visit, struct Tree_Pragma* node) { TREE_PRINTER_PREAMBLE - const ascii* pragma_name = pragma_type_to_string(node->type); + const ascii* pragma_name = tree_pragma_type_to_string(node->type); PRINT("(pragma %s", pragma_name); for (uint ai = 0; ai < node->argument_count; ++ai) { - struct Pragma_Argument* arg = &node->arguments[ai]; + struct Tree_Pragma_Argument* arg = &node->arguments[ai]; switch (arg->type) { - case PRAGMA_ARGUMENT_NUMBER: + case TREE_PRAGMA_ARGUMENT_NUMBER: PRINT(" (number %ld)", arg->value.number); break; - case PRAGMA_ARGUMENT_DECIMAL: + case TREE_PRAGMA_ARGUMENT_DECIMAL: PRINT(" (decimal %lf)", arg->value.decimal); break; - case PRAGMA_ARGUMENT_NAME_OR_STRING: + case TREE_PRAGMA_ARGUMENT_NAME_OR_STRING: PRINT(" (name/string '%s')", arg->value.name_or_string.data); break; default: - failure("unexpected pragma argument type in `printer_visit_pragma_node`"); + failure("unexpected pragma argument type in `tree_printer_visit_pragma`"); } } PRINT(")"); @@ -1103,12 +1103,12 @@ printer_visit_pragma_node(struct Visit* visit, struct Pragma_Node* node) } void -printer_visit_argument_group_node(struct Visit* visit, struct Argument_Group_Node* node) +tree_printer_visit_argument_group(struct Tree_Visit* visit, struct Tree_Argument_Group* node) { TREE_PRINTER_PREAMBLE uint i = 0; - FOR_EACH (struct Expression*, argument, node->arguments) { + FOR_EACH (struct Tree_Expression*, argument, node->arguments) { struct String name = *array_at(struct String, &node->argument_names, i++); if (name.data && name.data[0] != '\0') { PRINT(" (named arg '%s' ", name.data); @@ -1120,53 +1120,53 @@ printer_visit_argument_group_node(struct Visit* visit, struct Argument_Group_Nod } } -struct Visit_Table printer_visit_functions = { - .visit_tree = printer_visit_tree, - - .visit_statement = printer_visit_statement, - .visit_statement_declaration = printer_visit_statement_declaration, - .visit_statement_conditional = printer_visit_statement_conditional, - .visit_statement_loop = printer_visit_statement_loop, - .visit_statement_return = printer_visit_statement_return, - .visit_statement_break = printer_visit_statement_break, - .visit_statement_continue = printer_visit_statement_continue, - .visit_statement_defer = printer_visit_statement_defer, - - .visit_expression = printer_visit_expression, - .visit_expression_integer_literal = printer_visit_expression_integer_literal, - .visit_expression_float_literal = printer_visit_expression_float_literal, - .visit_expression_string_literal = printer_visit_expression_string_literal, - .visit_expression_boolean_literal = printer_visit_expression_boolean_literal, - .visit_expression_name = printer_visit_expression_name, - .visit_expression_unary_operation = printer_visit_expression_unary_operation, - .visit_expression_binary_operation = printer_visit_expression_binary_operation, - .visit_expression_group = printer_visit_expression_group, - .visit_expression_call = printer_visit_expression_call, - .visit_expression_construct = printer_visit_expression_construct, - .visit_expression_subscript = printer_visit_expression_subscript, - .visit_expression_member = printer_visit_expression_member, - .visit_expression_increment_decrement = printer_visit_expression_increment_decrement, - .visit_expression_try = printer_visit_expression_try, - .visit_expression_must = printer_visit_expression_must, - .visit_expression_function = printer_visit_expression_function, - - .visit_type_node = printer_visit_type_node, - .visit_type_node_name = printer_visit_type_node_name, - .visit_type_node_array = printer_visit_type_node_array, - .visit_type_node_reference = printer_visit_type_node_reference, - .visit_type_node_maybe = printer_visit_type_node_maybe, - .visit_type_node_tuple = printer_visit_type_node_tuple, - .visit_type_node_map = printer_visit_type_node_map, - .visit_type_node_function = printer_visit_type_node_function, - .visit_type_node_structure = printer_visit_type_node_structure, - .visit_type_node_variant = printer_visit_type_node_variant, - .visit_type_node_class = printer_visit_type_node_class, - - .visit_block_node = printer_visit_block_node, - .visit_bare_declaration_node = printer_visit_bare_declaration_node, +struct Tree_Visit_Table tree_printer_visit_functions = { + .visit_tree = tree_printer_visit_tree, + + .visit_statement = tree_printer_visit_statement, + .visit_statement_declaration = tree_printer_visit_statement_declaration, + .visit_statement_conditional = tree_printer_visit_statement_conditional, + .visit_statement_loop = tree_printer_visit_statement_loop, + .visit_statement_return = tree_printer_visit_statement_return, + .visit_statement_break = tree_printer_visit_statement_break, + .visit_statement_continue = tree_printer_visit_statement_continue, + .visit_statement_defer = tree_printer_visit_statement_defer, + + .visit_expression = tree_printer_visit_expression, + .visit_expression_integer_literal = tree_printer_visit_expression_integer_literal, + .visit_expression_float_literal = tree_printer_visit_expression_float_literal, + .visit_expression_string_literal = tree_printer_visit_expression_string_literal, + .visit_expression_boolean_literal = tree_printer_visit_expression_boolean_literal, + .visit_expression_name = tree_printer_visit_expression_name, + .visit_expression_unary_operation = tree_printer_visit_expression_unary_operation, + .visit_expression_binary_operation = tree_printer_visit_expression_binary_operation, + .visit_expression_group = tree_printer_visit_expression_group, + .visit_expression_call = tree_printer_visit_expression_call, + .visit_expression_construct = tree_printer_visit_expression_construct, + .visit_expression_subscript = tree_printer_visit_expression_subscript, + .visit_expression_member = tree_printer_visit_expression_member, + .visit_expression_increment_decrement = tree_printer_visit_expression_increment_decrement, + .visit_expression_try = tree_printer_visit_expression_try, + .visit_expression_must = tree_printer_visit_expression_must, + .visit_expression_function = tree_printer_visit_expression_function, + + .visit_type_node = tree_printer_visit_type, + .visit_type_node_name = tree_printer_visit_type_name, + .visit_type_node_array = tree_printer_visit_type_array, + .visit_type_node_reference = tree_printer_visit_type_reference, + .visit_type_node_maybe = tree_printer_visit_type_maybe, + .visit_type_node_tuple = tree_printer_visit_type_tuple, + .visit_type_node_map = tree_printer_visit_type_map, + .visit_type_node_function = tree_printer_visit_type_function, + .visit_type_node_structure = tree_printer_visit_type_structure, + .visit_type_node_variant = tree_printer_visit_type_variant, + .visit_type_node_class = tree_printer_visit_type_class, + + .visit_block_node = tree_printer_visit_block, + .visit_bare_declaration_node = tree_printer_visit_bare_declaration, .visit_function_header_node = printer_visit_function_header, - .visit_argument_group_node = printer_visit_argument_group_node, - .visit_pragma_node = printer_visit_pragma_node, + .visit_argument_group_node = tree_printer_visit_argument_group, + .visit_pragma_node = tree_printer_visit_pragma, }; void @@ -1175,9 +1175,9 @@ tree_printer(struct Tree* tree) struct Tree_Printer printer = { .indentation_level = 0, .output = stdout, .did_print_last_visit = false }; - struct Visit visit = { .table = &printer_visit_functions, .user_data = &printer }; + struct Tree_Visit visit = { .table = &tree_printer_visit_functions, .user_data = &printer }; - walk(&visit, tree); + tree_walk(&visit, tree); } #undef PRINT |
