如何在练习5.42中使用(op get-global-environment)?

时间:2012-07-14 14:42:21

标签: scheme sicp

我想知道当变量不在编译时环境中时如何使用文本建议的(op get-global-environment)。 由于我必须将env设置为指向全局环境,因此我添加了保存和恢复命令但感觉不舒服,因为文本始终使用保留来保存和恢复寄存器。这是我的代码,任何想法?

(define (compile-assignment exp target linkage cmpl-env)

  (let ((var (assignment-variable exp))

        (get-value-code
         (compile (assignment-value exp cmpl-env) 'val 'next))
    (laddr (find-variable var cmpl-env)))
    (end-with-linkage
     linkage
     (preserving '(env)
         get-value-code
         (if (eq? laddr 'not-found)
             (make-instruction-sequence
              '(env val) (list target)
              `((save env)    ;;;here;;;;
            (assign env (op get-global-environment))
                    (perform (op set-variable-value!)
                     (const ,var)
                     (reg val)
                     (reg env))
            (restore env) ;;;and here ;;;;
            (assign ,target (const ok))))
           (make-instruction-sequence
            '(env val) (list target)
            `((perform lexical-address-set! laddr (reg val) (reg env)))
              (assign ,target (const ok)))))))))

1 个答案:

答案 0 :(得分:0)

当我通过SICP练习时,我以更直接的方式解决了5.42,直接访问了全局环境(因此完全跳过(op get-global-environment))。在代码之上编写我的解决方案,它看起来像这样:

(if (eq? laddr 'not-found)
    (make-instruction-sequence
     '(env val) (list target)
     `((perform (op set-global-environment!)
                (const ,var)
                (reg val))
       (assign ,target (const ok)))
     (make-instruction-sequence
      '(env val) (list target)
      `((perform (op set-variable-value!)
                 (const ,var)
                 (reg val)
                 (reg env))
        (assign ,target (const ok))))))

使用以下帮助程序定义:

(define the-global-environment (setup-environment))

(define (set-global-environment! var val)
  (cond ((massq var (first-frame the-global-environment))
         => (lambda (binding) (set-mcdr! binding val)))
        (else (error "Unbound variable -- SET" var))))

注意:我正在使用Racket,如果您想知道set-mcdr!部分,可以在其他Scheme实现中将其替换为set-cdr!