SICP Exercise 4.12
在这个练习中我们使用框架原有的表示,即把框架表示为表的序对,而不是练习4.11中的方式。为了把环境的遍历和框架的遍历分开,我增加了两个过程,如下:
(define (scan var frame) "在框架frame中查找var,如果找到返回相应的vals,如果没有找到,返回#f。" (define (iter vars vals) (cond ((null? vars) #f) ((eq? var (car vars)) vals) (else (iter (cdr vars) (cdr vals))))) (iter (frame-variables frame) (frame-values frame))) (define (env-loop var env) "在所有框架中查找var,如果找到返回相应的vals,如果没有找到,报错。" (if (eq? env the-empty-environment) (error "Unbound variable" var) (let ((vals (scan var (first-frame env)))) (if vals vals (env-loop var (enclosing-environment env))))))
现在我们环境操作就变的简单多了:
(define (lookup-variable-value var env) (car (env-loop var env))) (define (set-variable-value! var val env) (set-car! (env-loop var env) val)) (define (define-variable! var val env) (let ((frame (first-frame env))) (let ((vals (scan var frame))) (if vals (set-car! vals val) (add-binding-to-frame! var val frame)))))
下面,我给出了一个简单的测试:
(define vars '(a b c d)) (define vals (list 1 2 3 4)) (define a (make-frame vars vals)) (define env (cons a '())) (lookup-variable-value 'a env) (set-variable-value! 'a 100 env) (lookup-variable-value 'a env) (define-variable! 'e 5 env) (lookup-variable-value 'e env)
运行结果如下:
1 100 5