問題4.13 – SICP(計算機プログラムの構造と解釈)その185

問題4.13

束縛の除去は環境の最初のフレームだけでよい。
現在のフレーム以外の束縛も削除してしまうと、手続き中などのスコープ内の束縛も削除されてしまう。

束縛の削除はフレーム内で見つかった変数とその値の先頭リストの参照先を変更させて行う。

(define (eval exp env)
  (cond ((self-evaluating? exp) exp)
        ; 省略
        ((unbind? exp) (eval-unbinding exp env))
        ; 省略
        (else
          (error "Unknown expression type -- EVAL" exp))))

(define (unbind? exp) (tagged-list? exp 'unbind!))

(define (eval-unbinding exp env)
  (unbind-variable! (unbinding-varialbe exp) env)
  'ok)

(define (unbinding-varialbe exp) (cadr exp))

(define (unbind-variable! var env)
  (let ((frame (first-frame env)))
       (define (scan vars vals)
         (cond ((null? vars)
                (error "Unbound variabl --UNBIND-VARIABLE:" var))
               ((eq? var (car vars))
                (set-car! vars (cadr vars))
                (set-cdr! vars (cddr vars))
                (set-car! vals (cadr vals))
                (set-cdr! vals (cddr vals)))
               (else (scan (cdr vars) (cdr vals)))))
       (scan (frame-variables frame)
             (frame-values frame))))

実行結果

;;; M-Eval input:
(define x 'a)

;;; M-Eval value:
ok

;;; M-Eval input:
(define (foo y) (define x 'b) (print (cons x y)))

;;; M-Eval value:
ok

;;; M-Eval input:
x

;;; M-Eval value:
a

;;; M-Eval input:
(foo 'a)
(b . a)

;;; M-Eval value:
#<undef>

;;; M-Eval input:
(unbind! x)

;;; M-Eval value:
ok

;;; M-Eval input:
(foo 'c)
(b . c)

;;; M-Eval value:
#<undef>

;;; M-Eval input:
x
*** ERROR: Unbound variable x
Stack Trace:
計算機プログラムの構造と解釈
ジェラルド・ジェイ サスマン ジュリー サスマン ハロルド エイブルソン
ピアソンエデュケーション
売り上げランキング: 6542
«
»