1

変数がコンパイル時の環境にない場合に、テキストで提案されている (op get-global-environment) の使用方法を知りたいです。グローバル環境を指すように環境を設定する必要があるため、保存コマンドと復元コマンドを追加しましたが、テキストは常に保存を使用してレジスタを保存および復元するため、快適ではありません。これが私のコードです、何かアイデアはありますか?

(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 に答える