The Core of the Explicit-Control Evaluator The Dispatcher and Basic Evaluation - SICP Comparison Edition" /> 5.4.1   <span style="color:green">The Core of the Explicit-Control Evaluator</span> <span style="color:blue">The Dispatcher and Basic Evaluation</span> - SICP Comparison Edition
Original JavaScript
"ev_sequence", assign("unev", list(op("sequence_statements"), reg("comp"))), test(list(op("is_empty_sequence"), reg("unev"))), branch(label("ev_sequence_empty")), save("continue"), "ev_sequence_next", assign("comp", list(op("first_statement"), reg("unev"))), test(list(op("is_last_statement"), reg("unev"))), branch(label("ev_sequence_last_statement")), save("unev"), save("env"), assign("continue", label("ev_sequence_continue")), go_to(label("eval_dispatch")), "ev_sequence_continue", restore("env"), restore("unev"), assign("unev", list(op("rest_statements"), reg("unev"))), go_to(label("ev_sequence_next")), "ev_sequence_last_statement", restore("continue"), go_to(label("eval_dispatch")), "ev_sequence_empty", assign("val", constant(undefined)), go_to(reg("continue")),

[1] In our controller, the dispatch is written as a sequence of test and branch instructions. Alternatively, it could have been written in a data-directed style (and in a real system it probably would have been) to avoid style, which avoids the need to perform sequential tests and to facilitate facilitates the definition of new expressioncomponent types. A machine designed to run Lisp would probably include a dispatch-on-type instruction that would efficiently execute such data-directed dispatches.
[2] This is an important but subtle point in translating algorithms from a procedural language, such as Lisp, to a register-machine language. As an alternative to saving only what is needed, we could save all the registers (except val) before each recursive call. This is called a framed-stack discipline. This would work but might save more registers than necessary; this could be an important consideration in a system where stack operations are expensive. Saving registers whose contents will not be needed later may also hold on to useless data that could otherwise be garbage-collected, freeing space to be reused.
[3] We add to the evaluator data-structure procedures in section 4.1.3 the following two procedures for manipulating argument lists: (define (empty-arglist) '()) (define (adjoin-arg arg arglist) (append arglist (list arg))) We also use an additional syntax procedure to test for the last operand in a combination: (define (last-operand? ops) (null? (cdr ops)))
[4] The optimization of treating the last operand specially is known as evlis tail recursion (see Wand 1980). We could be somewhat more efficient in the argument evaluation loop if we made evaluation of the first operand a special case too. This would permit us to postpone initializing argl until after evaluating the first operand, so as to avoid saving argl in this case. The compiler in section 5.5 performs this optimization. (Compare the construct-arglist procedure of section 5.5.3.)
[5] The order of operand evaluation in the metacircular evaluator is determined by the order of evaluation of the arguments to cons in the procedure list-of-values of section 4.1.1 (see exercise 4.2).
[6] In this chapter, we will use the function is_falsy to test the value of the predicate. This allows us to write the consequent and alternative branches in the same order as in a conditional, and simply fall through to the consequent branch when the predicate holds. The function is_falsy is declared as the opposite of the is_truthy function used to test predicates of conditionals in section 4.1.1.
5.4.1   The Core of the Explicit-Control Evaluator The Dispatcher and Basic Evaluation