diff options
author | kdx <kikoodx@paranoici.org> | 2023-06-18 20:57:59 +0200 |
---|---|---|
committer | kdx <kikoodx@paranoici.org> | 2023-06-18 20:57:59 +0200 |
commit | dd513a4fbee3c04f4b0a825198b9fe1e43dda767 (patch) | |
tree | 78dc066d1a358fba9f86c1e9fcc8b3124846282e | |
parent | 8a1646b915c7322daea5a1b74cde60e565121cfe (diff) | |
download | golem-dd513a4fbee3c04f4b0a825198b9fe1e43dda767.tar.gz |
brainfuck interpreter
-rw-r--r-- | samples/brainfuck.golem | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/samples/brainfuck.golem b/samples/brainfuck.golem new file mode 100644 index 0000000..c9e5e95 --- /dev/null +++ b/samples/brainfuck.golem @@ -0,0 +1,86 @@ +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++; + } +} |