diff options
| author | WormHeamer | 2025-08-07 00:50:01 -0400 |
|---|---|---|
| committer | WormHeamer | 2025-08-07 00:50:01 -0400 |
| commit | 9c5d50e5371cd26d7ae8fd896dc06fa9af684949 (patch) | |
| tree | 9140ba2ba6d6be752665cfb51ffb57262c4ba38e /main.c | |
| parent | 632f2e43d43eaae936cc0567ef18bb25f94e1bdd (diff) | |
add if statements
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 89 |
1 files changed, 83 insertions, 6 deletions
@@ -12,7 +12,7 @@ #include "strio.h" #include "ir.h" -int no_opt = 0; +int no_opt = 1; typedef struct { DYNARR(Proc) procs; @@ -35,7 +35,9 @@ Node *parse_expr(Lexer *l, Proc *p); void parse_return(Lexer *l, Proc *p) { lex_next(l); - p->stop = node_new(p, N_RETURN, p->start, parse_expr(l, p)); + Node *n = node_new(p, N_RETURN, p->ctrl, parse_expr(l, p)); + node_add(p, n, p->stop); + p->ctrl = n; } void parse_let(Lexer *l, Proc *p) { @@ -57,13 +59,16 @@ recurse: void parse_stmt(Lexer *l, Proc *p); /* TODO: return node from this! */ -void parse_block(Lexer *l, Proc *p) { +void parse_block(Lexer *l, Proc *p, ScopeNameList *nl) { lex_next(l); scope_push(&p->scope, p); while (l->tok != TOK_RBRACE) { lex_expected_not(l, TM_EOF); parse_stmt(l, p); } + if (nl) { + scope_collect(&p->scope, p, nl, &p->arena); + } scope_pop(&p->scope, p); lex_expected(l, TM_RBRACE); lex_next(l); @@ -80,6 +85,76 @@ void parse_assign(Lexer *l, Proc *p) { } } +void merge_scope(Proc *p, ScopeNameList *na, ScopeNameList *nb) { + for (ScopeFrame *f = p->scope.tail; f; f = f->prev) { + for (NameBinding *b = f->latest; b; b = b->prev) { + int i, j; + for (i = 0; i < na->len && !str_eql(na->data[i].name, b->name); i++); + for (j = 0; j < nb->len && !str_eql(nb->data[j].name, b->name); j++); + if (i >= na->len && j >= nb->len) continue; /* no change */ + Node *phi; + if (i >= na->len) { + phi = node_new(p, N_PHI, p->ctrl, b->node, nb->data[j].node); + } else if (j >= na->len) { + phi = node_new(p, N_PHI, p->ctrl, na->data[i].node, b->node); + } else { + phi = node_new(p, N_PHI, p->ctrl, na->data[i].node, nb->data[j].node); + } + node_add(p, phi, p->keepalive); + node_remove(p, b->node, p->keepalive); + b->node = phi; + } + } + + for (int i = 0; i < na->len; i++) node_remove(p, na->data[i].node, p->keepalive); + for (int i = 0; i < nb->len; i++) node_remove(p, nb->data[i].node, p->keepalive); +} + +void parse_if(Lexer *l, Proc *p) { + lex_next(l); + Node *cond = parse_expr(l, p); + Node *ctrl_if = NULL, *ctrl_else = NULL; + Node *if_node = node_new(p, N_IF_ELSE, p->ctrl, cond); + if_node->val = (Value) { + .type = { T_TOP, T_TUPLE, NULL }, + .tuple = { + .len = 2, + .cap = 0, + .data = (Value[2]) { + { .type = { T_CTRL, T_NONE, NULL } }, + { .type = { T_CTRL, T_NONE, NULL } }, + } + } + }; + Node *if_true = node_new(p, N_PROJ, if_node); + Node *if_false = node_new(p, N_PROJ, if_node); + ScopeNameList scope_before = { 0 }, scope_true = { 0 }, scope_false = { 0 }; + if_true->val.i = 0; + if_false->val.i = 1; + scope_collect(&p->scope, p, &scope_before, &p->arena); + NODE_KEEP(p, cond, { + p->ctrl = if_true; + lex_expected(l, TM_LBRACE); + parse_block(l, p, &scope_true); + ctrl_if = p->ctrl; + if (l->tok == TOK_ELSE) { + NODE_KEEP(p, ctrl_if, { + p->ctrl = if_false; + lex_expect(l, TM_LBRACE); + parse_block(l, p, &scope_false); + ctrl_else = p->ctrl; + }); + } + }); + if (ctrl_else) { + p->ctrl = node_new(p, N_REGION, ctrl_if, ctrl_else); + merge_scope(p, &scope_true, &scope_false); + } else { + p->ctrl = node_new(p, N_REGION, ctrl_if, if_false); + merge_scope(p, &scope_before, &scope_true); + } +} + void parse_stmt(Lexer *l, Proc *p) { /* TODO */ (void)l; @@ -91,18 +166,20 @@ void parse_stmt(Lexer *l, Proc *p) { parse_let(l, p); break; case TOK_LBRACE: - parse_block(l, p); + parse_block(l, p, NULL); break; case TOK_IDENT: parse_assign(l, p); break; + case TOK_IF: + parse_if(l, p); + break; default: lex_expected(l, TM_RBRACE); break; } } - Type parse_type(Lexer *l, Proc *proc) { (void)proc; Type t = { .lvl = T_BOT }; @@ -137,7 +214,7 @@ void parse_args_list(Lexer *l, Proc *proc) { lex_expect(l, TM_IDENT | TM_COMMA); if (l->tok == TOK_COMMA) continue; Value v = (Value) { .type = parse_type(l, proc) }; - ZDA_PUSH(&start->val.tuple, v, &proc->arena); + ZDA_PUSH(&proc->arena, &start->val.tuple, v); lex_expected(l, TM_RPAREN | TM_COMMA); for (int j = 0; j < id; j++) { Node *proj = node_new(proc, N_PROJ, proc->start); |
