Page:AIM-453.djvu/57

There was a problem when proofreading this page.

Steele and Sussman

55

The Art of the Interpreter


{EVALQUOTE} Page 14

The top level of LISP 1 [LISP 1M] and LISP 1.5 [LISP 1.5M] actually was not at all like the one presented here. Rather than reading one S-expression and giving it to EVAL, it read two S-expressions and gave them to APPLY. Such a top level is called an EVALQUOTE top level (see Figure N2).

(DEFINE (DRIVER-LOOP-1 PROCEDURES FORM1)
        (DRIVER-LOOP-2 PROCEDURES FORM1 (READ)))

(DEFINE (DRIVER-LOOP-2 PROCEDURES FORM1 FORM2)
        (COND ((EQ FORM1 'DEFINE)
               (DRIVER-LOOP (BIND (LIST (CAAR FORM2))
                                  (LIST (LIST '&PROCEDURE (CDAR FORM2) (CADR FORM2)))
                                  PROCEDURES)
                            (PRINT (CAAR FORM2))))
              (T (DRIVER-LOOP PROCEDURES
                              (PRINT (APPLY FORM1 FORM2 PROCEDURES))))))

For DRIVER-LOOP-1 see Figure 1.
For APPLY see Figure 2.
For BIND see Figure 3.

Figure N2
Driver Loop for an EVALQUOTE Top Level

This driver loop is somewhat nicer than the one in Figure 1, because the one in Figure 1 had an essentially useless COND clause. The case of typing an atom was not useful, because there were no top-1evel values for variables. Once we introduce procedural objects, this is no longer true. But EVALQUOTE requires an inconsistency of notation: at the top level one must write CAR((A . B)), whereas in the middle of a program one would write (CAR '(A . B)).

The notion of EVALQUOTE also has some theoretical motivation, if one thinks of LISP as a universal machine akin to a universal Turing machine. In this model one takes a description of a machine to be simulated and a description of its input data, and gives them to the universal machine to process. In LISP, the universal machine is APPLY.