With the ability to create GC-safe code, we start to implement what we really want.
Once again, I started with a print routine. I recreated, somewhat, the PRINTD subroutine using the new symbolic interpreter code. Then I modified it to accept a different association list of print names. After that, I modified it to create Lisp syntax which is lighter weight than the fully dotted S-expression of PRINTD.
Because there is no arithmetic and no access to address values, anonymous atoms are simply printed as “?”.
WRITEF closes its file when it’s done. However, the Windows CONOUT$ file allows piecemeal I/O to a console display, so the basic algorithm for the new routine, PRINTB, did not change. There is one slight drawback – the CONOUT$ text cannot be redirected to a file from the command line. However, it is possible to copy text from the Command Prompt window.
Of course, I want a corresponding read routine for entering data in list form.
The primary motivation for starting with an imperative Lisp is the parsing of the input. I have written one parser in functional style without global variables. It built the tree from an in-memory string text, and it was very tedious. The symbol table, input source code, parse stack, and the generated partial trees had to all be passed as arguments at each step.
All other parsers I have written (including the one I wrote for this bootstrap) were basically standard stream-oriented parsers that use imperative, sequential code.
The list input routine is in three phases: the first two phases are almost the same as the first two phases of the boot loader. The third phase takes the generated token list and performs a basic recursive descent parse on the list. The boot loader does not recognize a comma as white space, and it does not treat the brackets (parentheses) and period (dot) as single character tokens. The list input routine recognizes these extra nuances in the first phase.
The new list I/O routines are called READB and PRINTB, for bracketed expressions. The routines are asymmetric – the PRINTB routine will not write to a file. The association list for getting the print name of an atom is called NLIST, and the inverse list for selecting an atom from a print name is called SYMTAB.