a brainfuck interpreter written in go
Brainfuck is a so called esoteric programming language, which has no real real world use, but is rather used to demonstrate how abstract a programming language can be.
The language itself is pretty simple, it only consists of 8 commands: .,<>+-[]
.
When running Brainfuck code, you basically just go through and mutate an array of data cells. The program is always pointing at a certain data cell.
0 0 0 0 0 0 0 0
^^
Selected Cell
<>
Using the <
and >
operators, you can switch the selected cell.
Executing the >
command:
0 0 0 0 0 0 0 0
^^
Selected Cell
+-
So now we can switch between the cells, that's cool, but what else?
We can increase or decrease the value of the cell by using the +
or -
command.
Executing the +
command:
0 1 0 0 0 0 0 0
^^
Selected Cell
.,
Now we want to print our data to the terminal via using the .
or read from the user input via using ,
.
So, .
outputs the current cell in ASCII representation, and ,
stores the ASCII code of the inputted data in the currently selected cell.
[]
We've almost got everything to be turing complete, the only thing missing is the loop.
The [
indicates the beginning of a loop, and ]
indicates the end. The program loops, until the currently selected cell equals 0
.
Code:
>++++++++[<+++++++++>-]<.>++++[<+++++++>-]<+.+++++++..+++.>>++++++[<+++++++>-]<+
+.------------.>++++++[<+++++++++>-]<+.<.+++.------.--------.>>>++++[<++++++++>-
]<+.
Output:
Hello, World!
As I know some basic concepts of implementing a programming language (even though I never did implement one), I thought that it would be a short and fun project to implement a Brainfuck interpreter, as this is a common exercise, due to the simple syntax and logic.
For my implementation, I used nothing but the raw go programming language.
I tried to logically split the project into seperate layers, like it is done with bigger lanugages.
In the first layer, the plain text/string is converted to an array of instructions, that do not yet hold any functionality, but are rather just symbols for the interpreter to get along easier with the instructions.
In the second layer, the blocks are built. You may ask yourself now "what are blocks?".
In the definition for this project, a block is a set of instructions, that stands for itself and contains all instructions which are to be executed in it. A block cannot look outside of it's own scope, so it is isolated from it's surroundings, and therefore easily executable.
In the final layer, the previously built blocks are now being executed. There is a statically declared byte array, in which the entire cell-selection and storage takes place.