#lang r5rs (define (error x) (display x) (newline)) (define (make-frame variables values) (if (not (= (length variables) (length values))) (error "Number of variables and values should be the same -- MAKE-FRAME") (map cons variables values))) (define (frame-variables frame) (map car frame)) (define (frame-values frame) (map cdr frame)) (define (add-binding-to-frame! var val frame) (define (add-to-end-of-frame! b f) (if (null? (cdr f)) (set-cdr! f b) (add-to-end-of-frame! b (cdr f)))) (add-to-end-of-frame! (cons var val) frame)) (define (lookup-variable-value var env) (define (env-loop env) (define (scan frame) (if (null? frame) (env-loop (enclosing-environment env)) (let ((p (car frame))) (if (eq? var (car p)) (cdr p) (scan (cdr frame)))))) (if (eq? env the-empty-environment) (error "variable not defined") (let ((f (first-frame env))) (scan f)))) (env-loop env)) (define (set-variable-value! var val env) (define (env-loop env) (define (scan frame) (if (null? frame) (env-loop (enclosing-environment env)) (let ((p (car frame))) (if (eq? var (car p)) (set-cdr! p val) (scan (cdr frame)))))) (if (eq? env the-empty-environment) (error "variable not defined") (let ((f (first-frame env))) (scan f)))) (env-loop env)) (define (define-variable! var val env) (let ((frame (first-frame env))) (define (scan frame) (if (null? frame) (add-binding-to-frame var val frame) (let ((p (car frame))) (if (eq? (car p) var) (set-cdr! p val) (scan (cdr frame)))))) (scan frame)))