to 0 — Data pointer: Points to cell — Code: The program that's executed by the machine — Instruction pointer: Points to the next instruction — Input and output streams: STDIN and STDOUT — CPU: Executes the code
by 1 — < - Decrement the data pointer by 1 — + - Increment the value in the current cell — - - Decrement the value in the current cell — . - Print current cell — , - Read a character to current cell — [ - If the current cell contains a zero, jump to matching ] — ] - If the current cell does not contain a zero, jump to matching [
by 5" instead of "increase" 5 times? — ... we had an instruction that said "go to this matching bracket if current memory cell is empty"? Spoiler: we'd be faster!
{ current := c.code[c.position] switch current { case '+': c.CompileFoldableInstruction('+', Plus) case '-': c.CompileFoldableInstruction('-', Minus) case '<': c.CompileFoldableInstruction('<', Left) case '>': c.CompileFoldableInstruction('>', Right) case '.': c.CompileFoldableInstruction('.', PutChar) case ',': c.CompileFoldableInstruction(',', ReadChar) } c.position++ } return c.instructions }
will be 0 -- a placeholder value — "]" — emit JumpIfNotZero with correct argument — change JumpIfZero argument to correct position How do we keep track of JumpIfZero instructions? Solution to problem in solution: with a stack! Stack, the data structure. First in, last out.
// Pop position of last JumpIfZero ("[") instruction off stack openInstruction := loopStack[len(loopStack)-1] loopStack = loopStack[:len(loopStack)-1] // Emit the new JumpIfNotZero ("]") instruction, // with correct position as argument closeInstructionPos := c.EmitWithArg(JumpIfNotZero, openInstruction) // Patch the old JumpIfZero ("[") instruction with new position c.instructions[openInstruction].Argument = closeInstructionPos // [...] }
Hello, JIT World: The Joy Of Simple JITs: http:// blog.reverberate.org/2012/12/hello-jit-world-joy-of-simple-jits.html — interpreter, compiler, jit: https://nickdesaulniers.github.io/blog/ 2015/05/25/interpreter-compiler-jit/ — a optimized brainfuck compiler written in sed: https://github.com/ stedolan/bf.sed — the original Brainfuck distribution: https://gist.github.com/ rdebath/0ca09ec0fdcf3f82478f — there's much, much more