aboutsummaryrefslogtreecommitdiff
path: root/src/ssa.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-11-29 22:08:48 +0000
committerGinger Bill <bill@gingerbill.org>2016-11-29 22:08:48 +0000
commitb232b9d5ea23fdd4d53f8e93cdfeb1f962811331 (patch)
tree6b4fbe56bf1fc7e7929104790cfb05b42b5f4071 /src/ssa.c
parent348bcc3f9a1375ddf24b952fad537b5c84e84053 (diff)
Basic `when` statement - Compile time if statement
This is similar to an #if in C but handled during the semantic checking stage.
Diffstat (limited to 'src/ssa.c')
-rw-r--r--src/ssa.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/ssa.c b/src/ssa.c
index a97a5c9ae..e9262391c 100644
--- a/src/ssa.c
+++ b/src/ssa.c
@@ -3815,6 +3815,29 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
proc->module->stmt_state_flags = prev_stmt_state_flags;
}
+void ssa_build_when_stmt(ssaProcedure *proc, AstNodeWhenStmt *ws) {
+ ssaValue *cond = ssa_build_expr(proc, ws->cond);
+ GB_ASSERT(cond->kind == ssaValue_Constant &&
+ is_type_boolean(ssa_type(cond)));
+
+ GB_ASSERT(cond->Constant.value.kind == ExactValue_Bool);
+ if (cond->Constant.value.value_bool) {
+ ssa_build_stmt_list(proc, ws->body->BlockStmt.stmts);
+ } else if (ws->else_stmt) {
+ switch (ws->else_stmt->kind) {
+ case AstNode_BlockStmt:
+ ssa_build_stmt_list(proc, ws->else_stmt->BlockStmt.stmts);
+ break;
+ case AstNode_WhenStmt:
+ ssa_build_when_stmt(proc, &ws->else_stmt->WhenStmt);
+ break;
+ default:
+ GB_PANIC("Invalid `else` statement in `when` statement");
+ break;
+ }
+ }
+}
+
void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
switch (node->kind) {
case_ast_node(bs, EmptyStmt, node);
@@ -3827,6 +3850,10 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
}
case_end;
+ case_ast_node(ws, WhenStmt, node);
+ ssa_build_when_stmt(proc, ws);
+ case_end;
+
case_ast_node(vd, VarDecl, node);
ssaModule *m = proc->module;
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);