Brainfuck part 2: an interpreter in JavaScript
This article is part of a series on brainfuck, a weird programming language:
- Brainfuck part 1: what is it?
- Brainfuck part 2: an interpreter in JavaScript
- Brainfuck part 3: a brainfuck → JavaScript transpiler
Last week, I briefly explained what was brainfuck and gave some examples. It’s time to execute those examples and we’re gonna write the interpreter ourselves!
Basics
The interpreter will be a simple function, taking the brainfuck code as first parameter and the input as second parameter.
1 | var bf = function(code, input){ |
We need some place to store the cells: an array is perfect for that.
We also needs pointers. One for the memory, one for the code and one
for the input. With these, we always know what’s the current cell,
what’s the current instruction and what’s the current input character.
I also added the out
variable. This is the output string, it’s what
the interpreter will return at the end.
1 | var bf = function(code, input){ |
Then, we read the code character by character and interpret the instructions.
1 | while(code_ptr !== code.length){ |
Let’s interpret
>
move the data pointer forward<
move the data pointer backward+
increments (+1) the current cell-
decrements (-1) the current cell
Cases >
and <
are obvious (mem_ptr++/--;
). +
and -
are simple
too. Since the memory isn’t initialized, we can’t just do mem[mem_ptr]++/--;
.
Instead, we ensure the cell is set to zero: mem[mem_ptr] = (mem[mem_ptr] || 0) +/- 1;
1 | case '>': |
.
outputs the current cell as an ASCII character,
reads one character from the input and writes it in the current cell
.
and ,
are not much complex. .
converts the cell value to the
corresponding character (ascii) and outputs it. The cell may be empty,
we use 0 as the default value.
Reading from the input is as easy. The only thing not to forget is to
increment the input pointer.
1 | case '.': |
[
makes the program jump to the instruction after the matching]
if the current cell’s value is 0.]
makes the program jump to the instruction after the matching[
if the current cell’s value is not 0.
[
and ]
are a bit trickier since we need to find the matching bracket.
Let’s pretend we have a matching()
function that return the code position
of the matching bracket.
1 | case '[': |
Now, we need to stop pretending and write that matching()
function.
Read the comments:
1 | var matching = function(bracket){ // bracket is the character to find |
Before putting everything together, let’s add a little thing (brainfuck’s memory is supposed to be 30000 cells wide).
1 | if(mem_ptr < 0 || mem_ptr >= 30000){ |
Complete interpreter
1 | var bf = function(code, input){ |
Examples
1 |
|
The bf()
function is included in this page so you can open your
javascript console and test it yourself!
Next time
In the next (and last) post of this series, I will take a different
approach. Instead of interpreting the code, I will convert it to
JavaScript code and eval()
it.
This article is part of a series on brainfuck, a weird programming language: