Skip to content

OperationOrderOfEvaluation

Felix S. Klock II edited this page Jul 28, 2013 · 1 revision

Here's why Will says that MacScheme is designed for right-to-left order of evaluation: Operations take their first argument in the result register.

Consider the following code: (lambda (x y) (cons (+ x x) (/ x y)))

This produces the following MacScheme assembly code (peephole optimization turned off):


        lambda      *,0
        return
        .proc
        args=       2
        reg         1,.x|1
        op2         /,2
        setreg      7
        reg         1,.x|1
        op2         +,1
        op2         cons,7
        return

Notice that we start by doing the division, then we store that in register 7. Then we do the addition. Now, since the result of the addition is in the result register, we can immediately do the cons operation--the first argument is in the result register, and the second argument is stored in a register. So the operation calling convention works nicely with right-to-left evaluation of arguments. We avoid a little bit of register-shuffling.

There is a similar benefit when we replace cons by a procedure call to f. The invoke instruction expects to find the procedure in the result register, and in right-to-left evaluation the operator position of an application is the last evaluated.

This works less well when the arguments are procedure calls, because then instead of storing the second operand in register 7, we have to stick it in the stack, and the result register gets clobbered in retrieving it. There are ways around that, too, but I don't know if that's done.

Clone this wiki locally