summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorWormHeamer2025-10-21 05:47:19 -0400
committerWormHeamer2025-10-21 05:47:19 -0400
commit3ca04326ddb36b8551acf417ef195d1572bb3d47 (patch)
tree5b9d1d7bf90fcf60f883ca7ebe864b3a2281e2a5 /main.c
parentac15eb8b0ca41d502d8a26c360ff65f2b4a18d88 (diff)
almost there...
Diffstat (limited to 'main.c')
-rw-r--r--main.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/main.c b/main.c
index debb0ae..4f48ade 100644
--- a/main.c
+++ b/main.c
@@ -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);