environment.scm 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #lang racket
  2. (require "box.scm")
  3. (provide env env-bindings env-specials set-env-bindings! set-env-specials!
  4. make-binding make-dummy-binding
  5. extend-env extend-env* update-env! update-env!*
  6. special? bound? env-ref)
  7. ;;; environments
  8. ;;
  9. ;; an environment is the mapping of variable names -> values
  10. ;; during resolve we just make dummy bindings, everything is mapped to #f
  11. ;; envs also hold the list of unshadowed special forms
  12. (struct env ((bindings #:mutable)
  13. (specials #:mutable))
  14. #:transparent)
  15. (define (make-binding key value)
  16. (cons key (box value)))
  17. (define (make-dummy-binding key)
  18. (make-binding key #f))
  19. (define (extend-env env^ binding)
  20. (env (cons binding (env-bindings env^))
  21. (remove (car binding) (env-specials env^))))
  22. (define (extend-env* env^ bindings)
  23. (env (append bindings (env-bindings env^))
  24. (remove* (map car bindings) (env-specials env^))))
  25. (define (update-env! env binding)
  26. (set-env-bindings! env (cons binding (env-bindings env)))
  27. (set-env-specials! env (remove (car binding) (env-specials env)))
  28. env)
  29. (define (update-env!* env bindings)
  30. (set-env-bindings! env (append bindings (env-bindings env)))
  31. (set-env-specials! env (remove* (map car bindings) (env-specials env)))
  32. env)
  33. (define (special? s env)
  34. (member s (env-specials env)))
  35. (define (bound? var env)
  36. (assoc var (env-bindings env)))
  37. (define (env-ref key env)
  38. (let ((binding (assoc key (env-bindings env))))
  39. (unless binding
  40. (error "env-ref: no such key" key))
  41. (box-value (cdr binding))))