From: Jürgen Böhm
Subject: Lisp system construction
Date: 
Message-ID: <em6d3r$8mu$01$1@news.t-online.com>
Hi,

  first, thanks to all who answered my "tagged/untagged data" question
below. Now another question came up to me during my work on a new Lisp
system:

   I first started work on this Lisp-system by writing an interpreter,
call it L1I, for this Lisp - call it Lisp1 - in Common Lisp.
    My goal is to write GC routines and a compiler from Lisp1 to a new
machine - call it X1 - in Lisp1 itself. Also the other basic routines
contained in a Lisp system (reader, printer, main loop) shall be written
in Lisp1. Lisp1 shall be a restricted subset of Common Lisp with mostly
identical semantics, but very much restricted in the number of provided
functions.
    A working Lisp1 system with compiler, gc, reader, printer should be
approached step by step. For this I provide first replacements for cons,
car, cdr, rplaca, rplacd, consp, listp, etc. (essentially creators,
accessors, writers and tests for all basic Common Lisp types, which
shall be Lisp1 types too, namely conses, symbols, fixnums, vectors,
characters and strings). These replacements access explicitly an array,
which simulates the memory of a machine, which will be the X1-machine
(see above) when everything is completed.
   Now the route I want to take is:
1)
Write a Lisp1 interpreter in Common Lisp (done)
2)
Write the replacement cons, car, cdr etc (not done yet, but no
conceptional difficulty)
3)
Replace the "normal" cons, car, cdr etc in the Lisp1 interpreter from 1)
by the functions from 2) (this is easy using packages and :shadow)
4) Embed gc routines in the allocators in 2)
5) Now start Lisp1 as a usual Common Lisp function and be able to test
the routines from 2) and the gc routines from 4) for correctness.
6).... go further


   But: Step 4) already seems to be incompatible with the structure of
the Lisp1-interpreter (L1I) as a usual Common-Lisp program. The catch
seems to lie in beeing able to have access to the rootset necessary for
gc. The rootset actually needed would be the Common-Lisp stack itself,
that grows and shrinks during execution of L1I, containing arguments and
local variables of the functions comprising L1I.
   The only way to make gc possible seems to me to write L1I in a way,
that all local variables and arguments are explicitly allocated on a
"stack" that may be modeled by a suitable Common Lisp structure.
   Of course one would not write such an "explicit stack" L1I by hand.
So my idea was, to "compile" L1I from the form it has now by a suitable
"compile-function" into that "explicit form" - call it L1I' . This
should not be difficult (it is essentially compiling from CL to CL with
a compiler written in CL (or is this called "code-walker"?)).
With L1I' the implementation in 4) above is possible as now an explicit
stack is available as rootset.

Do you think, all this is a good path to follow, or is there a better
way to accomplish goal 5) above.

Greetings

J�rgen

-- 
J�rgen B�hm                                            www.aviduratas.de
"At a time when so many scholars in the world are calculating, is it not
desirable that some, who can, dream ?"  R. Thom
From: Ari Johnson
Subject: Re: Lisp system construction
Date: 
Message-ID: <m2k60pi2mx.fsf@nibbler.theari.com>
J�rgen B�hm <······@gmx.net> writes:

>    I first started work on this Lisp-system by writing an interpreter,
> call it L1I, for this Lisp - call it Lisp1 - in Common Lisp.

Calling it anything other than Lisp1 would be a good idea.  There are
enough ambiguities in the Lisp world, and Lisp1 already has a very
well-understood meaning.

>     My goal is to write GC routines and a compiler from Lisp1 to a new
> machine - call it X1 - in Lisp1 itself. Also the other basic routines
> contained in a Lisp system (reader, printer, main loop) shall be written
> in Lisp1. Lisp1 shall be a restricted subset of Common Lisp with mostly
> identical semantics, but very much restricted in the number of provided
> functions.
>     A working Lisp1 system with compiler, gc, reader, printer should be
> approached step by step. For this I provide first replacements for cons,
> car, cdr, rplaca, rplacd, consp, listp, etc. (essentially creators,
> accessors, writers and tests for all basic Common Lisp types, which
> shall be Lisp1 types too, namely conses, symbols, fixnums, vectors,
> characters and strings). These replacements access explicitly an array,
> which simulates the memory of a machine, which will be the X1-machine
> (see above) when everything is completed.
>    Now the route I want to take is:
> 1)
> Write a Lisp1 interpreter in Common Lisp (done)
> 2)
> Write the replacement cons, car, cdr etc (not done yet, but no
> conceptional difficulty)
> 3)
> Replace the "normal" cons, car, cdr etc in the Lisp1 interpreter from 1)
> by the functions from 2) (this is easy using packages and :shadow)
> 4) Embed gc routines in the allocators in 2)
> 5) Now start Lisp1 as a usual Common Lisp function and be able to test
> the routines from 2) and the gc routines from 4) for correctness.
> 6).... go further
>
>
>    But: Step 4) already seems to be incompatible with the structure of
> the Lisp1-interpreter (L1I) as a usual Common-Lisp program. The catch
> seems to lie in beeing able to have access to the rootset necessary for
> gc. The rootset actually needed would be the Common-Lisp stack itself,
> that grows and shrinks during execution of L1I, containing arguments and
> local variables of the functions comprising L1I.
>    The only way to make gc possible seems to me to write L1I in a way,
> that all local variables and arguments are explicitly allocated on a
> "stack" that may be modeled by a suitable Common Lisp structure.

That's not the only, or even best, way.  However, it is likely true
that your list of steps above makes it impossible to do some things
quite the way you want to.

>    Of course one would not write such an "explicit stack" L1I by hand.
> So my idea was, to "compile" L1I from the form it has now by a suitable
> "compile-function" into that "explicit form" - call it L1I' . This
> should not be difficult (it is essentially compiling from CL to CL with
> a compiler written in CL (or is this called "code-walker"?)).
> With L1I' the implementation in 4) above is possible as now an explicit
> stack is available as rootset.
>
> Do you think, all this is a good path to follow, or is there a better
> way to accomplish goal 5) above.

It depends on your end goal.  Since your goal appears to be to run on
the metal, not on top of an existing CL implementation, you might be
far better off writing a runtime to get everything up and running on
the new hardware from a Lisp image, a CL cross-compiler to run on an
existing implementation, and a means to dump an appropriate image for
your new runtime from the existing CL.

Good luck.