define EOF = 0xffff; define BUF_SIZE = 0x4000; define MEM_SIZE = 0x8000; // has to be 2^x define MEM_MAX_PTR = MEM_SIZE - 1; global buf[BUF_SIZE] = 0; global pc = 0; global mem[MEM_SIZE] = 0; global mem_ptr = 0; main() { if drain() |> ensure_match return error("[] don't match"); loop { if ([buf + pc] == 0) return; getop() |> exec; } } drain() { local p = buf; loop { red p; if ([p] == EOF | [p] == '\n') { [p] = 0; return buf; } p++; } } ensure_match(p) { local matching = 0; loop { if ([p] == 0) return matching; if ([p] == ']' & matching == 0) return 1; matching = matching + ([p] == '[') - ([p] == ']'); p++; } } error(msg) { loop { if ([msg] == 0) { wrt '\n'; return; } wrt [msg++]; } } getop() => [buf + pc++]; exec(op) if (op == '<') mem_ptr = (mem_ptr - 1) & MEM_MAX_PTR; else if (op == '>') mem_ptr = (mem_ptr + 1) & MEM_MAX_PTR; else if (op == '+') [mem + mem_ptr] = ([mem + mem_ptr] + 1) & 0xff; else if (op == '-') [mem + mem_ptr] = ([mem + mem_ptr] - 1) & 0xff; else if (op == '.') wrt [mem + mem_ptr]; else if (op == ',') red mem + mem_ptr; else if (op == '[') => zjmpfwd(); else if (op == ']') => nzjmpbckwd(); zjmpfwd() { local matching = 1; if ([mem + mem_ptr] == 0) loop { matching = matching + ([buf + pc] == '[') - ([buf + pc] == ']'); pc++; if (matching == 0) return; } } nzjmpbckwd() { local matching = 0; if ([mem + mem_ptr] != 0) loop { pc--; matching = matching + ([buf + pc] == ']') - ([buf + pc] == '['); if (matching == 0) return pc++; } }