-#lang racket
+#lang r5rs
+
+(define (error x)
+ (display x)
+ (newline))
(define (make-frame variables values)
(if (not (= (length variables)
(map cdr frame))
(define (add-binding-to-frame! var val frame)
- (set! frame (cons (cons 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)))