I just discovered your project today, and was quite intrigued by what you've
I am particularly interested in "bare metal" implementations of Lisp &
Lisp-like languages; part of my interest is analogous to the MirageOS
"unikernal" concept; part of my interest is in gaining access to HW--e.g., page
tables for more efficient implementation of large arrays.
I've worked on tiny languages before -- e.g., "Comfy" for the 8-bit
My approach is to write a machine-language compiler in a subset of Common Lisp,
and then simply port that subset to the bare metal.
However, I don't want to do too much work, so I'd like to abstract away many of
the machine language issues.
I was hoping to come up with a machine of 3 sizes: 16-bit, 32-bit or 64-bit
"words"; this would enable a "small", "medium" and "large" versions of this
The machine would have some number of "registers" of the standard word size,
some of which (I hope) would map directly into machine registers.
Most operations would operate on words, so as not to have to worry about byte
The byte stuff would likely have to be done as an escape mechanism to
incorporate raw bits into the instruction stream.
I don't want to have to re-invent C, relocatable binaries, etc., so the idea is
to completely dispense with assembler, C, loaders, etc., by compiling directly
into memory (a la the original 1960's Lisps).
So long as the compiler is *one-pass*, and doesn't do any complex
optimizations, it can run at *line speed* -- i.e., it can compile at the same
rate that it can read Lisp S-expressions from a file system. Hence, there is
very little advantage in ever storing compiled code in a file system.
(Perhaps another way to look at this is as a 'just-in-time' compiler, where
'just-in-time' is when the code is loaded; since the compilation process could
be functional, one could conceivably *page* these compilations in/out of memory
a la Maclisp/Macsyma's load-on-demand functions.)
The low-level portion of this Lisp would be *stackless*, and would look more
like an Actor machine which is passed arguments + a "continuation"
A stackless machine would enable painless multiprocessing, whereby a context
switch can occur at every function call. Since iterations are just
tail-recursions, context switches can occur very often and very quickly.
An initial experiment is a tiny *functional* Lisp based on ref counts. This
eliminates the need for a traditional GC, and can potentially provide better
BTW, here is the factorial function written in this functional Lisp:
(defun fact1(f n)
(if (zerop n) 1
(* n (funcall f f (1- n)))))
(defun factorial (n)
(funcall #'fact1 #'fact1 n))
(Of course, to compile this into an Actorish execution model, you need to
compile into continuation-passing form.)
Since you all have been looking at tiny Lisps, do you have any recommendations
of tiny Lisps to look at & play with?
Thanks very much for any info & help.
Santa Barbara, CA