environment.scm 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
  2. ;;;
  3. ;;; Port Author: Andrew Whatson
  4. ;;;
  5. ;;; Original Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  6. ;;;
  7. ;;; scheme48-1.9.2/scheme/rts/env.scm
  8. ;;;
  9. ;;; Accessing packages
  10. (define-module (prescheme environment)
  11. #:use-module (prescheme scheme48)
  12. #:use-module (prescheme bcomp binding)
  13. #:use-module (prescheme bcomp package)
  14. #:use-module (prescheme bcomp mtype)
  15. #:use-module (prescheme locations)
  16. #:export (*structure-ref
  17. environment-define!
  18. environment-ref
  19. environment-set!
  20. interaction-environment
  21. make-syntactic-tower
  22. make-reflective-tower ;; backwards compatibility for PreScheme compiler
  23. scheme-report-environment
  24. null-environment
  25. set-interaction-environment!
  26. set-scheme-report-environment!
  27. with-interaction-environment
  28. set-syntactic-tower-maker!
  29. set-reflective-tower-maker! ;; backwards compatibility for PreScheme compiler
  30. set-reader!))
  31. (define (environment-ref package name)
  32. (carefully (package-lookup package name)
  33. (lambda (loc)
  34. (if (location-assigned? loc)
  35. (contents loc)
  36. (assertion-violation 'environment-ref "uninitialized variable"
  37. name package)))
  38. package
  39. name))
  40. (define (environment-set! package name value)
  41. (let ((binding (package-lookup package name)))
  42. (if (and (binding? binding)
  43. (not (variable-type? (binding-type binding))))
  44. (assertion-violation 'environment-set! "invalid assignment" name package value)
  45. (carefully binding
  46. (lambda (loc)
  47. (set-contents! loc value))
  48. package name))))
  49. (define (environment-define! package name value)
  50. (set-contents! (package-define! package name usual-variable-type #f #f)
  51. value))
  52. (define (*structure-ref struct name)
  53. (let ((binding (structure-lookup struct name #f)))
  54. (if binding
  55. (carefully binding contents struct name)
  56. (assertion-violation 'structure-ref "name not exported" struct name))))
  57. (define (carefully binding action env name)
  58. (cond ((not binding)
  59. (assertion-violation 'carefully "unbound variable" name env))
  60. ((not (binding? binding))
  61. (assertion-violation 'carefully "peculiar binding" binding name env))
  62. ((eq? (binding-type binding) syntax-type)
  63. (assertion-violation 'carefully "attempt to reference syntax as variable"
  64. name env))
  65. (else
  66. (let ((loc (binding-place binding)))
  67. (if (location? loc)
  68. (if (location-defined? loc)
  69. (action loc)
  70. (assertion-violation 'carefully "unbound variable" name env))
  71. (assertion-violation 'carefully "variable has no location" name env))))))
  72. ; Interaction environment
  73. (define $interaction-environment (make-fluid (make-cell #f)))
  74. (define (interaction-environment)
  75. (fluid-cell-ref $interaction-environment))
  76. (define (set-interaction-environment! p)
  77. (if (package? p)
  78. (fluid-cell-set! $interaction-environment p)
  79. (assertion-violation 'set-interaction-environment!
  80. "invalid package" set-interaction-environment! p)))
  81. (define (with-interaction-environment p thunk)
  82. (if (package? p)
  83. (with-fluid* $interaction-environment (make-cell p) thunk)
  84. (assertion-violation 'with-interaction-environment
  85. "invalid package" with-interaction-environment p)))
  86. ; Scheme report environment. Should be read-only; fix later.
  87. (define (scheme-report-environment n)
  88. (if (= n *scheme-report-number*)
  89. *scheme-report-environment*
  90. (assertion-violation 'scheme-report-environment
  91. "no such Scheme report environment")))
  92. (define *scheme-report-environment* #f)
  93. (define *null-environment* #f)
  94. (define *scheme-report-number* 0)
  95. (define (set-scheme-report-environment! repnum env)
  96. (set! *scheme-report-number* repnum)
  97. (set! *scheme-report-environment* env)
  98. (set! *null-environment* env)) ; A cheat.
  99. (define (null-environment n)
  100. (if (= n *scheme-report-number*)
  101. *null-environment*
  102. (assertion-violation 'null-environment
  103. "no such Scheme report environment")))
  104. ; Make an infinite tower of packages for syntax.
  105. ; structs should be a non-null list of structures that should be
  106. ; opened at EVERY level of the tower.
  107. (define (make-syntactic-tower eval structs id)
  108. (let recur ((level 1))
  109. (delay (cons eval
  110. (make-simple-package structs
  111. eval
  112. (recur (+ level 1))
  113. `(for-syntax ,level ,id))))))
  114. ; backwards compatibility for PreScheme compiler
  115. (define make-reflective-tower make-syntactic-tower)
  116. ; (set-syntactic-tower-maker! p (lambda (clauses id) ...))
  117. ; where clauses is a list of DEFINE-STRUCTURE clauses
  118. (define set-syntactic-tower-maker!
  119. (let ((name (string->symbol ".make-syntactic-tower."))
  120. (name2 (string->symbol ".make-reflective-tower.")))
  121. (lambda (p proc)
  122. (environment-define! p name proc)
  123. ;; backwards compatibility for PreScheme compiler
  124. (environment-define! p name2 proc))))
  125. ; backwards compatibility for PreScheme compiler
  126. (define set-reflective-tower-maker!
  127. (let ((reader-name (string->symbol ".reader.")))
  128. (lambda (p proc)
  129. (set-syntactic-tower-maker! p proc)
  130. ;; total, utter kludge:
  131. ;; The reader wasn't configurable in earlier versions of Scheme 48,
  132. ;; so PreScheme doesn't how to initialize it.
  133. (if (not (package-lookup p reader-name))
  134. (environment-define! p reader-name read)))))
  135. (define set-reader!
  136. (let ((name (string->symbol ".reader.")))
  137. (lambda (p reader)
  138. (environment-define! p name reader))))