I just finished an initial release of an interpreter for the befunge programming language, based on the ‘93 spec. The project was quite fun! My goal was to produce a well-designed program with performance that didn’t suck too bad. Here are some highlights:
I found that writing the core functionality of the interpreter took almost no
time, once I settled on the approach I would take. I used a monad transformer
for the first time,
This let me pass around the state of the computation in the
while doing IO actions. This made some potentially-awkward befunge commands
really easy to implement.
Here is an excerpt from the function
execute :: Char -> REPL ()
which reads the befunge character at our position and returns
the code to execute:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
And here is the program state that gets passed in the monad:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
I only use the accessor functions (as opposed to pattern matching) to reach into the state in my code, so it was easy to add another state parameter if I wanted to extend the functionality somewhere.
Finally here is the evaluation loop that ties the core of the interpreter together:
1 2 3 4 5 6 7 8 9
I found the most time-consuming parts of this project were in the design decisions and behaviour tweaks related to holes in the ‘93 spec, and tracking down a few silly bugs that came from wrong assumptions about the spec.
Vital in debugging were the CCBI interpreter as well as the pyfunge interpreter. It’s difficult to debug an interpreter when you don’t whether the befunge code you are testing on is buggy or whether your interpreter is!
One last detail that I am proud of is the test suite that I have integrated into my darcs repo. Darcs automatically runs the befunge-93 portion of the amazing mycology test suite by Matti Niemenmaa on each commit, as well as two smaller test befunge programs from phlamethrower, testing that the interpreter hasn’t changed behavior.
Play With It
UPDATE (9/3/2014) Lost this repo long ago, but it’s up on github now
You can check out the full source for the program here, or get my whole darcs repository with:
$ darcs get --tag=v0.2 http://coder.bsimmons.name/code/Befunge
try out some programs from vsync’s funge stuff here.
There is still a lot that could be done, but I think I’m done with it for now. Thanks for looking!