diff options
Diffstat (limited to 'docs/history/13-gap-fixes/code/tests/meta.zc')
| -rw-r--r-- | docs/history/13-gap-fixes/code/tests/meta.zc | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/docs/history/13-gap-fixes/code/tests/meta.zc b/docs/history/13-gap-fixes/code/tests/meta.zc new file mode 100644 index 0000000..bc89454 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/meta.zc @@ -0,0 +1,46 @@ +fn ipow(a, b) { let r = 1; while (b > 0) { r *= a; b--; } return r; } +// a parse word that adds an operator to the compiler's tables +immediate fn pow_op() { next(); add_binop("**", 11, "ipow c"); return 0; } +pow_op + +// unless (cond) stmt: a parse word that emits code itself +immediate fn unless() +{ + let a; + next(); + expect(intern("(")); rval(); plainuse(expr()); rval(); expect(intern(")")); + emitseq(useq[0], ulen[0]); // not + a = hole(); op(O_JZ); // skip the body when the condition was true + substmt(); + setlit(a, here); + return 0; +} +// repeat N { body }: a macro, built from token lists +immediate fn repeat() +{ + let n, body, i = 0; + next(); n = tv; next(); + body = grab(); + while (i < n) { feed(qdup(body)); i++; } + free(d*body); + return 0; +} +fn main() +{ + putn(2 ** 10); putc(' '); putn(3 + 2 ** 3 * 2); putc(10); + unless (1 > 2) puts("unless ok\n"); + unless (2 > 1) puts("wrong\n"); + repeat 3 { putc('r'); } + putc(10); + let q = quote { putn(40 + 2); putc(10); return 7; }; + putn(q[0]); putc(' '); + putn(eval(q)); putc(10); + let f = compile(q); + putn(f()); putc(10); + free(d*q); + let defs = quote { fn sq(x) { return x * x; } }; + load(defs); + free(d*defs); + putn(evals("return sq(12);")); putc(10); + return 0; +} |
