さかもとのブログ

つらつらと

SICP演習問題5.42

(define (found? var)
  (if (not (eq? var 'not-found)) var false))

(define (compile-variable exp target linkage compile-time-env)
  (let ((found (found? (find-variable exp compile-time-env))))
    (end-with-linkage
     linkage
     (make-instruction-sequence
      '(env)
      (list target)
      (if found
          `((assign ,target
                    (op lexical-address-lookup)
                    (const ,found)
                    (reg env)))
          `((assign ,target
                    (op lookup-variable-value)
                    (const ,exp)
                    (reg env))))))))
(define (compile-assignment exp target linkage compile-time-env)
  (let ((var (assignment-variable exp))
        (get-value-code
         (compile (assignment-value exp) 'val 'next compile-time-env)))
      (let ((found (found? (find-variable var compile-time-env))))
        (end-with-linkage
         linkage
         (preserving
          '(env)
          get-value-code
          (make-instruction-sequence
           '(env val)
           (list target)
           (if found
               `((perform (op lexical-address-set!)
                          (const ,found)
                          (reg val)
                          (reg env))
                 (assign ,target (const ok)))
               `((perform (op set-variable-value!)
                          (const ,var)
                          (reg val)
                          (reg env))
                 (assign ,target (const ok)))))))
        )))
実行
(print-after-compiler
 (compile
  '(lambda (x y)
     (lambda (a)
       (* x y a)
       (set! w y)
       (set! y a)))
  'val
  'next
  '()))
(env)
(val)
  (assign val (op make-compiled-procedure) (label entry18) (reg env))
  (goto (label after-lambda19))
entry18
  (assign env (op compiled-procedure-env) (reg proc))
  (assign env (op extend-environment) (const (x y)) (reg argl) (reg env))
  (assign val (op make-compiled-procedure) (label entry20) (reg env))
  (goto (reg continue))
entry20
  (assign env (op compiled-procedure-env) (reg proc))
  (assign env (op extend-environment) (const (a)) (reg argl) (reg env))
  (save continue)
  (save env)
  (assign proc (op lookup-variable-value) (const *) (reg env))
  (assign val (op lexical-address-lookup) (const (0 0)) (reg env))
  (assign argl (op list) (reg val))
  (assign val (op lexical-address-lookup) (const (1 1)) (reg env))
  (assign argl (op cons) (reg val) (reg argl))
  (assign val (op lexical-address-lookup) (const (1 0)) (reg env))
  (assign argl (op cons) (reg val) (reg argl))
  (test (op primitive-procedure?) (reg proc))
  (branch (label primitive-branch22))
compiled-branch23
  (assign continue (label after-call24))
  (assign val (op compiled-procedure-entry) (reg proc))
  (goto (reg val))
primitive-branch22
  (assign val (op apply-primitive-procedure) (reg proc) (reg argl))
after-call24
  (restore env)
  (restore continue)
  (assign val (op lexical-address-lookup) (const (1 1)) (reg env))
  (perform (op set-variable-value!) (const w) (reg val) (reg env))
  (assign val (const ok))
  (assign val (op lexical-address-lookup) (const (0 0)) (reg env))
  (perform (op lexical-address-set!) (const (1 1)) (reg val) (reg env))
  (assign val (const ok))
  (goto (reg continue))
after-lambda21
after-lambda19

ちゃんとwや*はlookup-variable-value, set-variable-value!が使われていて,x,yなどにはlexical~が使われいる.