trac.callcc.org

root/release/3/riaxpander/classify.scm

Revision 9705, 20.2 kB (checked in by ashinn, 10 months ago)

Upstream bugfixes.

Line 
1 ;;; -*- Mode: Scheme -*-
2
3 ;;;; Riaxpander
4 ;;;; Classification
5
6 ;;; Copyright (c) 2008, Taylor R. Campbell
7 ;;; See the LICENCE file for licence terms and warranty disclaimer.
8
9 (define (classify form environment history)
10   (cond ((pair? form)
11          (classify-pair form environment history))
12         ((symbol? form)
13          (classify-name form environment history))
14         ((syntactic-closure? form)
15          (classify-syntactic-closure form environment history))
16         (else
17          ((datum-classifier environment) form environment history))))
18
19 ;;; CLASSIFY-ERROR calls RECLASSIFY if the user has supplied a
20 ;;; replacement form to classify instead.
21
22 (define (reclassify form history)
23   ;++ Should this replace the reduction instead of adding a new one?
24   (classify-reduction form
25                       (reduction/environment
26                        (history/current-reduction history))
27                       history))
28
29 (define (classify-pair pair environment history)
30   (receive (operator operator-history)
31            (classify-subform car-selector (car pair) environment history)
32     (if (keyword? operator)
33         (classify/keyword operator pair environment history)
34         (classify-combination operator operator-history
35                               pair environment history))))
36
37 (define (classify-name name environment history)
38   (cond ((syntactic-lookup environment name)
39          => (lambda (denotation)
40               (cond ((variable? denotation)
41                      ((variable-classifier environment) denotation
42                                                         name
43                                                         environment
44                                                         history))
45                     ((or (classifier? denotation)
46                          (transformer? denotation))
47                      (values (make-keyword (close-syntax name environment)
48                                            denotation)
49                              history))
50                     (else
51                      (error "Invalid denotation:" denotation
52                             name environment history)))))
53         (else
54          ((free-variable-classifier environment) name environment history))))
55
56 (define (classify-syntactic-closure form environment history)
57   (let ((form* (syntactic-closure/form form)))
58     (if (name? form*)
59         (classify-name form environment history)
60         (let ((environment*
61                (syntactic-filter (syntactic-closure/environment form)
62                                  (syntactic-closure/free-names form)
63                                  environment)))
64           (classify form*
65                     environment*
66                     (history/replace-reduction history form* environment*))))))
67
68 (define (classify/keyword keyword form environment history)
69   (let ((name (keyword/name keyword))
70         (denotation (keyword/denotation keyword)))
71     (let ((form (cons name (cdr form))))
72       (cond ((classifier? denotation)
73              (classify/classifier name denotation form environment history))
74             ((transformer? denotation)
75              (classify/transformer name denotation form environment history))
76             (else
77              (error "Invalid keyword denotation:" denotation keyword))))))
78
79 (define (classify/classifier name classifier form environment history)
80   name                                  ;ignore
81   ((classifier/procedure classifier) form environment history))
82
83 (define (classify/transformer name transformer form environment history)
84   (let ((form* (apply-transformer name transformer form environment)))
85     (if (eq? form* form)
86         (classify-error "Invalid syntax:" history form)
87         (classify-reduction form* environment history))))
88
89 (define (classify-combination operator operator-history
90                               combination environment history)
91   ((combination-classifier environment)
92    operator operator-history
93    cdr-selector (cdr combination) environment history))
94
95 (define (classify-subform selector form environment history)
96   (classify-subform* classify selector form environment history))
97
98 (define (classify-subform* classifier selector form environment history)
99   (classifier form
100               environment
101               (history/add-subform history selector form environment)))
102
103 (define (classify-subforms selector forms environment history)
104   (classify-subforms* classify selector forms environment history))
105
106 (define (classify-subforms* classifier selector forms environment history)
107   (select-map selector forms
108     (lambda (selector form)
109       (receive (classification history)
110                (classify-subform* classifier selector form environment history)
111         history                         ;ignore
112         classification))))
113
114 (define (classify-reduction form environment history)
115   (classify form environment (history/add-reduction history form environment)))
116
117 (define (guarded-classifier predicate error-message)
118   (lambda (form environment history)
119     (let loop ((classifier (lambda () (classify form environment history))))
120       (receive (classification history) (classifier)
121         (if (predicate classification)
122             (values classification history)
123             (loop
124              (lambda ()
125                (classify-error error-message history classification))))))))
126
127 ;;;; Classification Utilities
128
129 ;;; We could simplify this page with macros, if we allowed ourselves
130 ;;; to use macros.
131
132 (define classify-expression
133   (guarded-classifier (lambda (classification) (expression? classification))
134                       "Non-expression in expression context:"))
135
136 (define (classify-subexpression selector form environment history)
137   (classify-subform* classify-expression selector form environment history))
138
139 (define (classify-subexpressions selector forms environment history)
140   (classify-subforms* classify-expression selector forms environment history))
141
142 (define classify-definition
143   (guarded-classifier (lambda (classification) (definition? classification))
144                       "Non-definition in definition context:"))
145
146 (define (classify-subdefinition selector form environment history)
147   (classify-subform* classify-definition selector form environment history))
148
149 (define (classify-subdefinitions selector forms environment history)
150   (classify-subforms* classify-definition selector forms environment history))
151
152 (define classify-location
153   (guarded-classifier (lambda (classification) (location? classification))
154                       "Non-location in location context:"))
155
156 (define (classify-sublocation selector form environment history)
157   (classify-subform* classify-location selector form environment history))
158
159 (define (classify-sublocations selector forms environment history)
160   (classify-subforms* classify-location selector forms environment history))
161
162 (define classify-keyword
163   (guarded-classifier (lambda (classification) (keyword? classification))
164                       "Non-keyword in keyword context:"))
165
166 (define (classify-subkeyword selector form environment history)
167   (classify-subform* classify-keyword selector form environment history))
168
169 (define (classify-subkeywords selector forms environment history)
170   (classify-subforms* classify-keyword selector forms environment history))
171
172 ;;;; Temporary Classifiers
173
174 ;;; These must be extremely careful only to generate aliases for
175 ;;; syntactic bindings, never for variables!  They must be gone in the
176 ;;; expander's output, because we have no way to find them after the
177 ;;; expander is finished, since these keywords are entirely anonymous.
178
179 (define (keyword-denotation->operator denotation)
180   (close-syntax 'KEYWORD
181                 (let ((environment
182                        (syntactic-extend (null-syntactic-environment #f))))
183                   (syntactic-bind! environment 'KEYWORD denotation)
184                   environment)))
185
186 (define (classifier->operator procedure)
187   (keyword-denotation->operator (make-classifier #f procedure)))
188
189 (define (classifier->form procedure)
190   `(,(classifier->operator procedure)))
191
192 (define (transformer->operator environment auxiliary-names procedure)
193   (keyword-denotation->operator
194    (make-transformer environment auxiliary-names procedure #f)))
195
196 (define (transformer->form environment auxiliary-names procedure)
197   `(,(transformer->operator environment auxiliary-names procedure)))
198
199 (define (capture-syntactic-environment receiver)
200   (classifier->form
201    (lambda (form environment history)
202      form                               ;ignore
203      (classify-reduction (receiver environment) environment history))))
204
205 (define (capture-expansion-history receiver)
206   (classifier->form
207    (lambda (form environment history)
208      form                               ;ignore
209      (classify-reduction (receiver history) environment history))))
210
211 ;;; These names are backwards, but this is compatible with MIT Scheme.
212
213 (define (call-with-syntax-error-procedure receiver)
214   (capture-expansion-history
215    (lambda (history)
216      (receiver
217       (lambda (message . irritants)
218         (apply syntax-error message history
219                (and history
220                     (reduction/form (history/current-reduction history)))
221                irritants))))))
222
223 (define (capture-syntax-error-procedure receiver)
224   (classifier->form
225    (lambda (form environment history)
226      form                               ;ignore
227      (classify-reduction
228       (receiver
229        (lambda (message selector form . irritants)
230          (apply syntax-error
231                 message
232                 (history/add-subform history selector form environment)
233                 form
234                 irritants)))
235       environment
236       history))))
237
238 ;;;; Sequence Scanning
239
240 (define (classify-sequence selector forms environment history)
241   (if (and (pair? forms) (null? (cdr forms)))
242       (classify-subform (select-car selector) (car forms) environment history)
243       (values (make-sequence selector forms environment history) history)))
244
245 (define (classify/sequence scanner sequence)
246   (scanner (sequence/selector sequence)
247            (sequence/forms sequence)
248            (sequence/environment sequence)
249            (sequence/history sequence)))
250
251 (define (scan-expression expression environment)
252   environment
253   (list expression))
254
255 (define (scan-definition definition environment)
256   ((definition/scanner definition) environment))
257
258 (define (scan-top-level selector forms environment history)
259   (let loop ((selector selector) (forms forms) (result '()))
260     (if (pair? forms)
261         (loop (select-cdr selector)
262               (cdr forms)
263               (append-reverse (scan-top-level-form (select-car selector)
264                                                    (car forms)
265                                                    environment
266                                                    history)
267                               result))
268         (reverse result))))
269
270 (define (scan-top-level-form selector form environment history)
271   (let loop ((classifier
272               (lambda ()
273                 (classify-subform selector form environment history))))
274     (receive (classification history) (classifier)
275       (cond ((sequence? classification)
276              (classify/sequence scan-top-level classification))
277             ((definition? classification)
278              (scan-definition classification environment))
279             ((expression? classification)
280              (scan-expression classification environment))
281             (else
282              (loop (lambda ()
283                      (classify-error "Invalid top-level form:"
284                                      history
285                                      form))))))))
286
287 ;;;;; Homogeneous Sequences
288
289 (define (homogeneous-sequence-scanner predicate sequent-scanner error-message)
290   (define (scan-sequent selector form environment history)
291     (let loop ((classifier
292                 (lambda ()
293                   (classify-subform selector form environment history))))
294       (receive (classification history) (classifier)
295         (cond ((sequence? classification)
296                (classify/sequence scan-sequence classification))
297               ((predicate classification)
298                (sequent-scanner classification environment))
299               (else
300                (loop
301                 (lambda ()
302                   (classify-error error-message history classification))))))))
303   (define (scan-sequence selector forms environment history)
304     (let loop ((selector selector) (forms forms) (history history) (items '()))
305       (if (pair? forms)
306           (loop (select-cdr selector)
307                 (cdr forms)
308                 history
309                 (append-reverse (scan-sequent (select-car selector)
310                                               (car forms)
311                                               environment
312                                               history)
313                                 items))
314           (reverse items))))
315   scan-sequence)
316
317 (define scan-expressions
318   (homogeneous-sequence-scanner expression?
319                                 scan-expression
320                                 "Non-expression in expression sequence:"))
321
322 (define scan-definitions
323   (homogeneous-sequence-scanner definition?
324                                 scan-definition
325                                 "Non-definition in definition sequence:"))
326
327 ;;;;; R5RS Internal Definitions
328
329 ;++ This should report better errors about bodies with no expressions.
330
331 (define (scan-r5rs-body selector forms environment history)
332   (let loop ((selector selector) (forms forms) (bindings '()))
333     (if (pair? forms)
334         ((scan-r5rs-body-form (select-car selector)
335                               (car forms)
336                               environment
337                               history)
338          (lambda ()                     ;if-empty
339            (loop (select-cdr selector) (cdr forms) bindings))
340          (lambda (bindings*)            ;if-definitions
341            (loop (select-cdr selector)
342                  (cdr forms)
343                  (append-reverse bindings* bindings)))
344          (lambda (expressions)          ;if-expressions
345            (values (reverse bindings)
346                    (append expressions
347                            (scan-expressions (select-cdr selector)
348                                              (cdr forms)
349                                              environment
350                                              history)))))
351         (error "Body sequence contains no expressions!" history))))
352
353 (define (scan-r5rs-body-form selector form environment history)
354   (lambda (if-empty if-definitions if-expressions)
355     (let loop ((classifier
356                 (lambda ()
357                   (classify-subform selector form environment history))))
358       (receive (classification history) (classifier)
359         (cond ((sequence? classification)
360                ((classify/sequence scan-r5rs-subsequence classification)
361                 if-empty if-definitions if-expressions))
362               ((definition? classification)
363                (if-definitions (scan-definition classification environment)))
364               ((expression? classification)
365                (if-expressions (scan-expression classification environment)))
366               (else
367                (loop (lambda ()
368                        (classify-error "Invalid sequence element:"
369                                        history
370                                        classification)))))))))
371
372 (define (scan-r5rs-subsequence selector forms environment history)
373   (lambda (if-empty if-definitions if-expressions)
374     (let loop ((selector selector) (forms forms))
375       (define (scan scanner)
376         (scanner (select-cdr selector) (cdr forms) environment history))
377       (if (pair? forms)
378           ((scan-r5rs-body-form (select-car selector)
379                                 (car forms)
380                                 environment
381                                 history)
382            (lambda ()
383              (loop (select-cdr selector) (cdr forms)))
384            (lambda (definitions)
385              (if-definitions (append definitions (scan scan-definitions))))
386            (lambda (expressions)
387              (if-expressions (append expressions (scan scan-expressions)))))
388           (if-empty)))))
389
390 ;;;;; R6RS Internal Definitions
391
392 ;;; The difference between R5RS bodies and R6RS bodies is whether the
393 ;;; boundary between expressions and definitions may occur within an
394 ;;; internal sequence.  The R5RS forbids (BEGIN <definition> ...
395 ;;; <expression> ...), whereas the R6RS permits it.
396
397 (define (scan-r6rs-body selector forms environment history)
398   (receive (bindings expressions)
399       (scan-r6rs-subsequence selector forms environment history)
400     (if (pair? expressions)
401         (values bindings expressions)
402         (error "Body sequence contains no expressions!" history))))
403
404 (define (scan-r6rs-subsequence selector forms environment history)
405   (let loop ((selector selector) (forms forms) (bindings '()))
406     (if (pair? forms)
407         (receive (bindings* expressions)
408             (scan-r6rs-body-form (select-car selector)
409                                  (car forms)
410                                  environment
411                                  history)
412           (let ((bindings** (append-reverse bindings* bindings)))
413             (if (pair? expressions)
414                 (values (reverse bindings**)
415                         (append expressions
416                                 (scan-expressions (select-cdr selector)
417                                                   (cdr forms)
418                                                   environment
419                                                   history)))
420                 (loop (select-cdr selector)
421                       (cdr forms)
422                       bindings**))))
423         (values (reverse bindings) '()))))
424
425 (define (scan-r6rs-body-form selector form environment history)
426   (let loop ((classifier
427               (lambda ()
428                 (classify-subform selector form environment history))))
429     (receive (classification history) (classifier)
430       (cond ((sequence? classification)
431              (classify/sequence scan-r6rs-subsequence classification))
432             ((definition? classification)
433              (values (scan-definition classification environment) '()))
434             ((expression? classification)
435              (values '() (scan-expression classification environment)))
436             (else
437              (loop (lambda ()
438                        (classify-error "Invalid sequence element:"
439                                        history
440                                        classification))))))))
441
442 ;;;; Definitions
443
444 (define (make-variable-definition name-selector name form-selector form
445                                   environment history)
446   name-selector                         ;ignore
447   (make-definition
448    (lambda (definition-environment)
449      (variable-binding name definition-environment
450        (lambda ()
451          (classify-subexpression form-selector form environment history))))))
452
453 (define (variable-binding name environment classifier)
454   (list
455    (make-binding (bind-variable! name environment) environment classifier)))
456
457 (define (make-keyword-definition name-selector name form-selector form
458                                  environment history)
459   name-selector                         ;ignore
460   (make-definition
461    (lambda (definition-environment)
462      (receive (keyword keyword-history)
463               (classify-subkeyword form-selector form environment history)
464        keyword-history                  ;ignore
465        (keyword-binding name definition-environment keyword)))))
466
467 (define (keyword-binding name environment keyword)
468   (syntactic-bind! environment name (keyword/denotation keyword))
469   '())
470
471 (define (make-overloaded-definition name-selector name form-selector form
472                                     environment history)
473   name-selector                         ;ignore
474   (make-definition
475    (lambda (definition-environment)
476      (let loop ((classifier
477                  (lambda ()
478                    (classify-subform form-selector form environment history))))
479        (receive (classification history) (classifier)
480          (cond ((keyword? classification)
481                 (keyword-binding name definition-environment classification))
482                ((expression? classification)
483                 (variable-binding name definition-environment
484                                   (lambda ()
485                                     (values classification history))))
486                (else
487                 (loop
488                  (lambda ()
489                    (classify-error "Invalid right-hand side of definition:"
490                                    history
491                                    classification))))))))))
Note: See TracBrowser for help on using the browser.