a brainf-ck interpreter
you can find the code for this project on gitlab.
some random computer science class
during some computer science ocaml lab, i had finished my exercises and i was a bit bored and i didn't know what to do. after a while i got an idea: why not try writing a brainfuck interpreter in ocaml ? i wrote one and it even had a tiny visualizer mode. but what is brainfuck, you may ask, and i would reply that it is what i am going to talk to you about now and why i think what revolves around this is so interesting.
brainfuck, an esolang
brainfuck is an esoteric programming language designed by urban müller in 1993 while trying to make the tiniest compiler he could. he managed to write a 240-byte compiler for it.
why is it called an esoteric programming language ? maybe because a code that prints "hello world !" in this language looks like this:
++++++++[>+++++++++++++>++++<<-]>.---.+++++++..+++.>.<++++++++.--------.+++.------.--------.>.+. it's all well and good but how does that work
brainfuck is rather simple in its conception. it operates by reading and writing at a pointer on a right-infinite tape with cells, each containing a number between 0 and 255 (a byte).
brainfuck relies on eight operations to manipulate the data on this tape. a brainfuck program is a succession of these operations, read from left to right.
the eight operations are:
<move the pointer one cell to the left>move the pointer one cell to the right-
+increment the current cell by 1; if the cell value is 255, wrap to 0 -
-decrement the current cell by 1; if the cell value is 0, wrap to 255 .print the current cell value as ascii-
,read one input byte and write it to the current cell -
[jump past the matching `]` if the current cell is zero -
]jump back to the matching `[` if the current cell is nonzero
it is better to rust out than wear out
some months passed and i remembered that ocaml interpreter and wanted to rewrite it in rust. this gave me an opportunity to improve it and add new features.
improving the visualizer
the first thing i did was struggle hard to improve the visualizer. i made it possible to see the memory during execution as well as the operations performed by showing the operation list and highlighting the current operation.
better performance ?
after focusing on the visualizer, i wanted to optimize the interpreter a bit. i didn't really know how to do this but i figured that repeated adjacent operations could be combined into one operation that the computer could perform in one go.
for example this:
++++++++[>+++++++++++++>++++<<-]>.---.+++++++.++++.>.+. could become:
+8[>+13>+4<2-]>.-3.+7.+3.>.+. this is done by extending the brainfuck syntax with digits (0-9). for operations <, >, + and -. if a number (can be multi-digit) follows one of these commands, it specifies how many times the operation should be repeated.
indeed the computer is faster at adding 13 for example than adding 1, 13 times.
multi-tape brainfuck (mtbf)
i also added the ability to have several tapes to write on and move data from one to another.
this is done using the commands : and ;:
:nswitches to the n-th tape-
;nswitches to the n-th tape while copying the current cell
i like to call this extended brainfuck (multi-tape + repeated operations) "multi-tape brainfuck", abbreviated as mtbf.
but val, you said it would be interesting...
here it comes... brainfuck is turing-complete, that means it is theoretically possible to run any program ever written.
in some way, this makes it a virtual machine, and this is an insanely interesting fact.
a virtual machine ?
from a historical perspective, a virtual machine (vm) is a program that simulates a computer. the nintendo ds emulator you have on your computer to play pokemon is a good example of a virtual machine. it simulates the hardware of the nintendo ds to be able to run original ds games.
but you can also make up a virtual machine. this means it is possible to invent new kinds of computers. of course, the vm must have some kind of language to rely on to know what operations to perform.
finding a way to implement the virtual machine in real life using electronics or even something else, like mechanics, means you can now run any program written in the machine language of the vm.
now imagine you have a compiler that takes a regular program written in c, c++ or even rust and compiles it to the machine language of the vm. you can now write any program and run them on the physical implementation of the virtual machine.
this is very powerful because if:
- the vm's specification is easy to understand and quick to implement
- you have a version of the compiler written in the machine language of the vm
then, all the programs written in the input language of the compiler are guaranteed to work in any distant future on the condition that the data associated with the two above elements is not lost.
self-hosted mtbf
all of what is described above can be done with brainfuck as well as mtbf, although it's much easier in mtbf. as the brainfuck specification is rather simple, one could come up with a simple-ish circuit board or mechanical device that emulates brainfuck's behavior.
moreover, making and hand-compiling a c/c++/rust to mtbf compiler would be insanely much harder but feasible.
then, as explained above, it would be possible to run any c/c++/rust/... program on any computer, device, or anything that emulates brainfuck.
and that, to me, is quite amazing.
why the big deal ?
as a programming enthusiast, it is a bit frustrating to know that every program i create is heavily dependent on hardware i don't have a good understanding of and that i would not, in any circumstance, be able to recreate on my own.
this means programs won't really mean anything to people in 50, 100 or 500 years from now because the technology will most likely have evolved a lot and most compilers won't support future architectures.
working with virtual machines means you can develop programs that will always work in the future because the virtual machine you used is simple to understand and quick to implement.
ultimately, this makes programming a durable and lasting activity that produces artifacts that shall be used, even in the farthest future.