aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/life.c84
-rw-r--r--examples/life.cff7
-rw-r--r--src/llvm.cff38
3 files changed, 117 insertions, 12 deletions
diff --git a/examples/life.c b/examples/life.c
new file mode 100644
index 0000000..212ece9
--- /dev/null
+++ b/examples/life.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+
+#define W 60
+#define H 40
+
+typedef unsigned char Board[W*H/8];
+static Board board;
+
+static _Bool
+get(Board *b, unsigned x, unsigned y) {
+ x %= W; y %= H;
+ unsigned idx = x + y * W;
+ return (*b)[idx/8] & (1 << (idx % 8));
+}
+
+static void
+set(Board *b, unsigned x, unsigned y, _Bool set) {
+ x %= W; y %= H;
+ unsigned idx = x + y * W;
+ (*b)[idx/8] &= ~(1 << (idx % 8));
+ if (set)
+ (*b)[idx/8] |= (1 << (idx % 8));
+}
+
+static void
+next(Board *b) {
+ Board temp;
+ memcpy(temp, &**b, sizeof temp);
+ for (int y = 0; y < H; ++y)
+ for (int x = 0; x < W; ++x) {
+ #define C(ox, oy) get(&temp, x + ox, y + oy)
+ int n = C(-1,-1) + C(0,-1) + C(1,-1)
+ + C(-1, 0) + C(1, 0)
+ + C(-1, 1) + C(0, 1) + C(1, 1);
+
+ set(b, x, y, 0);
+ if (get(&temp, x, y))
+ set(b, x, y, n == 3);
+ else if (n == 2)
+ set(b, x, y, 1);
+ else if (n == 3)
+ set(b, x, y, 1);
+ }
+}
+
+static
+void draw(Board *b) {
+ printf("\x1B[H\n");
+ printf("\n");
+ for (int y = 0; y < H; ++y) {
+ printf(" ");
+ for (int x = 0; x < W; ++x) {
+ if (get(b, x, y)) {
+ printf("W");
+ } else {
+ printf(" ");
+ }
+ }
+ printf(" \n");
+ }
+}
+
+
+static void
+init(Board *b) {
+ int time(void *);
+ unsigned rnd = time(0);
+ for (int y = 0; y < H; ++y) {
+ for (int x = 0; x < W; ++x) {
+ set(b, x, y, (_Bool)((rnd >> 31) & 1));
+ rnd = (rnd * 134775813) + 1;
+ }
+ }
+}
+
+void usleep(unsigned);
+int main () {
+ init(&board);
+ for (;;) {
+ draw(&board);
+ usleep(100);
+ next(&board);
+ }
+}
diff --git a/examples/life.cff b/examples/life.cff
index 791916f..e9c4dce 100644
--- a/examples/life.cff
+++ b/examples/life.cff
@@ -29,12 +29,7 @@ fn next(b *Board) void {
+ C(-1, 0) + C(1, 0)
+ C(-1, 1) + C(0, 1) + C(1, 1);
- set(b, x, y, #f);
- if get(&temp, x, y) {
- set(b, x, y, n == 3);
- } else if n == 2 or n == 3 {
- set(b, x, y, #t);
- }
+ set(b, x, y, get(&temp, x, y) ? n == 3 : (n == 2 or n == 3));
}
}
}
diff --git a/src/llvm.cff b/src/llvm.cff
index e2659af..4644ee5 100644
--- a/src/llvm.cff
+++ b/src/llvm.cff
@@ -508,16 +508,18 @@ fn genexpr(f *Fn, ex *Expr) Value {
let id = orid++;
let lhs = genexpr(f, b.lhs);
let cnd = mktmp(ty_i1);
+ let tmpvar = mktmp(mkptrtype(ex.ty));
let res = mktmp(ex.ty);
- gen("\tbr label %%OrEntry%d\n", id);
- gen("OrEntry%d: ", id);
+ gen("\t%v = alloca %t\n", tmpvar, ex.ty);
+ gen("\tstore %t %v, %t %v\n", ex.ty, lhs, tmpvar.ty, tmpvar);
gen("\t%v = icmp ne %t %v, 0\n", cnd, lhs.ty, lhs);
gen("\tbr i1 %v, label %%OrT%d, label %%OrF%d\n", cnd, id, id);
gen("OrF%d: ", id);
let rhs = genexpr(f, b.rhs);
+ gen("\tstore %t %v, %t %v\n", ex.ty, rhs, tmpvar.ty, tmpvar);
gen("\tbr label %%OrT%d\n", cnd, id, id);
gen("OrT%d: ", id);
- gen("\t%v = phi %t [ %v, %%OrEntry%d ], [ %v, %%OrF%d ]\n", res, ex.ty, lhs, id, rhs, id);
+ gen("\t%v = load %t, %t %v\n", res, ex.ty, tmpvar.ty, tmpvar);
return res;
case 'and';
@@ -525,21 +527,45 @@ fn genexpr(f *Fn, ex *Expr) Value {
let id = andid++;
let lhs = genexpr(f, b.lhs);
let cnd = mktmp(ty_i1);
+ let tmpvar = mktmp(mkptrtype(ex.ty));
let res = mktmp(ex.ty);
- gen("\tbr label %%AndEntry%d\n", id);
- gen("AndEntry%d: ", id);
+ gen("\t%v = alloca %t\n", tmpvar, ex.ty);
+ gen("\tstore %t %v, %t %v\n", ex.ty, lhs, tmpvar.ty, tmpvar);
gen("\t%v = icmp ne %t %v, 0\n", cnd, lhs.ty, lhs);
gen("\tbr i1 %v, label %%AndT%d, label %%AndF%d\n", cnd, id, id);
gen("AndT%d: ", id);
let rhs = genexpr(f, b.rhs);
+ gen("\tstore %t %v, %t %v\n", ex.ty, rhs, tmpvar.ty, tmpvar);
gen("\tbr label %%AndF%d\n", cnd, id, id);
gen("AndF%d: ", id);
- gen("\t%v = phi %t [ %v, %%AndEntry%d ], [ %v, %%AndT%d ]\n", res, ex.ty, lhs, id, rhs, id);
+ gen("\t%v = load %t, %t %v\n", res, ex.ty, tmpvar.ty, tmpvar);
return res;
case else
assert(#f, "binop? %c", b.op);
}
+ case Cond cond;
+ static condid int = {};
+ let id = condid++;
+ let lhs = genexpr(f, cond.test);
+ let cnd = mktmp(ty_i1);
+ let tmpvar = mktmp(mkptrtype(ex.ty));
+ let res = mktmp(ex.ty);
+ gen("\t%v = alloca %t\n", tmpvar, ex.ty);
+ gen("\t%v = icmp ne %t %v, 0\n", cnd, lhs.ty, lhs);
+ gen("\tbr i1 %v, label %%CondT%d, label %%CondF%d\n", cnd, id, id);
+ gen("CondT%d: ", id);
+ let t = convert(f, ex.ty, cond.t);
+ gen("\tstore %t %v, %t %v\n", ex.ty, t, tmpvar.ty, tmpvar);
+ gen("\tbr label %%CondFin%d\n", cnd, id, id);
+ gen("CondF%d: ", id);
+ let f = convert(f, ex.ty, cond.f);
+ gen("\tstore %t %v, %t %v\n", ex.ty, f, tmpvar.ty, tmpvar);
+ gen("\tbr label %%CondFin%d\n", cnd, id, id);
+ gen("CondFin%d: ", id);
+ gen("\t%v = load %t, %t %v\n", res, ex.ty, tmpvar.ty, tmpvar);
+ return res;
+
case UnOp un;
switch un.op {
case :neg;