summaryrefslogtreecommitdiff
path: root/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'ir.c')
-rw-r--r--ir.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/ir.c b/ir.c
index e3d64f5..dd8b66c 100644
--- a/ir.c
+++ b/ir.c
@@ -64,11 +64,19 @@ void type_err(Node *n, Lexer *l) {
if (i > 0) str_cat(&s, S(", "), &l->arena);
str_cat(&s, type_desc(&IN(n, i)->val.type, &l->arena), &l->arena);
}
- lex_error_at(l, n->src_pos, LE_ERROR, str_fmt(&l->arena, "type error (%S)", s));
+ lex_error_at(l, n->src_pos, LE_ERROR, str_fmt(&l->arena, "type error %s (%S)", node_type_name(n->type), s));
}
int type_check(Node *n) {
switch (n->type) {
+ case N_PHI:
+ n->val.type = (Type) { .lvl = T_TOP, .t = IN(n, 1)->val.type.t };
+ for (int i = 2; i < n->in.len; i++) {
+ if (!type_base_eql(&IN(n, i)->val.type, &n->val.type)) {
+ return 0;
+ }
+ }
+ return 1;
case N_OP_NEG:
n->val.type = (Type) { .lvl = T_TOP, .t = T_INT };
return CAR(n)->val.type.t == T_INT;
@@ -103,7 +111,7 @@ int type_check(Node *n) {
const char *node_type_name(NodeType t) {
const char *names[] = {
"N/A",
- "start",
+ "start", "if-else", "region", "phi", "stop",
"projection",
"return",
"keepalive",
@@ -163,12 +171,12 @@ void node_kill(Node *n, Proc *p) {
}
void node_add_out(Proc *p, Node *a, Node *b) {
- ZDA_PUSH(&a->out, b, &p->arena);
+ ZDA_PUSH(&p->arena, &a->out, b);
b->refs++;
}
void node_add_in(Proc *p, Node *a, Node *b) {
- ZDA_PUSH(&a->in, b, &p->arena);
+ ZDA_PUSH(&p->arena, &a->in, b);
b->refs++;
}
@@ -745,6 +753,8 @@ void proc_init(Proc *proc, Str name) {
.t = T_TUPLE,
.next = NULL
};
+ proc->stop = node_new_empty(proc, N_STOP);
+ proc->ctrl = proc->start;
proc->keepalive = node_new_empty(proc, N_KEEPALIVE);
proc->name = name;
}
@@ -823,3 +833,13 @@ NameBinding *scope_update(Scope *scope, Str name, Node *to, Proc *proc) {
b->node = to;
return b;
}
+
+/* adds to keepalive so these aren't invalidated */
+void scope_collect(Scope *scope, Proc *proc, ScopeNameList *nl, Arena *arena) {
+ for (ScopeFrame *f = scope->tail; f; f = f->prev) {
+ for (NameBinding *b = f->latest; b; b = b->prev) {
+ node_add_out(proc, b->node, proc->keepalive);
+ ZDA_PUSH(arena, nl, (ScopeName) { b->name, b->node });
+ }
+ }
+}