Monday, June 02, 2025
I've just implemented a Forth system
It started out innocently enough—I just wanted to know how to implement the Forth word DOES>
.
I ended up implementing ANS Forth for the 6809,
as you do.
I've had a fascination with Forth since college. I have a copy of both the first edition and the second edition of Starting Forth. I have a copy of Thinking Forth I also have a copy of Threaded Interpretive Languages with the Robert Tinney cover art. I even wrote my own Forth-like langauge in college, which I used for a class project and a few work-relelated programs.
But the one concept I couldn't figure out how to implement was the Forth word DOES>
.
As a user of Forth,
using DOES>
is pretty easy and one of those things never thought about,
much like closures to a JavaScript programmer.
But implementing it?
That was a problem.
So in April I set out to do that, using the 6809 (because why not?) with the intent of figuring it out. I made a stab with it a few years ago, writing just enough of a Forth implementation in C and got it working. Barely. I wanted to do better.
And boy, did I.
I didn't intend on implementing ANS Forth,
but once I “got” DOES>
done
(and I know the grammar on that doesn't quite work,
but that's Forth for you)
I had enough of a system up that sure—why not finish it?
It's a classical indirect thread coded Forth interpreter. They tend to be the easiest to write and the most compact. They aren't exactly the fastest though. And the 6809 is unique among the 8-bit CPUs in that Forth is a very good match for it. Forth requires two stacks, the 6809 has two stack pointers. There are two index registers, so one can be used as the Forth instruction pointer, and the other one for use. It even has some limited 16-bit arithmatic operations. So it's a good match for Forth.
It just took a bit longer than expected. I ended up implementing 254 Forth words (in Forth, a “word“ is like a function) out of the possible 435—I wanted a Forth independent of any existing operating system, so I skipped implementing a few wordsets (Forth jargon for “module” or “library”). The only routines that need to be provided are a character input routine, a character output routine, and a routine to return back to the operating system. I also didn't implement floating point, as that would take up a considerable amount of space (the IEEE-754 routines for the 6809 Motorola placed into the public domain clock in at 8K and all that gives you is addition, subtraction, multiplcation, division and square roots—and the ANS Forth standard for floating point requires a lot more).
I also tried writing as much of it using ANS Forth standard words as possible, only it turned out to be less than I thought using the restrictions I placed upon myself (mainly—avoid using non-standard Forth words but more on that in a later post).
Then it took a while to get it to pass the test suite—the semantics of some Forth words are a bit tricker than I expected, and some words worked completely differently than how I expected them to work, but again, I'll be going into detail about that later. I also had to debug the test suite as it made some unwarrented assumptions about the Forth environment, mainly case-insensitivity (mine is case-sensitive, which is allowed by the Forth standard) and line length (mine is limited to 80 characters, again, the minimum allowed by the Forth standard). And the occastional outright bug (mostly typos).
Fun times.
Anyway, expect a flurry of posts about implemeting an ANS Forth system.