This page needs to be proofread.
environments (we count two environments as identical if they involve the same variable bindings, regardless of the number of "frames" involved; that is, the environment is the same inside and outside a (LAMBDA () ...)). Assume a simple target machine with argument registers called reg1, reg2, etc.
main: <code for a> ;result in regl
LOAD reg2,[name2] ;[name2] is the closure for name2
CALL-FUNCTION 2,[name1] ;call name1 with 2 arguments
name1: JUMP-IF-NIL reg1,name1a
RETURN ;return the value in reg1
name1a: CALL-FUNCTION 0,reg2
name2: <code for b> ;result in reg1
LOAD reg2,[name4] ;[name4] is the closure for name4
CALL-FUNCTION 2,[name3] ;call name3 with 2 arguments
name3: JUMP-IF-NIL reg1,name3a
RETURN ;return the value in reg1
name3a: CALL-FUNCTION 0,reg2 ;call function in reg2, 0 arguments
name4: <code for c> ;result in reg1
LOAD reg2,[name6] ;[name6] is the closure for name6
CALL-FUNCTION 2,[name5] ;call name5 with 2 arguments
name5: JUMP-IF-NIL reg1,name5a
RETURN ;return the value in reg1
name5a: CALL-FUNCTION 0,reg2 ;call function in reg2, 0 arguments
name6: LOAD reg1,'NIL ;constant NIL in reg1
RETURN
Now we make use of our knowledge that functions, and convert CALL-FUNCTION of certain variables always denote certain a known function to a simple GOTO. (We have actually done things backwards here; in practice this knowledge is used before generating any code. We have fudged over this issue here, but will return to it later. Our purpose here is merely to demonstrate the treatment of function calls as GOTOs.)
main: <code for a> ;result in reg1 L
LOAD reg2,[name2] ;[name2] is the closure for nameZ
GOTO name1