summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c70
1 files changed, 40 insertions, 30 deletions
diff --git a/main.c b/main.c
index 11c4e00..8265aab 100644
--- a/main.c
+++ b/main.c
@@ -85,7 +85,7 @@ void parse_assign(Lexer *l, Proc *p) {
}
}
-void merge_scope(Proc *p, ScopeNameList *na, ScopeNameList *nb) {
+void merge_scope(Lexer *l, 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;
@@ -94,20 +94,21 @@ void merge_scope(Proc *p, ScopeNameList *na, ScopeNameList *nb) {
if (i >= na->len && j >= nb->len) continue; /* no change */
Node *phi;
if (i >= na->len) {
+ if (nb->data[j].node == b->node) continue;
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);
+ if (na->data[i].node == b->node) continue;
+ phi = node_new(p, N_PHI, p->ctrl, b->node, na->data[i].node);
} else {
+ if (na->data[i].node == b->node && nb->data[j].node == b->node) continue;
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);
+ phi = node_peephole(phi, p, l);
+ node_add(p, phi, 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) {
@@ -117,21 +118,21 @@ void parse_if(Lexer *l, Proc *p) {
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 } },
- }
- }
+ .tuple = { 0 }
};
- Node *if_true = node_new(p, N_PROJ, if_node);
- Node *if_false = node_new(p, N_PROJ, if_node);
+ ZDA_PUSH(&p->arena, &if_node->val.tuple, (Value) { .type = { T_CTRL, T_NONE, NULL } });
+ ZDA_PUSH(&p->arena, &if_node->val.tuple, (Value) { .type = { T_CTRL, T_NONE, NULL } });
+ if_node = node_peephole(if_node, p, l);
+ Node *if_true = node_peephole(node_new(p, N_PROJ, if_node), p, l);
+ Node *if_false = node_peephole(node_new(p, N_PROJ, if_node), p, l);
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);
+ if (cond->val.type.lvl == T_CONST) {
+ if (cond->val.i) if_false->val.type.lvl = T_XCTRL;
+ else if_true->val.type.lvl = T_XCTRL;
+ }
NODE_KEEP(p, cond, {
p->ctrl = if_true;
lex_expected(l, TM_LBRACE);
@@ -147,12 +148,19 @@ void parse_if(Lexer *l, Proc *p) {
}
});
if (ctrl_else) {
- p->ctrl = node_new(p, N_REGION, ctrl_if, ctrl_else);
- merge_scope(p, &scope_true, &scope_false);
+ p->ctrl = node_peephole(node_new(p, N_REGION, ctrl_if, ctrl_else), p, l);
+ node_add(p, p->ctrl, p->keepalive);
+ merge_scope(l, p, &scope_true, &scope_false);
+ node_remove(p, p->ctrl, p->keepalive);
} else {
- p->ctrl = node_new(p, N_REGION, ctrl_if, if_false);
- merge_scope(p, &scope_before, &scope_true);
+ p->ctrl = node_peephole(node_new(p, N_REGION, ctrl_if, if_false), p, l);
+ node_add(p, p->ctrl, p->keepalive);
+ merge_scope(l, p, &scope_true, &scope_before);
+ node_remove(p, p->ctrl, p->keepalive);
}
+ scope_uncollect(&p->scope, p, &scope_true);
+ scope_uncollect(&p->scope, p, &scope_false);
+ scope_uncollect(&p->scope, p, &scope_before);
}
void parse_stmt(Lexer *l, Proc *p) {
@@ -214,12 +222,12 @@ 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(&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);
proj->val.type = v.type;
proj->val.i = i++;
+ ZDA_PUSH(&proc->arena, &start->val.tuple, v);
scope_bind(&proc->scope, idbuf[j].name, proj, idbuf[j].pos, proc);
}
id = 0;
@@ -264,7 +272,7 @@ Node *parse_term(Lexer *l, Proc *p) {
default: return node;
}
if (post_op == N_START) return node;
- return node_peephole(node_new(p, post_op, node), p, l);
+ return node_peephole(node_new(p, post_op, NULL, node), p, l);
}
if (l->tok == TOK_LPAREN) {
lex_next(l);
@@ -299,7 +307,7 @@ Node *parse_term(Lexer *l, Proc *p) {
lex_next(l);
}
if (op_after != N_START) {
- node = node_new(p, op_after, node_peephole(node, p, l));
+ node = node_new(p, op_after, NULL, node_peephole(node, p, l));
}
return node_peephole(node, p, l);
}
@@ -340,7 +348,7 @@ Node *parse_expr(Lexer *l, Proc *p) {
NODE_KEEP(p, lhs, {
rhs = parse_expr(l, p);
});
- lhs = node_peephole(node_new(p, nt, lhs, rhs), p, l);
+ lhs = node_peephole(node_new(p, nt, NULL, lhs, rhs), p, l);
}
lhs->src_pos = (LexSpan) { pos.ofs, l->pos.ofs - pos.ofs };
return lhs;
@@ -373,9 +381,6 @@ void parse_unit(Lexer *l) {
void node_print(Node *n, Proc *p) {
if (n->walked) return;
- const char *colors[] = {
- "red", "blue", "cyan", "green", "orange", "magenta",
- };
if (n->type == N_START) {
Str s = S("");
int c = n->val.tuple.len;
@@ -398,11 +403,12 @@ void node_print(Node *n, Proc *p) {
break;
}
} else if (n->type == N_PROJ) {
- printf("\t%d [label=\"PROJ(%ld)\", shape=record]", n->id, n->val.i);
+ Str d = type_desc(&n->in.data[0]->val.tuple.data[n->val.i].type, &p->arena);
+ printf("\t%d [label=\"%ld | %.*s\", shape=record]", n->id, n->val.i, (int)d.n, d.s);
} else {
printf("\t%d [label=\"%s\", shape=record]", n->id, node_type_name(n->type));
}
- printf(" [color=%s]\n", colors[n->id % (sizeof colors / sizeof *colors)]);
+ printf("\n");
n->walked = 1;
for (int i = 0; i < n->out.len; i++) {
Node *o = n->out.data[i];
@@ -411,7 +417,11 @@ void node_print(Node *n, Proc *p) {
} else {
int j;
for (j = 0; j < o->in.len && o->in.data[j] != n; j++);
- printf("\t%d -> %d [color=%s,headlabel=%d]\n", n->id, o->id, colors[o->id % (sizeof colors / sizeof *colors)], j);
+ if (j == 0) {
+ printf("\t%d -> %d [color=red,headlabel=%d]\n", n->id, o->id, j);
+ } else {
+ printf("\t%d -> %d [headlabel=%d]\n", n->id, o->id, j);
+ }
}
}
for (int i = 0; i < n->out.len; i++) {