diff options
| author | Richard Qin <richard.qin.001@gmail.com> | 2026-09-15 08:16:43 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.001@gmail.com> | 2026-09-15 08:16:43 +0800 |
| commit | 4022e5c95210631e4aceb08eaf9d9071aa5aefc4 (patch) | |
| tree | a5922559836e45fb3459a3d070367912e1035b1a /tests/performance/05_brainfuck-bootstrap.sy | |
| download | rcc-master.tar.gz rcc-master.tar.xz | |
Diffstat (limited to 'tests/performance/05_brainfuck-bootstrap.sy')
| -rw-r--r-- | tests/performance/05_brainfuck-bootstrap.sy | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/tests/performance/05_brainfuck-bootstrap.sy b/tests/performance/05_brainfuck-bootstrap.sy new file mode 100644 index 0000000..47b6aad --- /dev/null +++ b/tests/performance/05_brainfuck-bootstrap.sy @@ -0,0 +1,121 @@ +// Brainfuck Interpreter +// Reads program from stdin, interprets and outputs to stdout. +// +// Main optimization targets: +// jump table, inline variables, etc. + +int program_length = 0; +int program[65536] = {}; +int tape[65536] = {}; +int input[65536] = {}; +int input_length = 0; +int output[65536] = {}; +int output_length = 0; + +int get_bf_char() { + int get = getch(); + while (get != 62 && get != 60 && get != 43 && get != 45 && get != 91 && + get != 93 && get != 46 && get != 44 && get != 35) { + get = getch(); + } + return get; +} + +void read_program() { + int get = get_bf_char(); + while (get != 35) { + program[program_length] = get; + get = get_bf_char(); + program_length = program_length + 1; + } + + // read input + // input starts with an `i` + int verify = getch(); + if (verify != 105) { + return; + } + // and a length + input_length = getint(); + // and a random char + getch(); + int i = 0; + while (i < input_length) { + input[i] = getch(); + i = i + 1; + } +} + +void run_program() { + int ip = 0; + int read_head = 0; + int input_head = 0; + int return_address[512] = {}; + int return_address_top = 0; + output_length = 0; + while (ip < program_length) { + int code = program[ip]; + if (code == 62) { + read_head = read_head + 1; + } else if (code == 60) { + read_head = read_head - 1; + } else if (code == 43) { + tape[read_head] = tape[read_head] + 1; + } else if (code == 45) { + tape[read_head] = tape[read_head] - 1; + } else if (code == 91) { + int val = tape[read_head]; + if (val != 0) { + return_address[return_address_top] = ip; + return_address_top = return_address_top + 1; + } else { + // find the matching ] + int loop = 1; + while (loop > 0) { + ip = ip + 1; + if (program[ip] == 93) { + loop = loop - 1; + } + if (program[ip] == 91) { + loop = loop + 1; + } + } + } + } else if (code == 93) { + int val = tape[read_head]; + if (val == 0) { + return_address_top = return_address_top - 1; + } else { + ip = return_address[return_address_top - 1]; + } + } else if (code == 46) { + output[output_length] = tape[read_head]; + output_length = output_length + 1; + } else if (code == 44) { + if (input_head >= input_length) { + tape[read_head] = 0; + } else { + tape[read_head] = input[input_head]; + input_head = input_head + 1; + } + } + ip = ip + 1; + } +} + +void output_() { + int i = 0; + while (i < output_length) { + putch(output[i]); + i = i + 1; + } +} + +int main() { + read_program(); + starttime(); + run_program(); + stoptime(); + output_(); + return 0; +} |
