[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 the need to perform sequential tests and to facilitate the definition of new expression types. A machine designed to run JavaScript 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 JavaScript, 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 onto useless data that could otherwise be garbage-collected, freeing space to be reused.
[3] We add to the evaluator data-structure functions in section 4.1.3 the following two functions for manipulating argument lists:
const empty_arglist = list();

 
function adjoin_arg(arg, arglist) {
    return append(arglist, list(arg));
}
We also use an additional syntax function to test for the last operand in a combination:
function is_last_operand(ops) {
    return is_null(tail(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 Cound not find label for sec:compilation performs this optimization. (Compare the construct-arglist function of section Cound not find label for sec:compiling-combinations.)
[5] The order of operand evaluation in the metacircular evaluator is determined by the order of evaluation of the arguments to pair in the function list-of-values of section 4.1.1 (see exercise 4.1).
5.4.1 The Core of the Explicit-Control Evaluator