colorful rat Ratfactor.com > Dave's Repos

snobol4th

A Forth written in Snobol4
git clone http://ratfactor.com/repos/snobol4th/snobol4th.git

Files

README.md

Snobol4th

A toy Forth written in Snobol4.

This Forth is implemented as a “pure” interpreter, which simply means it has no compiling or translation step before immediately executing the source code as string data. In other words, it reads the program pretty much exactly like a human would.

Only enough of the Forth language was implemented to be able to execute a “99 Bottles of Beer” lyric-printing program.

I learned Snobol and then wrote a toy Forth

Snobol4 is an unusual language of contrasts. String pattern-matching operations are first-class items in the language and can be combined and composed into expressive string parsing and tokenization. Yet general program control flow is essentially a bunch of labeled GOTOs and branching is based on a hidden layer of “success” and “fail” results of any operation.

Ratfactor’s Judgement of Snobol4

I highly recommend having a small, specific goal when implementing any project as open-ended as a programming language. A lot of my real-world programming often comes down to relatively simple string manipulation, so the 99 bottles program has long been a favorite. It also exercises basic repetition and if/else logic.

99-bottles-of-beer-.net

Have a target for your programming language

The files

forth.sno - The actual program, a minimal Forth implemented in Snobol4.

99.forth - A Forth entry for the 99 bottles…

99output.txt - Your very own souvenir copy of the successful run of 99.forth!

test.forth - The test Forth I actually ran as I built up the word dictionary needed to execute 99.forth.

README.md - That’s me!

log.txt - Abandoned dev log of dubious worth!

Running it

You can interact directly with the interpreter like so:

$ snobol forth.sno
." Hello world!" CR
Hello world!
^D

Run a Forth script by piping it to the interpreter:

$ snobol forth.sno < 99.forth
99 bottles of beer on the wall
99 bottles of beer
Take one down and pass it around.
98 bottles of beer on the wall
...

A bit more about this implementation

I chose to play to Snobol’s strengths by storing and executing even “compiled” words in string form rather than machine code or bytecode for a VM.

Because of the GOTO-like behavior of control flow, writing a Forth in Snobol is both very different and very similar to writing one in assembly language.

It feels like cheating and a bit un-Forthy, but while matching and executing source code directly makes a lot of things easier (and simpler!), it also means you’re going well off the beaten path in terms of how various words are implemented. Some words don’t even make much sense when you’re not actually converting the source into bytecode or working with raw memory.

However, jumping around in strings can actually be quite similar to jumping around in binary code in memory. Again, it’s very similar to how you might “execute” the code yourself if you were doing it on paper.