3.14 The Interpreter

APPLY(FN:{id,function}, ARGS:any-list):any eval, spread
 
APPLY returns the value of FN with actual parameters ARGS. The actual parameters in ARGS are already in the form required for binding to the formal parameters of FN. Implementation specific portions described in English are enclosed in boxes.
EXPR PROCEDURE APPLY(FN, ARGS);

BEGIN SCALAR DEFN;

   IF CODEP FN THEN RETURN

  Spread the actual parameters in ARGS following the conventions: for calling functions, transfer to the entry point of the function, and return the value returned by the function. ;

IF IDP FN THEN RETURN

IF NULL(DEFN := GETD FN) THEN

ERROR(000, LIST(FN, "is an undefined function"))

ELSE IF CAR DEFN EQ ’EXPR THEN

APPLY(CDR DEFN, ARGS)

ELSE ERROR(000,

LIST(FN, "cannot be evaluated by APPLY"));

IF OR(ATOM FN, NOT(CAR FN EQ ’LAMBDA)) THEN

ERROR(000,

LIST(FN, "cannot be evaluated by APPLY"));

RETURN

Bind the actual parameters in ARGS to the formal parameters of the lambda expression. If the two lists are not of equal length then ERROR(000, "Number of parameters do not match"); The value returned is EVAL CADDR FN.

END;

EVAL(U:any):any eval, spread
 
The value of the expression U is computed. Error numbers are arbitrary. Portions of EVAL involving machine specific coding are expressed in English enclosed in boxes.
EXPR PROCEDURE EVAL(U);

BEGIN SCALAR FN;

   IF CONSTANTP U THEN RETURN U;

IF IDP U THEN RETURN

  U is an id. Return the value most currently bound to U or if there is no such binding: ERROR(000, LIST("Unbound:", U));

IF PAIRP CAR U THEN RETURN

IF CAAR U EQ ’LAMBDA THEN APPLY(CAR U, EVLIS CDR U)

ELSE ERROR(000, LIST(CAR U,

"improperly formed LAMBDA expression"))

ELSE IF CODEP CAR U THEN

RETURN APPLY(CAR U, EVLIS CDR U);

FN := GETD CAR U;

IF NULL FN THEN

ERROR(000, LIST(CAR U, "is an undefined function"))

ELSE IF CAR FN EQ ’EXPR THEN

RETURN APPLY(CDR FN, EVLIS CDR U)

ELSE IF CAR FN EQ ’FEXPR THEN

RETURN APPLY(CDR FN, LIST CDR U)

ELSE IF CAR FN EQ ’MACRO THEN

RETURN EVAL APPLY(CDR FN, LIST U)

END;

EVLIS(U:any-list):any-list eval, spread
 
EVLIS returns a list of the evaluation of each element of U.
EXPR PROCEDURE EVLIS(U);

  IF NULL U THEN NIL

   ELSE EVAL CAR U . EVLIS CDR U;

EXPAND(L:list, FN:function):list eval, spread
 
FN is a defined function of two arguments to be used in the expansion of a MACRO. EXPAND returns a list in the form:

(FN L0 (FN L1 …(FN Ln-1 Ln) …))

where n is the number of elements in L, Li is the ith element of L.

EXPR PROCEDURE EXPAND(L,FN);

  IF NULL CDR L THEN CAR L

   ELSE LIST(FN, CAR L, EXPAND(CDR L, FN));

FUNCTION(FN:function):function noeval, nospread
 
The function FN is to be passed to another function. If FN is to have side effects its free variables must be fluid or global. FUNCTION is like QUOTE but its argument may be affected by compilation. We do not consider FUNARGs in this report.

QUOTE(U:any):any noeval, nospread
 
Stops evaluation and returns U unevaluated.
FEXPR PROCEDURE QUOTE(U);

   CAR U;