(define (make-frame variables values)
(if (= (length variables) (length values))
(reverse
(let make-frame-iter ((vars variables) (vals values))
(cons (cons (car vars) (cdr vals)) (make-frame-iter (cdr vars) (cdr vals)))))
(error "variables length and values length are different.")))
(define (frame-variables frame) (map car frame))
(define (frame-values frame) (map cdr frame))
(define (add-binding-to-frame! var val frame)
(set! frame (cons (cons var val) frame)))
(define (lookup-variable-value var env)
(define (env-loop env)
(define (scan pairs)
(cond ((null? pairs)
(env-loop (enclosing-envrionment env)))
((eq? var (caar pairs))
(cdar pairs))
(else (scan (cdr pairs)))))
(if (eq? env the-empty-environment)
(error "Unbound variable" var)
(let ((frame (first-frame env)))
(scan frame))))
(env-loop env))
(define (set-variable-value! var val env)
(define (env-loop env)
(define (scan pairs)
(cond ((null? pairs)
(env-loop (enclosing-environment env)))
((eq? var (caar pairs))
(set-cdr! (car pairs) val))
(else (scan (cdr pairs)))))
(if (eq? env the-empty-environment)
(error "Unbound variable -- SET!" var)
(let ((frame (first-frame env)))
(scan frame))))
(env-loop env))
(define (define-variable! var val env)
(let ((frame (first-frame env)))
(define (scan pairs)
(cond ((null? pairs)
(add-binding-to-frame! var val frame))
((eq? var (caar pairs))
(set-cdr! (car pairs) val))
(else (scan (cdr pairs)))))
(scan frame)))