diff options
Diffstat (limited to 'boot/tree.c')
| -rw-r--r-- | boot/tree.c | 116 |
1 files changed, 79 insertions, 37 deletions
diff --git a/boot/tree.c b/boot/tree.c index dff0858..adee06a 100644 --- a/boot/tree.c +++ b/boot/tree.c @@ -408,6 +408,22 @@ struct Function_Header_Node void function_header_node_print(const struct Function_Header_Node* header); +// a declaration of a variable, constant, or other binding, without a mutability +// 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 String_Array names; + struct Expression* initializer; + struct Type_Node* type; + + struct Span span; + struct Cursor location; +}; + +void bare_declaration_node_print(const struct Bare_Declaration_Node* declaration); + enum Type_Node_Type { TYPE_NODE_NONE, @@ -936,9 +952,7 @@ statement_declaration_kind_from_token(const struct Token* token) struct Statement_Value_Declaration { enum Statement_Declaration_Kind kind; - struct String_Array names; - struct Expression* initializer; - struct Type_Node* type; + struct Bare_Declaration_Node inner; }; struct Statement_Value_Block @@ -959,13 +973,20 @@ struct Statement_Value_Conditional uint condition_count; }; +enum 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 {} +}; + +// stands for both `for` and `while` loops. struct Statement_Value_Loop { - // exists for iterator-style + c-style loops. - struct Statement* declaration; - // exists for all loop types, except for infinite loops. + enum Statement_Loop_Style style; + struct Bare_Declaration_Node declaration; struct Expression* condition; - // exists for c-style loops. struct Expression* iteration; struct Block_Node body; @@ -1033,6 +1054,27 @@ block_node_print(const struct Block_Node* block) printf(")"); } +void +bare_declaration_node_print(const struct Bare_Declaration_Node* declaration) +{ + printf("(declaration "); + STRING_ARRAY_FOR_EACH(i, name, declaration->names) + { + printf("%s ", name.data); + } + if (!type_node_is_none(declaration->type)) { + type_node_print(declaration->type); + printf(" "); + } + + if (declaration->initializer) { + printf("(initializer "); + expression_print(declaration->initializer); + printf(")"); + } + printf(")"); +} + struct Statement* statement_new( enum Statement_Kind kind, union Statement_Value value, struct Span span, struct Cursor location) @@ -1063,24 +1105,12 @@ statement_print(const struct Statement* statement) break; } case STATEMENT_DECLARATION: { - printf("(declaration "); if (statement->value.declaration.kind == STATEMENT_DECLARATION_VARIABLE) - printf("variable "); + printf("(variable "); else if (statement->value.declaration.kind == STATEMENT_DECLARATION_CONSTANT) - printf("constant "); + printf("(constant "); - STRING_ARRAY_FOR_EACH(i, name, statement->value.declaration.names) - { - printf("%s ", name.data); - } - if (type_node_is_none(statement->value.declaration.type)) - type_node_print(statement->value.declaration.type); - - if (statement->value.declaration.initializer) { - printf("(initializer "); - expression_print(statement->value.declaration.initializer); - printf(")"); - } + bare_declaration_node_print(&statement->value.declaration.inner); printf(")"); break; } @@ -1109,25 +1139,37 @@ statement_print(const struct Statement* statement) } case STATEMENT_LOOP: { printf("(loop "); - if (statement->value.loop.declaration) { - printf("(declaration "); - statement_print(statement->value.loop.declaration); - printf(") "); - } - if (statement->value.loop.condition) { - printf("(condition "); - expression_print(statement->value.loop.condition); - printf(") "); - } - - if (statement->value.loop.iteration) { - printf("(iteration "); - expression_print(statement->value.loop.iteration); - printf(") "); + switch (statement->value.loop.style) { + case STATEMENT_LOOP_STYLE_C: + printf("c-style "); + bare_declaration_node_print(&statement->value.loop.declaration); + printf(" (condition "); + expression_print(statement->value.loop.condition); + printf(") (iteration "); + expression_print(statement->value.loop.iteration); + printf(") "); + break; + case STATEMENT_LOOP_STYLE_FOR_EACH: + printf("for-each "); + bare_declaration_node_print(&statement->value.loop.declaration); + printf(" "); + break; + case STATEMENT_LOOP_STYLE_WHILE: + printf("while (condition "); + expression_print(statement->value.loop.condition); + printf(") "); + break; + case STATEMENT_LOOP_STYLE_ENDLESS: + printf("endless "); + break; + default: + failure("unexpected loop style in `statement_print`"); + break; } block_node_print(&statement->value.loop.body); + printf(")"); break; } case STATEMENT_RETURN: { |
