;; sicp 4.1.3 (define (enclosing-environment env) (cdr env)) (define (first-frame env) (car env)) (define-constant the-empty-environment ()) (define (make-frame variables values) (cons variables values)) (define (frame-variables frame) (car frame)) (define (frame-values frame) (cdr frame)) (define (add-binding-to-frame var val frame) (set-car! frame (cons var (car frame))) (set-cdr! frame (cons val (cdr frame)))) (define (extend-environment vars vals base-env) (if (= (length vars) (length vals)) (cons (make-frame vars vals) base-env) (if (< (length vars) (length vals)) (error "Too many arguments supplied" vars vals) (error "Too few arguments supplied" vars vals)))) (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? (first-frame env) the-empty-environment) (error "Unbound variable" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env)) (define (set-variable-value var val env) (define (env-loop env) (define (scan vars vals) (cond ((null? vars) (env-loop (enclosing-environment env))) ((eq? var (car vars)) (set-car! vals val)) (else (scan (cdr vars) (cdr vals))))) (if (eq? (first-frame env) the-empty-environment) (error "Unbound variable -- SET!" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env)) (define (define-variable var val env) (let ((frame (first-frame env))) (define (scan vars vals) (cond ((null? vars) (add-binding-to-frame var val frame)) ((eq? var (car vars)) (set-car! vals val)) (else (scan (cdr vars) (cdr vals))))) (scan (frame-variables frame) (frame-values frame)))) (define env (list (make-frame '() '()) the-empty-environment)) (define-variable 'x 2 env) (define-variable 'y 3 env) (print env) (print (lookup-variable-value 'x env)) (set-variable-value 'x 42 env) (print env) (set! env (extend-environment '(p q) '(7 8) env)) (print env) (print (lookup-variable-value 'p env)) (print (lookup-variable-value 'x env)) ;;(catch 'error ;; (print (lookup-variable-value 'z env))) (with-error-handler (lambda (err) (print "as expected: " err)) (lambda () (print (lookup-variable-value 'yaiks env)))) (with-error-handler (lambda (err) (print "as expected: " err)) (lambda () (print (set-variable-value 'yaiks 3 env))))