Archive for May, 2007

Bootstrapping Lisp – more primitives and new base instruction

Monday, May 28th, 2007

The quote and if functions were fairly easy to add to the high level interpreter.

The compact list syntax made the primitive, yet malleable, quadruple code feel very clumsy. The extremely slow execution speed of the list syntax code doesn’t help either. In an effort to relieve the increased tedium of coding in quadruples, the bcall instruction was added to the base interpreter.

The base boot loader now treats brackets (actually parentheses) as whitespace to make the quadruple code look like it’s being parsed as a list.

Bootstrapping Lisp – faster list reader

Sunday, May 20th, 2007

So now I have three levels of code.

  1. Assembly language, running the base interpreter, and loading quadruple code.
  2. Quadruples, running a higher level interpreter, and loading code in list format.
  3. List (Lisp) syntax, reading itself and printing out the result.

The list parser written in quadruple code (2) uses append and is not too slow. The same code in list syntax (3) was deadly slow. Cleaning up the (3) code using the new expression evaluator reminded me of the use of append. Changing the list syntax (3) parser to use a data stack made it very fast. The dramatic speedup (one order of magnitude) was due to the fact that the parser scans a list of tokens (Lisp literature calls them atoms), and consequently does not perform any searches – the slowdown was all due to the use of append.

The tokenizer and list printer at level (3) are still very slow, due to linear searches over association lists. append is not used for these routines.

Bootstrapping Lisp – expressions and primitive functions

Tuesday, May 8th, 2007

We are finally implementing functions!
Or at least, the primitive ones.

The functions are processed by an expression evaluator. The evaluator was first implemented on the BSETQ instruction. Attempts to update the IFGO to handle functions in the same build yielded broken code that resisted repair. As a result, functions (or equivalently, expressions) were added to IFGO in a separate build.

Because of the way the list reader and writer were written, BSETQ is often bulkier than the code it replaces. However, a lot of the code involves IFGO, and embedding function calls reduces the number of temporaries and instructions needed for test-and-jump. The new IFGO tests are often more complex than a simple EQ of two “variables”, so more than one temporary binding can be eliminated per IFGO.

cdr is the first function verified. It is easily tested by using any printable string. The cdr of a printable string of at least two characters is also a printable string. We can also test the nesting of function calls.

cons is the next function verified. I have generated names for one set of letters, and cons‘ing a letter to the beginning of a printable string also yields a printable string. cons has two arguments, so care must be taken to ensure we preserve data across recursive subroutine calls.

With a template for both one- and two-argument functions, we can figure out the rest, and then test them one by one.

A file filled with text will test readf.

IFGO and WRITEF tests eq.

car and byte are tested in combination with cons and cdr to produce strings.