A collection of brainfuck interpreters written in C, Ruby and Python
I have tried to keep the basic algorithm same in all three languages which I'll describe here -
-
The filename has to be supplied as an argument. We open the file in the program, and pass it to the function filter_code This function filters the code and remove any character that's not one of the 8 instructions.
-
We take the clean code and pass it to the function loopmap. This function creates a map of [ and ]'s. (We talk about it later).
-
We take the clean code and pass it to a function called evaluate. This function reads the code and evaluates it.
#Usage python brainfuck.py filename
ruby brainfuck.rb filename
gcc -o brainfuck brainfuck.c
./brainfuck filename
#Important variable names:
- memcells - The memory cells. At the start of the program we initialize it as 30000 zeroes.
- memptr - The memory pointer. This variable points to the memory cells.
- map_loops - The map of the [ and ]'s
#How we handle instructions:
-
> We increase memptr by 1 so that it points to the next cell. If it tries to point outside memory cells, we exit showing an error
-
< We decrease memptr by 1 so that it points to the previous cell. If it tries to point before starting of memory cells, we exit showing an error
-
+ We increase the current pointed value by 1. If it gets more than 255, we wrap it up.
-
- We decrease the current pointed value by 1. if it gets less than 0, we wrap it up.
-
. We print the character of current pointed cell.
-
, We take one character input and put its ASCII value in current pointed cell.
Handling [ and ] is a bit tricky. The rule is " When we encounter a [ we check if the current pointed value is 0 or not. If not, then go on normally. If 0 then jump to the corresponding balancing ]. And when we encounter a ], we go back to its corresponding [" To achieve this, inside loopmap we create a map of the indices of [ and ]'s
First we create a stack. If we encounter a [, we push its index into the stack. When we encounter a ], we pop the stack. this popped value must be its balancing [. So, we map the popped value to the index of ].
Also, if we encounter a ], but the stack is empty, it means that there are more ] than [. We exit showing an error.
And after mapping, if the stack is still empty, it means that there are more [ than ]. we exit showing an error.