+: (analyze-sequence) ( explist -- eproc-list )
+ nil? if exit then
+
+ 2dup car analyze
+ 2swap cdr recurse
+
+ cons
+;
+
+: analyze-sequence ( explist -- eproc )
+ (analyze-sequence)
+ ['] sequence-executor primitive-proc-type
+ nil cons cons
+;
+
+
+: macro-definition-executor ( name params bproc env -- ok )
+ make-macro ok-symbol
+;
+
+: analyze-macro-definition ( exp -- eproc )
+ 2dup macro-definition-name
+ 2swap 2dup macro-definition-params
+ 2swap macro-definition-body analyze-sequence
+
+ ['] macro-definition-executor primitive-proc-type
+ nil cons cons cons cons
+;
+
+: if-executor ( cproc aproc pproc env -- res )
+ 2swap 2over ( cproc aproc env pproc env -- res )
+ evaluate-eproc
+
+ true? if
+ 2swap 2drop
+ else
+ 2rot 2drop
+ then
+
+ ['] evaluate-eproc goto
+;
+
+: analyze-if ( exp -- eproc )
+ 2dup if-consequent analyze
+ 2swap 2dup if-alternative analyze
+ 2swap if-predicate analyze
+
+ ['] if-executor primitive-proc-type
+ nil cons cons cons cons
+;
+
+: lambda-executor ( params bproc env -- res )
+ make-procedure
+ ( Although this is packaged up as a regular compound procedure,
+ the "body" element contains an _eproc_ to be evaluated in an
+ environment resulting from extending env with the parameter
+ bindings. )
+;
+
+: analyze-lambda ( exp -- eproc )
+ 2dup lambda-parameters
+ 2swap lambda-body
+
+ nil? if
+ except-message: ." encountered lambda with an empty body." recoverable-exception throw
+ then
+
+ analyze-sequence
+
+ ['] lambda-executor primitive-proc-type
+ nil cons cons cons
+;
+
+: operand-eproc-list ( operands -- eprocs )
+ nil? invert if
+ 2dup car analyze
+ 2swap cdr recurse
+ cons
+ then
+;
+
+: evaluate-operand-eprocs ( env aprocs -- vals )
+ nil? if
+ 2swap 2drop
+ else
+ 2over 2over car 2swap evaluate-eproc ( env aprocs thisval )
+ -2rot cdr recurse ( thisval restvals )
+ cons
+ then
+;
+
+: apply ( vals proc )
+ dup case
+ primitive-proc-type of
+ drop execute
+ endof
+
+ compound-proc-type of
+ 2dup procedure-body ( argvals proc bproc )
+ -2rot 2dup procedure-params ( bproc argvals proc argnames )
+ -2rot procedure-env ( bproc argnames argvals procenv )