diff options
| -rw-r--r-- | examples/life.c | 84 | ||||
| -rw-r--r-- | examples/life.cff | 7 | ||||
| -rw-r--r-- | src/llvm.cff | 38 |
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; |