Martin Karlsson / prog.re

Notes to self


Make A Lisp (step 2)

Continued from step 1. This is where you add eval capability to the interpreter. Eval is short for evaluate, and what's added is the ability to actually evaluate the code. That is

(+ 1 2)

can be evaluated to

3

But before any evaluating logic is written the concept of an environment is introduced. An environment is basically a look-up table where symbols are mapped to something else. In this step only the first environment is actually implemented and it contains mappings from the symbols

+ - * /

to functions that can take arguments to produce new AST items from those. Environments are also tied to the current scope of the program. At certain points (in PHP basically any time a '{' character is found) a new scope is introduced. In practical terms this means that a new environment is created. But, not to get ahead of ourselves, only the base environment is needed to pass all tests in this step.

In a fit of over-thinking I also introduced function overloading based on argument types and variable number of arguments to functions that are operators in PHP, i.e all four of the ones in my current base environment. I will probably regret this pretty soon, but it's nice to be able to do

(+ 1 2 3 4 5)

instead of

(+ 1 (+ 2 (+ 3 (+ 4 5))))

Anyway, apart from over-thinking the function mapping, this step was way easier than the previous. The only hiccup was that I had sort of cheated with the implementation of the map type (a list surrounded by {} in MAL where every odd item, first, third and so on, is a key and the even items are values). I had kept it as a list with different delimiters, but in this step, to get the tests to pass, I had to actually make it a map. Otherwise the eval would grab the first thing in the "list", a key obviously, and try to find a function for that key and use the rest of the items in the "list" as arguments.


Get in touch: martin [at] prog.re