Page Numbers: Yes X: 306 Y: 1.0" First Page: 20
Margins: Top: 1.0" Bottom: 1.3"
Heading:
CS-370 (FALL 1982)3-LISP REFERENCE MANUALNovember 3, 1982
————————————
6. Programming Context
————————————
6.a. Processor Top Level
Each reflective level of the processor is assumed to start off running the following procedure:
(DEFINE READ-NORMALISE-PRINT
(LAMBDA SIMPLE [ENV STREAM]
(BLOCK (PROMPT (LEVEL) STREAM)
(MAPLET [[FORM (NORMALISE (READ STREAM) ENV ID*)]]
(PROMPT #= STREAM)
(PRINT FORM STREAM))
(READ-NORMALISE-PRINT ENV STREAM))))
The way this is imagined to work is as follows: the very top processor level (infinitely high up) is invoked by someone (say, God, or some functional equivalent) normalising the expression ‘(READ-NORMALISE-PRINT GLOBAL INPUT-STREAM)’, where INPUT-STREAM designates the primary input channel. When it reads an expression, it is given the input string ‘(READ-NORMALISE-PRINT GLOBAL STREAM)’, which causes the level below it to read an expression, which is in turn given ‘(READ-NORMALISE-PRINT GLOBAL STREAM)’, and so forth, until finally the second reflective level is given ‘(READ-NORMALISE-PRINT GLOBAL STREAM)’. This types out ‘1>’ on the console, and awaits your input.
6.b. Environments
Environments are sequences of two-element sequences, with each sub-sequence consisting of a variable and a binding (both of which are of course expressions). A normal-form environment designator, therefore, is a rail of rails, with each rail consisting of two handles. Variables are looked up starting at the front (i.e. the second element of the first subrail whose first element is the variable is the binding of that variable in that environment). Environments can also share tails: this is implemented by normal-form environment designators sharing tails (this is used heavily in the GLOBAL/ROOT/LOCAL protocols, and so forth). Effecting a side-effect on the standard normal-form environment designator changes what the environment is, which is as it should be. Each level is initialised with the same global environment.
6.c. Control Flow and Processor State
...
The four standard continuations:
C0: Accept the normalised function designator in an application.
C1: Accept the normalised arguments for a SIMPLE application.
C2: Accept the normalised first element in a rail fragment.
C3: Accept the normalised tail of a rail fragment.
6.d. Control Flow in the Reflective Processor
...
(define NORMALISE
(lambda simple [exp env cont]
(cond [(normal exp) (cont exp)]
[(atom exp) (cont (binding exp env))]
[(rail exp) (normalise-rail exp env cont)]
[(pair exp) (reduce (car exp) (cdr exp) env cont)])))
(define REDUCE
(lambda simple [proc args env cont]
(normalise proc env
(lambda simple [proc!]; Continuation C0
(if (reflective proc!)
((de-reflect proc!) args env cont)
(normalise args env
(lambda simple [args!]; Continuation C1
(if (primitive proc!)
(cont ↑(proc! . args!))
(normalise (body proc!)
(bind (pattern proc!) args! (cenv proc!))
cont)))))))))
(define NORMALISE-RAIL
(lambda simple [rail env cont]
(if (empty rail)
(cont (rcons))
(normalise (1st rail) env
(lambda simple [first!]; Continuation C2
(normalise-rail (rest rail) env
(lambda simple [rest!]; Continuation C3
(cont (prep first! rest!)))))))))
———————————————
(define READ-NORMALISE-PRINT
(lambda simple [level env stream]
(block (prompt level)
(map (lambda simple [form!] (reply form! stream))
(normalise (read stream) env id*))
(read-normalise-print level env stream))))