diff options
Diffstat (limited to 'examples/lang.zc')
| -rw-r--r-- | examples/lang.zc | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/examples/lang.zc b/examples/lang.zc new file mode 100644 index 0000000..6e992b4 --- /dev/null +++ b/examples/lang.zc @@ -0,0 +1,49 @@ +// growing the language from inside a program, while it compiles + +// x |> f calls f(x). on a stack machine that's just "call": the value is +// already on the stack, under f's address. +immediate fn pipe_op() { next(); add_binop("|>", 1, "c"); return 0; } +pipe_op + +// unless (c) stmt +immediate fn unless() { + let a; + next(); expect(intern("(")); plainuse(expr()); rval(); expect(intern(")")); + emitseq(useq[0], ulen[0]); // not + a = hole(); op(O_JZ); + substmt(); + setlit(a, here); + return 0; +} +// assert (c): the failure message carries the line it was written on +fn assert_fail(int line) { put_s("assertion failed on line "); put_n(line); put_c(10); halt(); return 0; } +immediate fn assert() { + let a, l = tline; + next(); expect(intern("(")); plainuse(expr()); rval(); expect(intern(")")); + emitseq(useq[0], ulen[0]); // not: the jump below skips the failure when it holds + a = hole(); op(O_JZ); + lit(l); callname(intern("assert_fail")); op(O_DROP); + setlit(a, here); + return 0; +} +// times N { body }: the body pasted N times, at compile time +immediate fn times() { + let n, b, i = 0; + next(); n = tv; next(); + b = grab(); + while (i < n) { feed(qdup(b)); i++; } + free(d*b); + return 0; +} + +fn double(x) { return x * 2; } +fn inc(x) { return x + 1; } +fn main() { + put_n(5 |> double |> inc |> double); put_c(10); + unless (1 > 2) put_s("one isn't bigger than two\n"); + times 3 { put_c('*'); } + put_c(10); + assert(double(4) == 8); + assert(inc(1) == 3); + return 0; +} |
