Make a Lisp [2] Technical SITREP

21 Jan 2019

Today, approximately five weeks after starting this project, I’ve got a Lisp sophisticated enough to read and evaluate functions that are halfway useful. Exhibit A:

(def! factorial (fn* (n) (if (<= n 1) n (* n (factorial (- n 1))))))

Taking this from the left:

To get to this point, I’ve completed steps 0 to 4 in the Make a Lisp guide I’m following:

The source code is on Github.

I admit to cheating slightly by looking at the reference C# implementation (‘C#-Mal’), specifically to understand how to:

Regex are a programming tool for recognising patterns in streams of text; they are powerful but the pattern definitions are extremely hard to write - the definitions for Mal tokens is

[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)

But the rest I figured out on my own based on the instructions in the guide and the C# documentation. In my defence, I’ve also made some improvements. Specifically, JKL can handle:

The biggest changes compared with C#-Mal relate to regex handling and were prompted by the need to handle decimals. I didn’t find the .Net regex documentation particularly enlightening so checked how C#-Mal did things. It turns out that it uses regex in two places, one to perform gross tokenisation of the input lines (the sample pattern listed above), the second to convert selected tokens into Mal symbols, numbers, keywords and numbers. I ended up completely redoing the latter with a more comprehensive version that could handle decimals and detect more errors.

There are still some quite complex steps involved to get JKL to the point where it can self-host, but I have the basic program framework and understand the range of C# mechanisms involved. So, I think I can now avoid looking at the the C#-Mal implementation of the remaining steps.