Exercise 5.39. Write a procedure lexical-address-lookup that implements the new lookup operation. It should take two arguments -- a lexical address and a run-time environment -- and return the value of the variable stored at the specified lexical address. Lexical-address-lookup should signal an error if the value of the variable is the symbol *unassigned*. Also write a procedure lexical-address-set! that implements the operation that changes the value of the variable at a specified lexical address. ———————————————————————————————————————————————————————————————————————— For reference, lookup-variable-value from ch5-eceval-support.scm: (define (lookup-variable-value var env) (define (env-loop env) (define (scan vars vals) (cond ((null? vars) (env-loop (enclosing-environment env))) ((eq? var (car vars)) (car vals)) (else (scan (cdr vars) (cdr vals))))) (if (eq? env the-empty-environment) (error "Unbound variable" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env)) --- (define (lexical-address-lookup lexaddr env) (let ((frame (find-frame (car lexaddr) env))) (let ((val (frame-find-val (cadr lexaddr) frame))) (if (eq? val '*unassigned*) (error "Unassigned variable dereference") val)))) (define (lexical-address-set! lexaddr env val) (let ((frame (find-frame (car lexaddr) env))) (frame-set-val! (cadr lexaddr) frame val))) (define (find-frame index env) (if (= index 0) (first-frame env) (find-frame (- index 1) (enclosing-environment env)))) (define (frame-find-val index frame) (list-ref (frame-values frame) index)) (define (frame-set-val! index frame val) (define (go index values) (if (= index 0) (set-car! values val) (go (- index 1) (cdr values)))) (go index (frame-values frame)))