From a19a4ba299881b3bd154d3c01e33faf0184d4b7b Mon Sep 17 00:00:00 2001 From: boons <57451966+boonsboos@users.noreply.github.com> Date: Wed, 26 Oct 2022 18:31:15 +0200 Subject: [PATCH] examples: add a tiny brainvuck interpreter (#16213) --- examples/brainvuck.v | 66 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 examples/brainvuck.v diff --git a/examples/brainvuck.v b/examples/brainvuck.v new file mode 100644 index 0000000000..81ebd726e8 --- /dev/null +++ b/examples/brainvuck.v @@ -0,0 +1,66 @@ +import os + +fn main() { + if os.args.len < 2 { + eprintln('you need to supply a brainfuck program as a string argument') + exit(1) // exit with non-zero exit code if there is no program to run + } + program := os.args[1] // our program is fed in as a string + + mut memory := []u8{len: 256} // we have 256 bytes of memory + mut address := u8(0) // as well as an 8-bit address register + + mut stack := []int{} // our stack does not need a maximum length + + mut program_counter := 0 // program counter + + // interpreter starts here + for program_counter < program.len { + // we look at what the current character our program counter is seeing + match program[program_counter] { + `>` { + address++ // increment the address + } + `<` { + address-- // decrement the address + } + `+` { + memory[address]++ // increment the value at the address + } + `-` { + memory[address]-- // decrement the value at the address + } + `.` { + print(memory[address].ascii_str()) // print the value at the address + } + `,` { + input := os.input_opt('') or { '' } // read value and account for errors + memory[address] = input[0] // this is so we can ignore newlines + // because strings are 0-terminated, it also gives us a default value for free! + } + `[` { + stack << program_counter // add loop start address to the call stack + } + `]` { + if memory[address] != 0 { + // set the program counter to the last loop start + // so it jumps back and loops again + program_counter = stack[stack.len - 1] + } else { + // otherwise remove the address from the stack and continue + stack.pop() + } + } + else { + // the interpreter should ignore characters that are not part of the language + } + } + // increment the program counter to go to the next instruction + program_counter++ + // back to line 20! + } + + // print the state of the interpreter at the end + println('Address: $address') + println('Memory: $memory') +}