About half a year ago, I wrote a small FORTH interpreter in portable C. As opposed to gforth (GNU Forth), it only depends on the standard C library and it can be built in just seconds. The resulting binary (including the dictionary image) is only 55 kB in size.
Why did I build this? Because other FORTH implementations ether leave out some functionality I considered important (such as vocabularies or floating point numbers) and because gforth required too many dependencies to be built from source. Plus I wanted some FORTH system to run on a stand-alone RP2350-based system that generates DVI video in software and can also access USB peripherals like a mouse, a keyboard and a USB drive.
The FORTH system consists of two parts:
- The virtual machine written in portable C. It interprets byte instructions via a giant switch statement. Some instructions access operating system functions.
- The dictionary image. It contains the functions written in FORTH and the FORTH interpreter itself.
The file kernel.img is provided, a minimal dictionary image that is just capable enough to load more FORTH code to extend itself into a full FORTH system. The dictionary image of the full FORTH system is then written to a file.
Two versions of the FORTH interpreter are compiled:
- bforth can load a dictionary image from a file. It can be used to load kernel.img and extend itself into forth,img
- forth has a dictionary image embedded in its code. It must first be created by bforth and then be converted to a C header file.
This is not as fast as gforth, but reasonably fast for a FORTH implemented in C. All addressing in FORTH is done relative to the base of the dictionary image. Even though it can run on a 64-bit system, the FORTH virtual machine is a 32-bit machine. At the moment, execution addresses are even restricted to 24 bit. 16 MB should be really more than enough for a FORTH system like this.
This FORTH system is known to run under Linux on x86-64, x86-32, arm64 and riscv-64. It should also work on arm32. In its current form, FORTH requires the system to be little-endian. All currently relevant systems are little-endian. If you want to try it out, please get it from https://github.com/lennart-benschop/embeddable-forth
Leave a Reply