File: linking.scm

package info (click to toggle)
scheme48 1.8%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 14,980 kB
  • ctags: 14,127
  • sloc: lisp: 76,272; ansic: 71,514; sh: 3,026; makefile: 637
file content (256 lines) | stat: -rw-r--r-- 8,648 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
; Copyright (c) 1993-2008 by Richard Kelsey.  See file COPYING.

; This file has the Pre-Scheme compiler's code for dealing with the
; Scheme 48's module system.

; FILES is a list of files that contain structure definitions, including
; a definition for NAME.  The files are loaded into a config package
; containing:
;   - the procedures and macros for defining structures and interfaces
;   - a Pre-Scheme structure (called PRESCHEME)
;   - a ps-memory structure
;   - a ps-receive structure
;   - the STRUCTURE-REFS structure
; We then return:
;   1. a list of the packages required to implement the named structures
;   2. a list of the names exported by the named structures
;   3. a procedure that for looking up names defined in packages in the
;      config package (this is used to map user directives to their targets)

(define (package-specs->packages+exports struct-names files)
  (let ((config (make-very-simple-package 'config (list defpackage)))
	(old-config ((structure-ref package-commands-internal config-package))))
    (environment-define! config 'prescheme prescheme)
    (environment-define! config 'ps-memory ps-memory)
    (environment-define! config 'ps-receive ps-receive)
    (environment-define! config 'ps-flonums ps-flonums)
    (environment-define! config 'ps-unsigned-integers ps-unsigned-integers)
    (environment-define! config 'ps-record-types ps-record-types)
    (environment-define! config 'structure-refs structure-refs)
    (environment-define! config ':syntax (structure-ref meta-types syntax-type))
    (set-reflective-tower-maker! config (get-reflective-tower-maker old-config))
    (let-fluids (structure-ref packages-internal $get-location)
		(make-cell get-variable)
		(structure-ref reading-forms $note-file-package)
		(make-cell (lambda (filename package) (values)))
      (lambda () 
	(for-each (lambda (file)
		    (load file config))
		  files)))
    (values (collect-packages (map (lambda (name)
				     (environment-ref config name))
				   struct-names)
			      (lambda (package)
				#t))
	    (let ((names '()))
	      (for-each (lambda (struct-name)
			  (let ((my-names '()))
			    (for-each-declaration
			      (lambda (name package-name type)
				(set! my-names (cons name my-names)))
			      (structure-interface
			        (environment-ref config struct-name)))
			    (set! names
				  (cons (cons struct-name my-names)
					names))))
			struct-names)
	      names)
	    (make-lookup config))))

; This creates new variables as needed for packages.

(define (get-variable package name)
  ;(format #t "Making variable ~S for ~S~%" name package)
  ((structure-ref variable make-global-variable)
     name
     (structure-ref ps-types type/unknown)))

; Return something that will find the binding of ID in the package belonging
; to the structure PACKAGE-ID in the CONFIG package.

(define (make-lookup config)
  (lambda (package-id id)
    (let ((binding (package-lookup config package-id)))
      (if (and (binding? binding)
	       (location? (binding-place binding))
	       (structure? (contents (binding-place binding))))
	  (let* ((package (structure-package
			   (contents (binding-place binding))))
		 (binding (package-lookup package id)))
	    (if (binding? binding)
		(binding-place binding)
		#f))
	  #f))))
	       
;----------------------------------------------------------------
; Handy packages and package making stuff.

(define defpackage     (structure-ref built-in-structures defpackage))
(define structure-refs (structure-ref built-in-structures structure-refs))
(define scheme         (structure-ref built-in-structures scheme))

(define (make-env-for-syntax-promise . structures)
  (make-reflective-tower eval structures 'prescheme-linking))

(define (make-very-simple-package name opens)
  (make-simple-package opens
		       eval
		       (make-env-for-syntax-promise scheme)
		       name))

(define (get-reflective-tower-maker p)
  (environment-ref p (string->symbol ".make-reflective-tower.")))

;----------------------------------------------------------------
; The following stuff is used to define the DEFINE-RECORD-TYPE macro.
; We produce a structure that exports EXPAND-DEFINE-RECORD-TYPE.  The
; base package then includes that structure in its FOR-SYNTAX package.

(define defrecord-for-syntax-package
  (make-very-simple-package 'defrecord-for-syntax-package '()))

(define defrecord-for-syntax-structure
  (make-structure defrecord-for-syntax-package
		  (lambda () (export expand-define-record-type))
		  'defrecord-for-syntax-structure))

(define (define-for-syntax-value id value)
  (let ((loc (make-new-location defrecord-for-syntax-package id)))
    (set-contents! loc value)
    (package-define! defrecord-for-syntax-package
		     id
		     (structure-ref meta-types usual-variable-type)
		     loc
		     #f)))

(define-for-syntax-value 'expand-define-record-type expand-define-record-type)

;----------------------------------------------------------------
; BASE-PACKAGE contains all of the primitives, syntax, etc. for Pre-Scheme

(define (prescheme-unbound package name)
  (bug "~S has no binding in package ~S" name package))

(define base-package
;  (let-fluid (structure-ref packages-internal $get-location) prescheme-unbound
;    (lambda () ))
  (make-simple-package '()
		       eval
		       (make-env-for-syntax-promise
			  scheme
			  defrecord-for-syntax-structure)
		       'base-package))

; Add the operators.

(let ((syntax-type (structure-ref meta-types syntax-type)))
  (for-each (lambda (id)
	      (package-define! base-package
			       id
			       syntax-type
			       #f
			       (get-operator id syntax-type)))
	    '(if begin lambda letrec quote set!
		 define define-syntax let-syntax letrec-syntax
		 ; the rest are special for Prescheme
		 goto type-case real-external)))

; Add the usual macros.

(let ((syntax-type (structure-ref meta-types syntax-type)))
  (for-each (lambda (name)
	      (package-define! base-package
			       name
			       syntax-type
			       #f
			       (make-transform
			         (usual-transform name)
				 base-package
				 (structure-ref meta-types syntax-type)
				 `(usual-transform ',name)
				 name)))
	    '(and cond do let let* or quasiquote))) ; delay

; Plus whatever primitives are wanted.

(define (define-prescheme! name location static)
  (package-define! base-package
		   name
		   (structure-ref meta-types usual-variable-type)
		   location
		   static))

; Copy over the enumeration macros and the ERRORS enumeration.

(define (import-syntax! package-id name)
  (let ((config ((structure-ref package-commands-internal config-package)))
	(syntax-type (structure-ref meta-types syntax-type)))
    (let ((binding (structure-lookup (environment-ref config package-id)
				     name
				     #t)))
      (package-define! base-package
		       name
		       syntax-type
		       (binding-place binding)
		       (binding-static binding)))))

(import-syntax! 'enumerated 'define-enumeration)
(import-syntax! 'enumerated 'enum)
(import-syntax! 'enumerated 'name->enumerand)
(import-syntax! 'enumerated 'enumerand->name)
(import-syntax! 'prescheme  'errors)
(import-syntax! 'prescheme  'define-external-enumeration)
(import-syntax! 'scheme     'syntax-rules)

; define still more syntax

(load "prescheme/ps-syntax.scm" base-package)

(eval '(define-syntax define-record-type expand-define-record-type)
      base-package)

;(eval '(define-syntax define-union-type expand-define-union-type)
;      base-package)

;----------------------------------------------------------------
; Make the Pre-Scheme structure and related structures

(define (get-interface name)
  (environment-ref ((structure-ref package-commands-internal config-package))
		   name))

(define prescheme
  (make-structure base-package
		  (lambda () (get-interface 'prescheme-interface))
		  'prescheme))

(define ps-memory
  (make-structure base-package
		  (lambda () (get-interface 'ps-memory-interface)) 
		  'ps-memory))

(define ps-flonums
  (make-structure base-package
		  (lambda () (get-interface 'ps-flonums-interface)) 
		  'ps-flonums))

(define ps-unsigned-integers
  (make-structure base-package
		  (lambda () (get-interface 'ps-unsigned-integers-interface)) 
		  'ps-unsigned-integers))

(define ps-receive
  (make-structure base-package
		  (lambda () (get-interface 'ps-receive-interface)) 
		  'ps-receive))

(define ps-record-types
  (make-structure base-package
                  (lambda () (export (define-record-type :syntax)))
                  'ps-record-types))

; and a handy environment

(define prescheme-compiler-env
  (package->environment base-package))