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