1

我想知道当变量不在编译时环境中时如何使用文本建议的(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)))))))))
4

1 回答 1

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,如果你想知道这部分,你可以在其他 Scheme 实现set-mcdr!中替换它。set-cdr!

于 2012-07-14T16:44:42.030 回答