123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- #lang racket
- (require "box.scm")
- (provide env env-bindings env-specials set-env-bindings! set-env-specials!
- make-binding make-dummy-binding
- extend-env extend-env* update-env! update-env!*
- special? bound? env-ref)
- ;;; environments
- ;;
- ;; an environment is the mapping of variable names -> values
- ;; during resolve we just make dummy bindings, everything is mapped to #f
- ;; envs also hold the list of unshadowed special forms
- (struct env ((bindings #:mutable)
- (specials #:mutable))
- #:transparent)
- (define (make-binding key value)
- (cons key (box value)))
- (define (make-dummy-binding key)
- (make-binding key #f))
- (define (extend-env env^ binding)
- (env (cons binding (env-bindings env^))
- (remove (car binding) (env-specials env^))))
- (define (extend-env* env^ bindings)
- (env (append bindings (env-bindings env^))
- (remove* (map car bindings) (env-specials env^))))
- (define (update-env! env binding)
- (set-env-bindings! env (cons binding (env-bindings env)))
- (set-env-specials! env (remove (car binding) (env-specials env)))
- env)
- (define (update-env!* env bindings)
- (set-env-bindings! env (append bindings (env-bindings env)))
- (set-env-specials! env (remove* (map car bindings) (env-specials env)))
- env)
- (define (special? s env)
- (member s (env-specials env)))
- (define (bound? var env)
- (assoc var (env-bindings env)))
- (define (env-ref key env)
- (let ((binding (assoc key (env-bindings env))))
- (unless binding
- (error "env-ref: no such key" key))
- (box-value (cdr binding))))
|