diff options
Diffstat (limited to 'docs/history/17-o3-boundaries/code/examples/bf.zc')
| -rw-r--r-- | docs/history/17-o3-boundaries/code/examples/bf.zc | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/docs/history/17-o3-boundaries/code/examples/bf.zc b/docs/history/17-o3-boundaries/code/examples/bf.zc new file mode 100644 index 0000000..384025a --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/bf.zc @@ -0,0 +1,50 @@ +// a brainfuck compiler. it turns a brainfuck program into zc source, hands +// that to the compiler that's sitting in memory, and runs the result, which on +// arm64 means native code. runs of + - < > fold into one statement each. +// give it a program after a backtick, or it runs the hello world below. +let out[30000], n, depth; +fn emit(s) { let i = 0; while (s[i]) { out[n] = s[i]; n++; i++; } return 0; } +fn emitn(int v) { if (v >= 10) emitn(v / 10); out[n] = '0' + v % 10; n++; return 0; } +// how many times does c repeat from s[i] +int run(s, int i, int c) { int k = 0; while (s[i + k] == c) k++; return k; } + +fn translate(s) +{ + int i = 0, k; + n = 0; depth = 0; + emit("let t[30000], p = 0;\n"); + while (s[i]) { + switch (s[i]) { + case '+', '-': + k = run(s, i, s[i]); + emit("t[p] = (t[p] "); emit(s[i] == '+' ? "+ " : "- "); emitn(k); emit(") & 255;\n"); + i = i + k; continue; + case '>', '<': + k = run(s, i, s[i]); + emit("p "); emit(s[i] == '>' ? "+= " : "-= "); emitn(k); emit(";\n"); + i = i + k; continue; + case '[': emit("while (t[p]) {\n"); depth++; + case ']': emit("}\n"); depth--; + case '.': emit("putc(t[p]);\n"); + case ',': emit("t[p] = eof() ? 0 : getc() & 255;\n"); + } + i++; + } + emit("return 0;\n"); + out[n] = 0; + return depth; +} +let hello = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."; +let prog[20000]; +fn main() +{ + let src = hello, k = 0, lines = 0, i = 0; + while (!eof() && k < 19999) { let c = getc(); if (c != 10) { prog[k] = c; k++; } } + prog[k] = 0; + if (k) src = prog; + if (translate(src)) { puts("unbalanced brackets\n"); return 1; } + while (out[i]) { if (out[i] == 10) lines++; i++; } + puts("compiled to "); putn(lines); puts(" lines of zc, running it:\n"); + evals(out); + return 0; +} |
