next up previous contents
Next: Creating LISP with Compiler Up: Compilation Previous: General

Bootstrapping LISP

``Bootstraping LISP'' means ``Creating a pure STD-LISP interpreter from scratch''. Here is how to do it:

  1. Put all the files with extension ".l'' into the same directory. Put also the C programs cr1.c cr2.c crc.c cri.c size.c crfile.h into the same directory.

    Each of these C programs will create a part of the C source, those which will later be compiled by a C compiler and presumably will be linked to get the actual executable program.

    cr1
    Will create lisp1.c the part of the LISP system that contains the static declarations.
    cr2
    Will create lisp2.c. lisp2.c is the source of all the LISP system functions, the memory manager, the garbage collector, the I/O routines etc. Unless these definitions are not changed you do not have to run cr2 more than once even if you later perform a LISP tex2html_wrap_inline1791 C compilation of any LISP program. (Please note that this is not so for lisp1.c when you later perform a LISP code compilation than cr1 has to be fired again to reproduce lisp1.c.
    crc
    Actually this program and the below described program will only be used if you will compile a LISP program that you have written. Details will be explained in the section entitled ``Compiling a LISP code''. For the time being just know that this program will attack the output of the LISP tex2html_wrap_inline1791 C compiler and produce a true C source that will be C compilable.
    cri
    Just as crc this program is also used only if a user written LISP code is compiled. It produces a LISP initialization file, in which the non-compilable, user defined LISP expressions are stored. (e.g. quoted lists, strings, atom names).

  2. Change the directory information in the crfile.h file.

    We hear you groaning, but this was necessary, again, to keep true portability, since systems with different operating system have different directory and file access strings. (The trivial example is UNIX versus DOS, one has a slash, the other has a backslash for directories)

  3. If necessary edit the file flags.lIn this file you have various compiler flags for the C compilation. They are explained below:
    TRACEABLE
    If you perform a traceable and/or redefinable code generation (see the relevant section on this topic) for user defined functions, this C flag if zero, tells the C compiler to omit the traceability or redefinability. So, the value of this flag is only important if you perform a LISP tex2html_wrap_inline1791 C compilation.
    DSTACK
    Of course any LISP has to have a stack, that is for sure. The DSTACK C flag stands for `Dynamic-STACK' depending on which the stack is created in the static data area or alternatively allocated at run time as a dynamic memory.
    BITF
    If this flag is non-zero then the code generated will make use of the bit-sub field concept of C. If the flag is set to zero no such code will be generated.

    The bit fields come into account in the tag of a dotted pair, where various informations have to be hold about that dotted pair (e.g. one bit is for garbage collection marking). It is cute and elegant to use in this case bit-fields, but unfortunately some compilers generate a terrible code for bit-field accesses. (e.g. some of them perform a number of shift right operations to get the desired bit to the least significant bit position and then test it, which is awful!). But another alternative is to use just a byte and mask the bits of it. Then setting will correspond to a bitwise OR, and the testing will correspond to bitwise AND operation among the tested byte containing the tested bit and the selection mask byte.

    TURBOC
    If you are using Borland's Turbo C compiler this file will serve for better code generation.
    IBMPC
    If you are working on an IBM-PC or compatible, then the higher ascii codes are set in a specific manner, if this flag is non-zero the generated C code of the LISP interpreter will make use of these ascii codes.

    Furthermore the IBM-PC is using the 80x86 tex2html_wrap_inline1902 P-chip which allows pointers to sit at addresses that are not zero (modulo 4). The code makes use of this (non-portable) feature if the flag IBMPC is set to 1. If you don't have an 80x86 or if you get errors like (bus-error, segmentation fault) turn this flag to zero.

  4. Compile all the C files, that you have copied.
  5. Execute the size program you have just compiled. This program will propose a value for the constant PAGESIZEThat constant lives in the file types.lSet in this file #define PAGESIZE to an integer multiple of the proposed value.

    data structures may have different sizes on different C compilers, because of the underlying hardware. Therefore it is necessary to determine how your compiler acts. We need this information because this LISP implementation does not simply use malloc or calloc when it has to create a LISP data object, for further details see the chapter on ``The Dynamic Structure''.

  6. Execute cr1 and cr2 in order to generate lisp1.c \ and lisp2.c respectively.
  7. Compile lisp1.c and lisp2.c with the C compiler.
  8. Link them, with the appropriate libraries in order to obtain an executable program which is your STD-LISP interpreter.

    what the libraries will be is something system dependent, so since you got your hands on a C compiler, we have to assume that you are fully capable of creating an executable code after a C compilation.


next up previous contents
Next: Creating LISP with Compiler Up: Compilation Previous: General

Gokturk UCOLUK
Fri Nov 1 21:52:13 EET 1996