aboutsummaryrefslogtreecommitdiff
path: root/docs/history/15-o3/code/examples/bf.zc
blob: 384025acd48f6cccea553619ef0109908e4e4a12 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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;
}