Forth in Lisp


Recently on my blog I wrote about how I implemented Forth in Lisp. I did it because I needed a user accessible scripting language and I decided Forth had the simplist syntax of anything ever. Its also pretty easy to do.

In the blog entry in about 128 loc I produce a working Forth implementation and demonstrate it by having it compile a recursive factorial function and then evaluate 10 factorial. I hope this is interesting to some of you because it's Lisp, and it implements a programming language.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

possibly related

i always wanted to experiment with staapl.


It looks like Staapl is like a Forth compiler. (code> 1 2 +) in staapl outputs ASM code to perform the operation. In mine no ASM would ever be generated, instead I would push into the memory space a literal function call, then a 1, then a second literal function call, then a two, and then an add instruction.

Staapl seems to me that it allows forth like code to be played with, and then compiled for a user-specified register machine's ASM.

Modules and Toplevel

Staapl consists of two parts that complement each other: a module compiler and an interactive toplevel. The compiler marries the Racket macro system with a Forth-like low level 2-stack language that acts as a machine abstraction. The interactive toplevel is an ad-hoc command interface bolted on top of the compiler and a target machine monitor.

The Racket macro system makes language towers easier to understand by pinning down the meaning of identifiers at compile time, eliminating some "moving parts" and so making code easier to reason about and easier to modularize. The "functional nature" of a 2-stack machine as opposed to a register machine adds simple low-level code composition and so further facilitates modularization.

The complementary interactive toplevel emulates a standalone Forth interpreter, allowing the execution of existing on-target code and the definition of new on-target code by invoking the compiler and uploading machine code while the target is running. The interactive toplevel is there to "break the rules" when you need more direct control over the target hardware. While the "static" and "purely functional" approach are nice for building well-structured programs, the reality of embedded programming is still that hardware issues are related to state and ill-defined behaviour and require interactive trial and error to resolve.

let over lambda

chapter 8 in let over lambda called 'lisp moving fort moving lisp' does implement forth using common lisp. Have you looked at that?

Let Over Lambda

Actually, no I haven't but I've heard of it. I'd be curious to know if/how they differ in implementation.


along the same lines…

A quote from the latter:

There has been much interest in building a Lisp system on top of Forth, especially a Forth engine. A common approach has been to write the Lisp system from scratch, in Forth. We propose an alternate approach based upon the existing Portable Standard Lisp (PSL) system. The PSL compiler emits code for an abstract machine with 15 registers. Typically, the abstract machine code and registers are mapped to target operations and registers/memory locations. In this paper we explore two approaches to bootstrapping Lisp in Forth: (1) create a Forth wordset to emulate the PSL abstract machine, and (2) map PSL's abstract machine operations to Forth primitives.