# Brainfuck2Scheme A simple compiler from Brainfuck to R5RS. The compiler will output a Scheme list that is a lambda with two arguments: * `data`: The data vector. * `dptr`: The initial data pointer. To turn the list into an executable Scheme function, just give it to `eval`. ## How It Works Brainfuck is a very simple Harvard architecture computer. The data is stored as a vector `data` and the data pointer is an integer `dptr`. The big idea is that all the code is compiled to a big lambda form, but there are some wrinkles due to jumps. Data access brainfuck instructions are translated like * `+` -> `(vector-set! data dptr (+ 1 (vector-ref data dptr)))` * `-` -> `(vector-set! data dptr (+ -1 (vector-ref data dptr)))` * `>` -> `(set! dptr (+ dptr 1))` * `<` -> `(set! dptr (- dptr 1))` * `.` -> `(display (vector-ref data dptr))` * `,` -> `(vector-set! data dptr (read-char))` Branches are trickier. Basically, all code that will be executed in a block is in a lambda. Given `[code...]`, the `code...` will be compiled to a lambda in a `letrec`, with a conditional at the end that will tail-call the lambda if the current data pointer is not zero. The transformation then goes like `[ CODE ... ] REST ...]` -> (letrec ((between (lambda () (TRANSLATE CODE ...) (if (not (zero? vector-ref data dptr) (between)))))) (if (not (zero? (vector-ref data dptr))) (between))) (TRANSLATE REST ...) where `(TRANSLATE CODE ...)` translates `CODE` to Scheme instructions like above.