; environment (load "utils.scm") (define list-of (lambda (base-type) (lambda (val) (and (list? val) (fold-left val (lambda (e x) (and e (base-type x))) #t) ) ) ) ) (define list-find-position (lambda (sym los) (list-index (lambda (sym1) (eqv? sym1 sym)) los) ) ) (define list-index (lambda (pred ls) (cond ((null? ls) #f) ((pred (car ls)) 0) (else (let ((list-index-r (list-index pred (cdr ls)))) (if (number? list-index-r) (+ list-index-r 1) #f))) ) ) ) (define-datatype environment environment? (empty-env-rec) (extend-env-rec (syms (list-of symbol?)) (vals (list-of (lambda (x) #t))) (env environment?)) ) ; environment operations (define empty-env (lambda () (empty-env-rec) ) ) (define extend-env (lambda (syms vals env) (extend-env-rec syms vals env) ) ) (define apply-env (lambda (env sym) (cases environment env (empty-env-rec () (eopl:error 'apply-env "No binding for ~s" sym)) (extend-env-rec (syms vals old-env) (let ((pos (list-find-position sym syms))) (if (number? pos) (list-ref vals pos) (apply-env old-env sym)))) ) ) )