<< Previous exercise (5.41) | Index | Next exercise (5.43) >>
(define (compile-variable exp target linkage compile-time-environment) (let ((lexical-addr (find-variable exp compile-time-environment))) (end-with-linkage linkage (make-instruction-sequence '(env) (list target) (if (eq? 'not-found lexical-addr) `((assign ,target (op lookup-variable-value) (const ,exp) (reg env))) `((assign ,target (op lexical-address-lookup) (const ,lexical-addr) (reg env)))))))) (define (compile-assignment exp target linkage compile-time-environment) (let ((var (assignment-variable exp)) (get-value-code (compile (assignment-value exp) 'val 'next compile-time-environment))) (let ((lexical-addr (find-variable var compile-time-environment))) (end-with-linkage linkage (preserving '(env) get-value-code (make-instruction-sequence '(env val) (list target) (if (eq? lexical-addr 'not-found) `((perform (op set-variable-value!) (const ,var) (reg val) (reg env)) (assign ,target (const ok))) `((perform (op lexical-address-set!) (const ,lexical-addr) (reg val) (reg env)))))))))) (compile '((lambda (x y) (+ x y)) 1 2) 'val 'next the-empty-environment) ; after compiling, and simulating -> 3 (compile '(((lambda (x y) (lambda (a b c d e) ((lambda (y z) (* x y z)) (* a b x) (+ c d x)))) 3 4) 1 2 3 4 5) 'val 'next the-empty-environment) ; generates and 89 instruction sequence machine, and computes 180. ; as expected.
Similar to what you all had, but I instead looked in the global environment if I got back 'not-found:
(define (compile-variable
exp target linkage compile-env)
(let ((var-addr (find-variable exp
compile-env)))
(end-with-linkage
linkage
(make-instruction-sequence
'(env)
(list target)
(if (eq? var-addr 'not-found)
`((save env)
(assign env (op get-global-environment))
(assign ,target
(op lookup-variable-value)
(const ,exp)
; Look for it straight in global env
(reg env))
(restore env))
`((assign ,target
(op lexical-address-lookup)
(const ,var-addr)
(reg env))))))))
I think this could be a little better; You might as well assign the global environment to ,target instead of env. That way you can get rid of the (save env) and (restore env) instructions.
meteorgan