summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c12
-rw-r--r--proc.c11
-rw-r--r--proc.h3
-rw-r--r--test.lang9
4 files changed, 25 insertions, 10 deletions
diff --git a/main.c b/main.c
index 3315f2a..9b22751 100644
--- a/main.c
+++ b/main.c
@@ -253,12 +253,17 @@ void parse_if(Lexer *l, Proc *p) {
Node *if_node = node_new(g, N_IF_ELSE, g->ctrl, cond);
if_node->val = (Value) {
.type = { .lvl = T_TOP, .t = T_TUPLE },
- .tuple = { 0 }
+ .tuple = {
+ .len = 2,
+ .cap = 2,
+ .data = new_arr(g->pool->arena, Value, 2)
+ }
};
- ZDA_PUSH(g->pool->arena, &if_node->val.tuple, (Value) { .type = { .lvl = T_CTRL, .t = T_NONE } });
- ZDA_PUSH(g->pool->arena, &if_node->val.tuple, (Value) { .type = { .lvl = T_CTRL, .t = T_NONE } });
+ if_node->val.tuple.data[0] = (Value) { .type = { .lvl = T_CTRL, .t = T_NONE } };
+ if_node->val.tuple.data[1] = (Value) { .type = { .lvl = T_CTRL, .t = T_NONE } };
if_node = node_peephole(if_node, g, l);
node_add(g, if_node, g->keepalive);
+
Node *if_true = node_new(g, N_PROJ, if_node);
Node *if_false = node_new(g, N_PROJ, if_node);
if_true->val.i = 0;
@@ -266,6 +271,7 @@ void parse_if(Lexer *l, Proc *p) {
if_true = node_peephole(if_true, g, l);
if_false = node_peephole(if_false, g, l);
node_remove(g, if_node, g->keepalive);
+
assert(if_true->in.len > 0);
assert(if_false->in.len > 0);
node_add(g, if_true, g->keepalive);
diff --git a/proc.c b/proc.c
index 7e983ca..1fe00a8 100644
--- a/proc.c
+++ b/proc.c
@@ -1,5 +1,6 @@
#include <string.h>
#include "proc.h"
+#include "peephole.h"
/* procedures */
@@ -93,6 +94,7 @@ NameBinding *scope_bind(Scope *scope, Str name, Node *value, LexSpan pos, Graph
} else {
b = new(scope->arena, NameBinding);
}
+ b->nestlvl = scope->nestlvl;
b->name = name;
b->prev = scope->tail->latest;
scope->tail->latest = b;
@@ -152,6 +154,7 @@ void scope_changelist_pop(Scope *scope, Graph *g) {
}
}
+#include <assert.h>
#include <stdio.h>
/* TODO: implement merge, probably will need scratch arena to build up
* a Xar of something like struct { NameBinding *b; Node *y, *n; }. if
@@ -162,7 +165,7 @@ typedef struct {
NameBinding *b;
Node *y, *n;
} MergeChange;
-void scope_changelist_merge(Scope *scope, ScopeChangeList *y, ScopeChangeList *n, Node *region, Graph *graph, Arena *scratch) {
+void scope_changelist_merge(Scope *scope, Lexer *l, ScopeChangeList *y, ScopeChangeList *n, Node *region, Graph *graph, Arena *scratch) {
MergeChange *m = new_arr(scratch, MergeChange, y->n + n->n);
unsigned c = 0;
for (unsigned i = 0; i < y->n; i++) {
@@ -187,7 +190,11 @@ void scope_changelist_merge(Scope *scope, ScopeChangeList *y, ScopeChangeList *n
c++;
next:
}
- fprintf(stderr, "%u\n", c);
+ for (unsigned i = 0; i < c; i++) {
+ Node *phi = node_new(graph, N_PHI, region, m[i].y, m[i].n);
+ phi = node_peephole(phi, graph, l);
+ scope_update(scope, m[i].b, phi, graph);
+ }
}
void scope_changelist_discard(ScopeChangeList *l, Graph *g) {
diff --git a/proc.h b/proc.h
index 3ef49a9..b95c149 100644
--- a/proc.h
+++ b/proc.h
@@ -20,7 +20,6 @@ typedef struct ScopeFrame {
typedef struct {
NameBinding *bind;
Node *from, *to;
- LexSpan from_pos, to_pos;
} ScopeChange;
typedef struct ScopeChangeList {
@@ -46,7 +45,7 @@ NameBinding *scope_update(Scope *scope, NameBinding *b, Node *to, Graph *g);
void scope_changelist_update(ScopeChangeList *l, NameBinding *b, Node *from, Node *to, Graph *g);
void scope_changelist_push(Scope *scope, ScopeChangeList *l, Arena *a);
void scope_changelist_pop(Scope *scope, Graph *g);
-void scope_changelist_merge(Scope *scope, ScopeChangeList *y, ScopeChangeList *n, Node *region, Graph *graph, Arena *scratch);
+void scope_changelist_merge(Scope *scope, Lexer *l, ScopeChangeList *y, ScopeChangeList *n, Node *region, Graph *graph, Arena *scratch);
void scope_changelist_discard(ScopeChangeList *l, Graph *g);
typedef struct {
diff --git a/test.lang b/test.lang
index 6dc6a5b..15a3338 100644
--- a/test.lang
+++ b/test.lang
@@ -1,9 +1,12 @@
func main(a, b i64) i64 {
if a < b {
- a := 4
+ if a = 5 {
+ a := 2
+ } else {
+ a := 7
+ }
} else {
- a := 2
- b := 5
+ a := 4
}
return a + b
}