diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 44 |
1 files changed, 27 insertions, 17 deletions
@@ -127,7 +127,7 @@ recurse: void parse_stmt(Lexer *l, Proc *p); /* TODO: return node from this! */ -void parse_block(Lexer *l, Proc *p, ScopeNameList *nl) { +void parse_block(Lexer *l, Proc *p) { Graph *g = &p->graph; lex_next(l); arena_reset(&p->scratch); @@ -136,9 +136,6 @@ void parse_block(Lexer *l, Proc *p, ScopeNameList *nl) { lex_expected_not(l, TM_EOF); parse_stmt(l, p); } - if (nl) { - scope_collect(&p->scope, g, nl, &p->scratch); - } scope_pop(&p->scope, g); lex_expected(l, TM_RBRACE); lex_next(l); @@ -163,7 +160,7 @@ void parse_assign(Lexer *l, Proc *p) { str_fmt(&p->scratch, "possibly uninitialized %S", type_desc(&e->type, &p->scratch))); } - scope_update(b, e, &p->graph); + scope_update(&p->scope, b, e, &p->graph); } /* TODO: Implement a better system for this. @@ -199,6 +196,7 @@ void parse_assign(Lexer *l, Proc *p) { * */ +#if 0 void merge_scope(Lexer *l, Proc *p, Node *region, ScopeNameList *before, ScopeNameList *ntrue, ScopeNameList *nfalse) { Graph *g = &p->graph; for (int i = 0; i < before->len; i++) { @@ -226,6 +224,7 @@ void merge_scope(Lexer *l, Proc *p, Node *region, ScopeNameList *before, ScopeNa scope_update(b, phi, g); } } +#endif /* TODO: find out a way to encode known relations between nodes, based on the * conditional, within the body of an if statement --- e.g., for a statement @@ -272,31 +271,41 @@ void parse_if(Lexer *l, Proc *p) { assert(if_false->in.len > 0); node_add(g, if_true, g->keepalive); node_add(g, if_false, g->keepalive); - ScopeNameList scope_before = { 0 }, scope_true = { 0 }, scope_false = { 0 }; - scope_collect(&p->scope, g, &scope_before, &p->scratch); + + ScopeChangeList chg_if = { 0 }; + ScopeChangeList chg_else = { 0 }; + if (cond->type.lvl == T_CONST) { if (cond->val.i) if_false->type.lvl = T_XCTRL; else if_true->type.lvl = T_XCTRL; } + ctrl(g, if_true); lex_expected(l, TM_LBRACE); int pos = l->pos.ofs; - parse_block(l, p, &scope_true); + + scope_changelist_push(&p->scope, &chg_if, &p->scratch); + parse_block(l, p); + scope_changelist_pop(&p->scope, g); + if_true->src_pos = (LexSpan) { .ofs = pos, .n = l->pos.ofs - pos }; ctrl_if = g->ctrl; node_add(g, ctrl_if, g->keepalive); + if (l->tok == TOK_ELSE) { - for (int i = 0; i < scope_before.len; i++) { - scope_update(scope_find(&p->scope, scope_before.data[i].name), scope_before.data[i].node, g); - } ctrl(g, if_false); lex_expect(l, TM_LBRACE); pos = l->pos.ofs; - parse_block(l, p, &scope_false); + + scope_changelist_push(&p->scope, &chg_else, &p->scratch); + parse_block(l, p); + scope_changelist_pop(&p->scope, g); + if_false->src_pos = (LexSpan) { .ofs = pos, .n = l->pos.ofs - pos }; ctrl_else = g->ctrl; node_add(g, ctrl_else, g->keepalive); } + Node *region; if (ctrl_else) { assert(ctrl_if); @@ -320,11 +329,12 @@ void parse_if(Lexer *l, Proc *p) { assert(g->ctrl->in.len > 0); assert(region->in.data[0]); assert(region->in.data[1]); - merge_scope(l, p, region, &scope_before, &scope_true, &scope_false); - scope_uncollect(&p->scope, g, &scope_true); - scope_uncollect(&p->scope, g, &scope_false); - scope_uncollect(&p->scope, g, &scope_before); + + scope_changelist_merge(&p->scope, &chg_if, &chg_else, region, g, &p->scratch); + scope_changelist_discard(&chg_if, g); + scope_changelist_discard(&chg_else, g); node_del_out(region, g->keepalive); + /* make sure we're not orphaning any phi nodes*/ if (g->ctrl->out.len < 1) { ctrl(g, node_peephole(g->ctrl, g, l)); @@ -342,7 +352,7 @@ void parse_stmt(Lexer *l, Proc *p) { parse_let(l, p); break; case TOK_LBRACE: - parse_block(l, p, NULL); + parse_block(l, p); break; case TOK_IDENT: parse_assign(l, p); |
