about summary refs log tree commit diff
path: root/boot
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2026-05-04 21:19:42 +0200
committerMel <mel@rnrd.eu>2026-05-04 21:19:42 +0200
commit59cf0e45d701bd7ec0bbdbf10f69ec7cec66051a (patch)
treea38eb53feb3b23e5f4bd2487e97fd41ff11728de /boot
parent8783c2c0a3465d380376ba346f6bea4525ddd379 (diff)
downloadcatskill-59cf0e45d701bd7ec0bbdbf10f69ec7cec66051a.tar.zst
catskill-59cf0e45d701bd7ec0bbdbf10f69ec7cec66051a.zip
Lower source if + while + endless statements
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'boot')
-rw-r--r--boot/lower.c58
1 files changed, 55 insertions, 3 deletions
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;