Exercise 5.35. What expression was compiled to produce the code shown in figure 5.18? ———————————————————————————————————————————————————————————————————————— ;; here we have a lambda, and at after-lambda15 this is assigned to ;; a variable f, so we have (define f ...) (assign val (op make-compiled-procedure) (label entry16) (reg env)) (goto (label after-lambda15)) entry16 ; entry point for f (assign env (op compiled-procedure-env) (reg proc)) ;; f has one argument 'x' (assign env (op extend-environment) (const (x)) (reg argl) (reg env)) ;; we are doing (+ ...) (assign proc (op lookup-variable-value) (const +) (reg env)) (save continue) (save proc) (save env) ;; we are doing (g ...) (assign proc (op lookup-variable-value) (const g) (reg env)) (save proc) ;; we are doing (+ ...) again (assign proc (op lookup-variable-value) (const +) (reg env)) (assign val (const 2)) (assign argl (op list) (reg val)) (assign val (op lookup-variable-value) (const x) (reg env)) (assign argl (op cons) (reg val) (reg argl)) ;; the args to + are x and 2, so (+ 2 x) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch19)) compiled-branch18 (assign continue (label after-call17)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch19 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) ;; val is now (+ 2 x) after-call17 (assign argl (op list) (reg val)) (restore proc) ;; the proc just restored was g, and the arguments to g is ;; just the previous result of (+ 2 x) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch22)) compiled-branch21 (assign continue (label after-call20)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch22 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call20 ;; we just came back from the call to g (assign argl (op list) (reg val)) (restore env) ;; now argl is the result of (g (+ 2 x)) (assign val (op lookup-variable-value) (const x) (reg env)) (assign argl (op cons) (reg val) (reg argl)) ;; now argl has x consed onto it, so it is `(x ,(g (+ 2 x))) (restore proc) ;; the proc we just restored is +, from way up at the top. (restore continue) ;; continue is whatever it was when f was entered, and we are ;; either going to (goto (reg continue)) below or we are going ;; to call a compiled procedure which will do the same, so this ;; is a tail-call of (+ x (g (+ 2 x))) ;; so that's the whole body of f (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch25)) compiled-branch24 (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch25 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) (goto (reg continue)) after-call23 after-lambda15 (perform (op define-variable!) (const f) (reg val) (reg env)) (assign val (const ok)) So, the expression was: (define (f x) (+ x (g (+ 2 x))))