From 59cf0e45d701bd7ec0bbdbf10f69ec7cec66051a Mon Sep 17 00:00:00 2001 From: Mel Date: Mon, 4 May 2026 21:19:42 +0200 Subject: Lower source if + while + endless statements Signed-off-by: Mel --- boot/lower.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) (limited to 'boot') diff --git a/boot/lower.c b/boot/lower.c index 4a831d9..9531483 100644 --- a/boot/lower.c +++ b/boot/lower.c @@ -882,7 +882,8 @@ lower_pop_scope(struct Lower_Context* ctx, enum Scope_Type expected) struct Scope* top = array_at(struct Scope, &ctx->scope_stack, ctx->scope_stack.length - 1); - check(top->type == expected, "scope type mismatch on pop: expected %d, got %d", (int)expected, (int)top->type); + check(top->type == expected, "scope type mismatch on pop: expected %d, got %d", (int)expected, + (int)top->type); check(expected != SCOPE_TYPE_UNIT, "lowering pass tried popping top-level unit scope"); --ctx->scope_stack.length; @@ -955,8 +956,7 @@ lower_statement(struct Lower_Context* ctx, struct Tree_Statement* tree_stmt) union Statement_Value v = { 0 }; v.declaration.name = name; v.declaration.type = type; - if (decl->initializer) - v.declaration.initializer = lower_expression(ctx, decl->initializer); + if (decl->initializer) v.declaration.initializer = lower_expression(ctx, decl->initializer); return statement_new(STATEMENT_DECLARATION, v, tree_stmt->span); } @@ -996,6 +996,58 @@ lower_statement(struct Lower_Context* ctx, struct Tree_Statement* tree_stmt) return statement_new(STATEMENT_BLOCK, v, tree_stmt->span); } + case TREE_STATEMENT_CONDITIONAL: { + struct Tree_Statement_Value_Conditional* cond = &tree_stmt->value.conditional; + union Statement_Value v = { 0 }; + v.conditional.branches = array_new(struct If_Branch, 8); + + for (uint i = 0; i < cond->condition_count; ++i) { + struct If_Branch branch = { + .condition = + cond->conditions[i].when + ? lower_expression(ctx, cond->conditions[i].when) + : nil, + .body = lower_block(ctx, &cond->conditions[i].then), + }; + array_push(&v.conditional.branches, &branch); + } + + return statement_new(STATEMENT_CONDITIONAL, v, tree_stmt->span); + } + case TREE_STATEMENT_LOOP: { + struct Tree_Statement_Value_Loop* loop = &tree_stmt->value.loop; + union Statement_Value v = { 0 }; + + switch (loop->style) { + case TREE_STATEMENT_LOOP_STYLE_WHILE: + v.loop.condition = lower_expression(ctx, loop->condition); + v.loop.body = lower_block(ctx, &loop->body); + + break; + case TREE_STATEMENT_LOOP_STYLE_ENDLESS: { + // synthesize a `true` literal + union Expression_Value tv = { 0 }; + tv.bool_literal.value = true; + v.loop.condition = expression_new(EXPRESSION_BOOLEAN_LITERAL, tv, tree_stmt->span); + v.loop.body = lower_block(ctx, &loop->body); + + break; + } + case TREE_STATEMENT_LOOP_STYLE_C: + case TREE_STATEMENT_LOOP_STYLE_FOR_EACH: + lower_emit_error_c( + ctx->unit, tree_stmt->span, "unimplemented: c-style and for-each loops"); + return nil; + default: + lower_emit_error_c(ctx->unit, tree_stmt->span, "unknown loop style"); + return nil; + } + return statement_new(STATEMENT_LOOP, v, tree_stmt->span); + } + case TREE_STATEMENT_BREAK: + return statement_new(STATEMENT_BREAK, (union Statement_Value){ 0 }, tree_stmt->span); + case TREE_STATEMENT_CONTINUE: + return statement_new(STATEMENT_CONTINUE, (union Statement_Value){ 0 }, tree_stmt->span); default: lower_emit_error_c(ctx->unit, tree_stmt->span, "unimplemented: this statement kind"); return nil; -- cgit 1.4.1