linking.scm 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Mike Sperber
  3. ; This file has the Pre-Scheme compiler's code for dealing with the
  4. ; Scheme 48's module system.
  5. ; FILES is a list of files that contain structure definitions, including
  6. ; a definition for NAME. The files are loaded into a config package
  7. ; containing:
  8. ; - the procedures and macros for defining structures and interfaces
  9. ; - a Pre-Scheme structure (called PRESCHEME)
  10. ; - a ps-memory structure
  11. ; - a ps-receive structure
  12. ; - the STRUCTURE-REFS structure
  13. ; We then return:
  14. ; 1. a list of the packages required to implement the named structures
  15. ; 2. a list of the names exported by the named structures
  16. ; 3. a procedure that for looking up names defined in packages in the
  17. ; config package (this is used to map user directives to their targets)
  18. (define (package-specs->packages+exports struct-names files)
  19. (let ((config (make-very-simple-package 'config (list defpackage)))
  20. (old-config ((structure-ref package-commands-internal config-package))))
  21. (environment-define! config 'prescheme prescheme)
  22. (environment-define! config 'ps-memory ps-memory)
  23. (environment-define! config 'ps-receive ps-receive)
  24. (environment-define! config 'ps-flonums ps-flonums)
  25. (environment-define! config 'ps-unsigned-integers ps-unsigned-integers)
  26. (environment-define! config 'ps-record-types ps-record-types)
  27. (environment-define! config 'structure-refs structure-refs)
  28. (environment-define! config ':syntax (structure-ref meta-types syntax-type))
  29. (set-reflective-tower-maker! config (get-reflective-tower-maker old-config))
  30. (let-fluids (structure-ref packages-internal $get-location)
  31. (make-cell get-variable)
  32. (structure-ref reading-forms $note-file-package)
  33. (make-cell (lambda (filename package) (values)))
  34. (lambda ()
  35. (for-each (lambda (file)
  36. (load file config))
  37. files)))
  38. (values (collect-packages (map (lambda (name)
  39. (environment-ref config name))
  40. struct-names)
  41. (lambda (package)
  42. #t))
  43. (let ((names '()))
  44. (for-each (lambda (struct-name)
  45. (let ((my-names '()))
  46. (for-each-declaration
  47. (lambda (name package-name type)
  48. (set! my-names (cons name my-names)))
  49. (structure-interface
  50. (environment-ref config struct-name)))
  51. (set! names
  52. (cons (cons struct-name my-names)
  53. names))))
  54. struct-names)
  55. names)
  56. (make-lookup config))))
  57. ; This creates new variables as needed for packages.
  58. (define (get-variable package name)
  59. ;(format #t "Making variable ~S for ~S~%" name package)
  60. ((structure-ref variable make-global-variable)
  61. name
  62. (structure-ref ps-types type/unknown)))
  63. ; Return something that will find the binding of ID in the package belonging
  64. ; to the structure PACKAGE-ID in the CONFIG package.
  65. (define (make-lookup config)
  66. (lambda (package-id id)
  67. (let ((binding (package-lookup config package-id)))
  68. (if (and (binding? binding)
  69. (location? (binding-place binding))
  70. (structure? (contents (binding-place binding))))
  71. (let* ((package (structure-package
  72. (contents (binding-place binding))))
  73. (binding (package-lookup package id)))
  74. (if (binding? binding)
  75. (binding-place binding)
  76. #f))
  77. #f))))
  78. ;----------------------------------------------------------------
  79. ; Handy packages and package making stuff.
  80. (define defpackage (structure-ref built-in-structures defpackage))
  81. (define structure-refs (structure-ref built-in-structures structure-refs))
  82. (define scheme (structure-ref built-in-structures scheme))
  83. (define (make-env-for-syntax-promise . structures)
  84. (make-reflective-tower eval structures 'prescheme-linking))
  85. (define (make-very-simple-package name opens)
  86. (make-simple-package opens
  87. eval
  88. (make-env-for-syntax-promise scheme)
  89. name))
  90. (define (get-reflective-tower-maker p)
  91. (environment-ref p (string->symbol ".make-reflective-tower.")))
  92. ;----------------------------------------------------------------
  93. ; The following stuff is used to define the DEFINE-RECORD-TYPE macro.
  94. ; We produce a structure that exports EXPAND-DEFINE-RECORD-TYPE. The
  95. ; base package then includes that structure in its FOR-SYNTAX package.
  96. (define defrecord-for-syntax-package
  97. (make-very-simple-package 'defrecord-for-syntax-package '()))
  98. (define defrecord-for-syntax-structure
  99. (make-structure defrecord-for-syntax-package
  100. (lambda () (export expand-define-record-type))
  101. 'defrecord-for-syntax-structure))
  102. (define (define-for-syntax-value id value)
  103. (let ((loc (make-new-location defrecord-for-syntax-package id)))
  104. (set-contents! loc value)
  105. (package-define! defrecord-for-syntax-package
  106. id
  107. (structure-ref meta-types usual-variable-type)
  108. loc
  109. #f)))
  110. (define-for-syntax-value 'expand-define-record-type expand-define-record-type)
  111. ;----------------------------------------------------------------
  112. ; BASE-PACKAGE contains all of the primitives, syntax, etc. for Pre-Scheme
  113. (define (prescheme-unbound package name)
  114. (bug "~S has no binding in package ~S" name package))
  115. (define base-package
  116. ; (let-fluid (structure-ref packages-internal $get-location) prescheme-unbound
  117. ; (lambda () ))
  118. (make-simple-package '()
  119. eval
  120. (make-env-for-syntax-promise
  121. scheme
  122. defrecord-for-syntax-structure)
  123. 'base-package))
  124. ; Add the operators.
  125. (let ((syntax-type (structure-ref meta-types syntax-type)))
  126. (for-each (lambda (id)
  127. (package-define! base-package
  128. id
  129. syntax-type
  130. #f
  131. (get-operator id syntax-type)))
  132. '(if begin lambda letrec quote set!
  133. define define-syntax let-syntax letrec-syntax
  134. ; the rest are special for Prescheme
  135. goto type-case real-external)))
  136. ; Add the usual macros.
  137. (let ((syntax-type (structure-ref meta-types syntax-type)))
  138. (for-each (lambda (name)
  139. (package-define! base-package
  140. name
  141. syntax-type
  142. #f
  143. (make-transform
  144. (usual-transform name)
  145. base-package
  146. (structure-ref meta-types syntax-type)
  147. `(usual-transform ',name)
  148. name)))
  149. '(and cond do let let* or quasiquote))) ; delay
  150. ; Plus whatever primitives are wanted.
  151. (define (define-prescheme! name location static)
  152. (package-define! base-package
  153. name
  154. (structure-ref meta-types usual-variable-type)
  155. location
  156. static))
  157. ; Copy over the enumeration macros and the ERRORS enumeration.
  158. (define (import-syntax! package-id name)
  159. (let ((config ((structure-ref package-commands-internal config-package)))
  160. (syntax-type (structure-ref meta-types syntax-type)))
  161. (let ((binding (structure-lookup (environment-ref config package-id)
  162. name
  163. #t)))
  164. (package-define! base-package
  165. name
  166. syntax-type
  167. (binding-place binding)
  168. (binding-static binding)))))
  169. (import-syntax! 'enumerated 'define-enumeration)
  170. (import-syntax! 'enumerated 'enum)
  171. (import-syntax! 'enumerated 'name->enumerand)
  172. (import-syntax! 'enumerated 'enumerand->name)
  173. (import-syntax! 'prescheme 'errors)
  174. (import-syntax! 'prescheme 'define-external-enumeration)
  175. (import-syntax! 'scheme 'syntax-rules)
  176. ; define still more syntax
  177. (load "prescheme/ps-syntax.scm" base-package)
  178. (eval '(define-syntax define-record-type expand-define-record-type)
  179. base-package)
  180. ;(eval '(define-syntax define-union-type expand-define-union-type)
  181. ; base-package)
  182. ;----------------------------------------------------------------
  183. ; Make the Pre-Scheme structure and related structures
  184. (define (get-interface name)
  185. (environment-ref ((structure-ref package-commands-internal config-package))
  186. name))
  187. (define prescheme
  188. (make-structure base-package
  189. (lambda () (get-interface 'prescheme-interface))
  190. 'prescheme))
  191. (define ps-memory
  192. (make-structure base-package
  193. (lambda () (get-interface 'ps-memory-interface))
  194. 'ps-memory))
  195. (define ps-flonums
  196. (make-structure base-package
  197. (lambda () (get-interface 'ps-flonums-interface))
  198. 'ps-flonums))
  199. (define ps-unsigned-integers
  200. (make-structure base-package
  201. (lambda () (get-interface 'ps-unsigned-integers-interface))
  202. 'ps-unsigned-integers))
  203. (define ps-receive
  204. (make-structure base-package
  205. (lambda () (get-interface 'ps-receive-interface))
  206. 'ps-receive))
  207. (define ps-record-types
  208. (make-structure base-package
  209. (lambda () (export (define-record-type :syntax)))
  210. 'ps-record-types))
  211. ; and a handy environment
  212. (define prescheme-compiler-env
  213. (package->environment base-package))