trac.callcc.org

root/release/3/riaxpander/standard.scm

Revision 9399, 30.8 kB (checked in by ashinn, 10 months ago)

Adding DSSSL support, updating license info.

Line 
1 ;;; -*- Mode: Scheme -*-
2
3 ;;;; Riaxpander
4 ;;;; Macrologies for Standard Syntax
5
6 ;;; Copyright (c) 2008, Taylor R. Campbell
7 ;;; See the LICENCE file for licence terms and warranty disclaimer.
8
9 (define (macrology/standard-derived-syntax)
10   (compose-macrologies
11    (macrology/standard-variable-binding)
12    (macrology/standard-boolean-connectives)
13    (macrology/standard-iteration)
14    (macrology/standard-derived-conditional)
15    (macrology/standard-quasiquote)))
16
17 (define (make-extended-classifier-macrology receiver)
18   (make-classifier-macrology
19    (lambda (*define-classifier)
20      (define (define-classifier pattern procedure)
21        (*define-classifier (car pattern)
22          (let ((predicate (pattern-predicate `(KEYWORD ,@(cdr pattern)))))
23            (lambda (form environment history)
24              (if (predicate form
25                             (lambda (name) name)
26                             (make-name-comparator environment))
27                  (procedure form environment history)
28                  (classify-error "Invalid syntax:" history form))))))
29      (receiver define-classifier))))
30
31 (define (make-expression-compiler-macrology receiver)
32   (make-extended-classifier-macrology
33    (lambda (define-classifier)
34      (define (define-expression-compiler pattern procedure)
35        (define-classifier pattern
36          (lambda (form environment history)
37            (values (make-expression (lambda ()
38                                       (procedure form environment history)))
39                    history))))
40      (receiver define-expression-compiler))))
41
42 (define (make-extended-er-macro-transformer-macrology receiver)
43   (make-er-macro-transformer-macrology
44    (lambda (*define-transformer)
45      (define (define-transformer pattern procedure auxiliary-names)
46        (*define-transformer (car pattern)
47          (let ((predicate (pattern-predicate `(KEYWORD ,@(cdr pattern)))))
48            (lambda (form rename compare)
49              (if (predicate form rename compare)
50                  (procedure form rename compare)
51                  form)))
52          auxiliary-names))
53      (receiver define-transformer))))
54
55 (define (define-expression-compiler-macrology pattern procedure)
56   (make-expression-compiler-macrology
57    (lambda (define-expression-compiler)
58      (define-expression-compiler pattern procedure))))
59
60 ;;;; Rudimentary Syntax Pattern Checking
61
62 ;;; This pattern predicate mechanism is not for use outside this file.
63 ;;; Please use a real pattern matcher instead.
64
65 ;++ Improvement:  Record the position of the subexpression
66 ;++ that went wrong, and report that in the syntax error.
67
68 (define (pattern-predicate pattern)
69   (cond ((pair? pattern)
70          (case (car pattern)
71            ((@)
72             (if (and (pair? (cdr pattern))
73                      (string? (cadr pattern))
74                      (pair? (cddr pattern))
75                      (null? (cdddr pattern)))
76                 (pattern/annotated (cadr pattern)
77                                    (pattern-predicate (caddr pattern)))
78                 (pattern-error pattern)))
79            ((? * +)
80             (if (pair? (cdr pattern))
81                 ((case (car pattern)
82                    ((?) (repeating-pattern 0 1))
83                    ((*) (repeating-pattern 0 #f))
84                    ((+) (repeating-pattern 1 #f)))
85                  (pattern-predicate (cadr pattern))
86                  (pattern-predicate (cddr pattern)))
87                 (pattern-error pattern)))
88            ((NOT)
89             (if (and (pair? (cdr pattern))
90                      (null? (cddr pattern)))
91                 (pattern/complement (cadr pattern))
92                 (pattern-error pattern)))
93            ((AND)
94             (pattern/conjunction (map pattern-predicate (cdr pattern))))
95            ((OR)
96             (pattern/disjunction (map pattern-predicate (cdr pattern))))
97            ((QUOTE)
98             (if (and (pair? (cdr pattern))
99                      (null? (cddr pattern)))
100                 (pattern/literal (cadr pattern))
101                 (pattern-error pattern)))
102            (else
103             (pattern/pair (pattern-predicate (car pattern))
104                           (pattern-predicate (cdr pattern))))))
105         ((symbol? pattern)
106          (case pattern
107            ((NAME)
108             (pattern/predicate name?))
109            ((SYMBOL)
110             (pattern/predicate symbol?))
111            ((DATUM FORM KEYWORD BVL EXPRESSION LOCATION)    ;Plugh...
112             (pattern/variable))
113            (else
114             (pattern/literal pattern))))
115         ((procedure? pattern)
116          pattern)
117         (else
118          (pattern/literal pattern))))
119
120 (define (pattern-error pattern)
121   (error "Malformed pattern:" pattern))
122
123 (define (test-pattern pattern form)
124   ((pattern-predicate pattern) form (lambda (x) x) eq?))
125
126 (define (pattern/variable)
127   (lambda (form rename compare)
128     form rename compare                 ;ignore
129     #t))
130
131 (define (pattern/annotated annotation predicate)
132   annotation                            ;ignore
133   predicate)
134
135 (define (pattern/predicate procedure)
136   (lambda (form rename compare)
137     rename compare                      ;ignore
138     (procedure form)))
139
140 (define (pattern/complement predicate)
141   (lambda (form rename compare)
142     (not (predicate form rename compare))))
143
144 (define (pattern/literal datum)
145   (if (name? datum)
146       (lambda (form rename compare)
147         (compare form (rename datum)))
148       (lambda (form rename compare)
149         rename compare                  ;ignore
150         (eqv? form datum))))
151
152 (define (pattern/pair car-predicate cdr-predicate)
153   (lambda (form rename compare)
154     (and (pair? form)
155          (car-predicate (car form) rename compare)
156          (cdr-predicate (cdr form) rename compare))))
157
158 (define (pattern/conjunction conjuncts)
159   (lambda (form rename compare)
160     (let loop ((conjuncts conjuncts))
161       (or (not (pair? conjuncts))
162           (and ((car conjuncts) form rename compare)
163                (loop (cdr conjuncts)))))))
164
165 (define (pattern/disjunction disjuncts)
166   (lambda (form rename compare)
167     (let loop ((disjuncts disjuncts))
168       (and (pair? disjuncts)
169            (or ((car disjuncts) form rename compare)
170                (loop (cdr disjuncts)))))))
171
172 (define (repeating-pattern lower upper)
173   (lambda (element-predicate tail-predicate)
174     (lambda (form rename compare)
175       (define (element? form)
176         (element-predicate form rename compare))
177       (define (tail? form)
178         (tail-predicate form rename compare))
179       (let loop ((form form) (count 0))
180         (cond ((and upper (= count upper))
181                (tail? form))
182               ((not (pair? form))
183                (and (>= count lower)
184                     (tail? form)))
185               ((element? (car form))
186                (loop (cdr form) (+ count 1)))
187               ((>= count lower)
188                (tail? form))
189               (else #f))))))
190
191 ;;;; Standard Primitive Syntax
192
193 (define (macrology/standard-assignment)
194   (define-expression-compiler-macrology '(SET! LOCATION EXPRESSION)
195     (lambda (form environment history)
196       (define (subform classifier selector cxr)
197         (receive (classification history)
198             (classifier selector (cxr form) environment history)
199           history                       ;ignore
200           classification))
201       ((location/assignment-compiler
202         (subform classify-sublocation cadr-selector cadr))
203        (subform classify-subexpression caddr-selector caddr)
204        history))))
205
206 (define (macrology/standard-conditional compiler)
207   (define-expression-compiler-macrology '(IF EXPRESSION
208                                              EXPRESSION
209                                              ? EXPRESSION)
210     (lambda (form environment history)
211       (define (subexpression selector cxr)
212         (receive (expression history)
213             (classify-subexpression selector (cxr form) environment history)
214           history                       ;ignore
215           expression))
216       (let ((condition (subexpression cadr-selector cadr))
217             (consequent (subexpression caddr-selector caddr))
218             (alternative
219              (and (pair? (cdddr form))
220                   (subexpression cadddr-selector cadddr))))
221         (compiler condition consequent alternative history)))))
222
223 (define (macrology/standard-lambda compiler lambda-bvl-mapper)
224   (define-expression-compiler-macrology '(LAMBDA BVL + FORM)
225     (lambda (form environment history)
226       (let* ((environment* (syntactic-extend environment))
227              (bvl*
228               (let ((bvl (cadr form)))
229                 (lambda-bvl-mapper
230                  bvl
231                  (history/add-subform history cadr-selector bvl environment)
232                  (lambda (name)
233                    (bind-variable! name environment*))))))
234         (syntactic-seal! environment*)
235         (compiler bvl*
236                   (make-sequence cddr-selector
237                                  (cddr form)
238                                  (syntactic-extend environment*)
239                                  history)
240                   environment*
241                   history)))))
242
243 (define (macrology/standard-quotation compiler)
244   (define-expression-compiler-macrology '(QUOTE DATUM)
245     (lambda (form environment history)
246       environment                       ;ignore
247       (compiler (syntax->datum (cadr form)) history))))
248
249 (define (macrology/standard-sequence)
250   (make-extended-classifier-macrology
251    (lambda (define-classifier)
252      (define-classifier '(BEGIN * FORM)
253        (lambda (form environment history)
254          (classify-sequence cdr-selector (cdr form) environment history))))))
255
256 ;;;; Definition Syntax
257
258 (define (macrology/standard-keyword-definition)
259   (make-extended-classifier-macrology
260    (lambda (define-classifier)
261      (define-classifier '(DEFINE-SYNTAX NAME FORM)
262        (lambda (form environment history)
263          (values (make-keyword-definition cadr-selector (cadr form)
264                                           caddr-selector (caddr form)
265                                           environment history)
266                  history))))))
267
268 (define (macrology/standard-definition)
269   (make-definition-macrology standard-definition-pattern
270                              make-variable-definition))
271
272 (define (macrology/curried-definition)
273   (make-definition-macrology curried-definition-pattern
274                              make-variable-definition))
275
276 (define (macrology/overloaded-definition)
277   (make-definition-macrology curried-definition-pattern
278                              make-overloaded-definition))
279
280 (define standard-definition-pattern
281   '(DEFINE . (OR (NAME EXPRESSION) ((NAME . BVL) + FORM))))
282
283 (define curried-definition-pattern
284   (letrec ((curried?
285             (pattern-predicate
286              `((OR NAME
287                    ,(lambda (form rename compare)
288                       (curried? form rename compare)))
289                . BVL))))
290     `(DEFINE . (OR (NAME EXPRESSION) (,curried? + FORM)))))
291
292 (define (make-definition-macrology pattern make-definition)
293   (make-extended-er-macro-transformer-macrology
294    (lambda (define-transformer)
295      (define-transformer pattern
296        (let ((definition-operator (make-definition-operator make-definition)))
297          (lambda (form rename compare)
298            compare                      ;ignore
299            (if (name? (cadr form))
300                (let ((name (cadr form))
301                      (expression (caddr form)))
302                  `(,definition-operator ,name ,expression))
303                (let ((define (car form))
304                      (name (caadr form))
305                      (lambda (rename 'LAMBDA))
306                      (bvl (cdadr form))
307                      (body (cddr form)))
308                  `(,define ,name (,lambda ,bvl ,@body))))))
309        '(LAMBDA)))))
310
311 (define (make-definition-operator make-definition)
312   (classifier->operator
313    (lambda (form environment history)
314      (values (make-definition cadr-selector (cadr form)
315                               caddr-selector (caddr form)
316                               environment history)
317              history))))
318
319 ;;;; Local Syntactic Bindings: LET-SYNTAX & LETREC-SYNTAX
320
321 ;;; This does not implement R5RS semantics, which requires that the
322 ;;; body consist only of expressions.  This does, however, implement
323 ;;; R6RS semantics, and, much as I am opposed to R6RS, I prefer its
324 ;;; LET-SYNTAX semantics.  If one wishes to introduce a new scope, one
325 ;;; can write the LET explicitly.  Implementing R5RS semantics is more
326 ;;; trouble than it's worth to do correctly.
327
328 (define (macrology/standard-syntactic-binding)
329   (make-extended-classifier-macrology
330    (lambda (define-classifier)
331
332      (define (local-syntax form environment enclosing-environment history)
333        (select-for-each cadr-selector (cadr form)
334          (lambda (selector binding)
335            (receive (keyword history)
336                (classify-subkeyword (select-car (select-cdr selector))
337                                     (cadr binding)
338                                     enclosing-environment
339                                     history)
340              history                    ;ignore
341              (syntactic-bind! environment
342                               (car binding)
343                               (keyword/denotation keyword)))))
344        (syntactic-seal! environment)
345        (classify-sequence cddr-selector (cddr form) environment history))
346
347      (define-classifier '(LET-SYNTAX (* (@ "LET-SYNTAX binding"
348                                            (NAME EXPRESSION)))
349                            + FORM)
350        (lambda (form enclosing-environment history)
351          (let ((environment (syntactic-splicing-extend enclosing-environment)))
352            (local-syntax form environment enclosing-environment history))))
353
354      (define-classifier '(LETREC-SYNTAX (* (@ "LETREC-SYNTAX binding"
355                                               (NAME EXPRESSION)))
356                            + FORM)
357        (lambda (form enclosing-environment history)
358          (let ((environment (syntactic-splicing-extend enclosing-environment)))
359            (local-syntax form environment environment history)))))))
360
361 ;;;; Local Variable Bindings: LET, LET*, & LETREC
362
363 (define (macrology/standard-variable-binding)
364   (make-extended-er-macro-transformer-macrology
365    (lambda (define-transformer)
366
367      (define-transformer '(LET . DATUM)   ;Dummy pattern.
368        (let ((unnamed-let? (pattern-predicate '((* (NAME EXPRESSION)) + FORM)))
369              (named-let?
370               (pattern-predicate '(NAME (* (NAME EXPRESSION)) + FORM))))
371          (lambda (form rename compare)
372            (cond ((unnamed-let? (cdr form) rename compare)
373                   (let ((bindings (cadr form))
374                         (body (cddr form)))
375                     (let ((variables (map car bindings))
376                           (initializers (map cadr bindings)))
377                       `((,(rename 'LAMBDA) ,variables ,@body)
378                         ,@initializers))))
379                  ((named-let? (cdr form) rename compare)
380                   (let ((name (cadr form))
381                         (bindings (caddr form))
382                         (body (cdddr form)))
383                     (let ((variables (map car bindings))
384                           (initializers (map cadr bindings)))
385                       `((,(rename 'LET) ()
386                           (,(rename 'DEFINE) (,name ,@variables)
387                             ,@body)
388                           ,name)
389                         ,@initializers))))
390                  (else form))))
391        '(DEFINE LAMBDA LET))
392
393      (define-transformer '(LET* (* (@ "LET* binding" (NAME EXPRESSION)))
394                             + FORM)
395        (lambda (form rename compare)
396          compare                        ;ignore
397          (let ((clauses (cadr form))
398                (body (cddr form)))
399            (if (not (pair? clauses))
400                `(,(rename 'LET) () ,@body)
401                (let recur ((clauses clauses))
402                  (let ((clause (car clauses))
403                        (clauses (cdr clauses)))
404                    `(,(rename 'LET) (,clause)
405                       ,@(if (pair? clauses)
406                             `(,(recur clauses))
407                             body)))))))
408        '(LET))
409
410      (define-transformer '(LETREC (* (@ "LETREC binding" (NAME EXPRESSION)))
411                             + FORM)
412        (lambda (form rename compare)
413          compare                        ;ignore
414          (let ((bindings (cadr form))
415                (body (cddr form)))
416            `(,(rename 'LET) ()
417               ,@(map (lambda (binding)
418                        (let ((variable (car binding))
419                              (initializer (cadr binding)))
420                          `(,(rename 'DEFINE) ,variable ,initializer)))
421                      bindings)
422               (,(rename 'LET) ()
423                 ,@body))))
424        '(DEFINE LET)))))
425
426 ;;;; Standard Derived Syntax
427
428 (define (macrology/standard-boolean-connectives)
429   (make-extended-er-macro-transformer-macrology
430    (lambda (define-transformer)
431
432      (define (boolean-reduction identity binary-case)
433        (lambda (form rename compare)
434          compare                        ;ignore
435          (let ((operands (cdr form)))
436            (cond ((not (pair? operands))
437                   identity)
438                  ((not (pair? (cdr operands)))
439                   (car operands))
440                  (else
441                   (binary-case rename
442                                (car operands)
443                                `(,(car form) ,@(cdr operands))))))))
444
445      (define-transformer '(AND * EXPRESSION)
446        (boolean-reduction '#T
447                           (lambda (rename a b)
448                             `(,(rename 'IF) ,a ,b #F)))
449        '(IF))
450
451      (define-transformer '(OR * EXPRESSION)
452        (boolean-reduction '#F
453                           (lambda (rename a b)
454                             `(,(rename 'LET) ((,(rename 'T) ,a))
455                                (,(rename 'IF) ,(rename 'T)
456                                  ,(rename 'T)
457                                  ,b))))
458        '(LET IF)))))
459
460 (define (macrology/standard-iteration)
461   (make-extended-er-macro-transformer-macrology
462    (lambda (define-transformer)
463      (define-transformer
464          '(DO (* (@ "DO variable clause" (NAME EXPRESSION ? EXPRESSION)))
465               (@ "DO return clause" (EXPRESSION ? EXPRESSION))
466             * FORM)
467        (lambda (form rename compare)
468          compare                        ;ignore
469          (let ((bindings (cadr form))
470                (condition (car (caddr form)))
471                (result (cdr (caddr form)))
472                (body (cdddr form)))
473            (let ((loop-variables
474                   (map (lambda (binding)
475                          `(,(car binding) ,(cadr binding)))
476                        bindings))
477                  (loop-updates
478                   (map (lambda (binding)
479                          (if (null? (cddr binding))
480                              (car binding)
481                              (caddr binding)))
482                        bindings)))
483              `(,(rename 'LET) ,(rename 'DO-LOOP) (,@loop-variables)
484                 (,(rename 'IF) ,condition
485                   (,(rename 'IF) #F #F ,@result)
486                   (,(rename 'BEGIN)
487                     ,@body
488                     (,(rename 'DO-LOOP) ,@loop-updates)))))))
489        '(BEGIN IF LET)))))
490
491 ;;;;; Standard Derived Conditional Syntax: COND & CASE
492
493 (define (macrology/standard-derived-conditional)
494   (make-extended-er-macro-transformer-macrology
495    (lambda (define-transformer)
496
497      ;;; This supports the SRFI 61 extension to `=>' clauses.
498
499      (define-transformer '(COND + (@ "COND clause" (+ EXPRESSION)))
500        (let ((else-clause? (pattern-predicate '('ELSE + EXPRESSION)))
501              (or-clause? (pattern-predicate '(EXPRESSION)))
502              (=>-clause? (pattern-predicate '(EXPRESSION '=> EXPRESSION)))
503              (=>*-clause?
504               (pattern-predicate '(EXPRESSION EXPRESSION '=> EXPRESSION))))
505          (lambda (form rename compare)
506            (call-with-syntax-error-procedure
507              (lambda (syntax-error)
508                (let recur ((selector cdr-selector) (clauses (cdr form)))
509                  (let ((clause (car clauses))
510                        (clauses* (cdr clauses))
511                        (selector* (select-cdr selector)))
512                    (define (more?) (pair? clauses*))
513                    (define (more) (recur selector* clauses*))
514                    (define (maybe-more) (if (more?) `(,(more)) '()))
515                    (cond ((else-clause? clause rename compare)
516                           (if (more?)
517                               (syntax-error "COND clauses after ELSE:"
518                                             selector*
519                                             clauses*)
520                               (let ((body (cdr clause)))
521                                 ;; Tricky pedantic case to prevent
522                                 ;; internal definitions at all costs.
523                                 `(,(rename 'IF) #T
524                                    (,(rename 'BEGIN) ,@body)))))
525                          ((or-clause? clause rename compare)
526                           (let ((expression (car clause)))
527                             (if (more?)
528                                 `(,(rename 'OR) ,expression ,(more))
529                                 ;; More pedantic tricks.
530                                 `(,(rename 'IF) #T
531                                    ,expression))))
532                          ((=>-clause? clause rename compare)
533                           (let ((producer (car clause))
534                                 (consumer (caddr clause)))
535                             `(,(rename 'LET) ((,(rename 'T) ,producer))
536                                (,(rename 'IF) ,(rename 'T)
537                                  (,consumer ,(rename 'T))
538                                  ,@(maybe-more)))))
539                          ((=>*-clause? clause rename compare)
540                           (let ((producer (car clause))
541                                 (tester (caddr clause))
542                                 (consumer (cadddr clause)))
543                             `(,(rename 'LET) ((,(rename 'T) ,producer))
544                                (,(rename 'IF)
545                                    (,(rename 'APPLY) ,tester ,(rename 'T))
546                                  (,(rename 'APPLY) ,consumer ,(rename 'T))
547                                  ,@(maybe-more)))))
548                          (else
549                           (let ((condition (car clause))
550                                 (body (cdr clause)))
551                             `(,(rename 'IF) ,condition
552                                (,(rename 'BEGIN) ,@body)
553                                ,@(maybe-more)))))))))))
554        '(APPLY BEGIN IF LET OR))
555
556      ;;; (DEFINE (MACROLOGY/STANDARD-DERIVED-CONDITIONAL) ...), continued
557
558      (define-transformer '(CASE EXPRESSION + (@ "CASE clause" (+ EXPRESSION)))
559        (let ((else-clause? (pattern-predicate '('ELSE + EXPRESSION)))
560              (case-clause? (pattern-predicate '((* DATUM) + EXPRESSION))))
561          (lambda (form rename compare)
562            (capture-syntax-error-procedure
563              (lambda (syntax-error)
564                `(,(rename 'LET) ((,(rename 'KEY) ,(cadr form)))
565                   ,(let recur ((selector cddr-selector)
566                                (clauses (cddr form)))
567                      (let ((clause (car clauses))
568                            (clauses* (cdr clauses))
569                            (selector* (select-cdr selector)))
570                        (define (more?) (pair? clauses*))
571                        (define (more) (recur selector* clauses*))
572                        (define (maybe-more) (if (more?) `(,(more)) '()))
573                        (cond ((else-clause? clause rename compare)
574                               (if (more?)
575                                   (syntax-error "CASE clauses after ELSE:"
576                                                 selector*
577                                                 clauses*)
578                                   `(,(rename 'IF) #T
579                                      (,(rename 'BEGIN) ,@(cdr clause)))))
580                              ((case-clause? clause rename compare)
581                               (let ((data (car clause))
582                                     (forms (cdr clause)))
583                                 `(,(rename 'IF)
584                                      ,(let ((compare
585                                              (lambda (datum)
586                                                `(,(rename 'EQV?)
587                                                  ,(rename 'KEY)
588                                                  (,(rename 'QUOTE) ,datum)))))
589                                         ;; Gratuitous optimization...
590                                         (cond ((not (pair? data))
591                                                '#F)
592                                               ((not (pair? (cdr data)))
593                                                (compare (car data)))
594                                               (else
595                                                `(,(rename 'OR)
596                                                  ,@(map compare data)))))
597                                    (,(rename 'BEGIN) ,@forms)
598                                    ,@(maybe-more))))
599                              (else
600                               (syntax-error "Invalid CASE clause:"
601                                             (select-car selector)
602                                             clause))))))))))
603        '(BEGIN EQV? IF LET QUOTE)))))
604
605 ;;;;; Quasiquote
606
607 (define (macrology/standard-quasiquote)
608   (make-extended-er-macro-transformer-macrology
609    (lambda (define-transformer)
610      ;++ This should check for misplaced uses of the keywords.
611      (define quasiquote? (pattern-predicate '('QUASIQUOTE DATUM)))
612      (define unquote? (pattern-predicate '('UNQUOTE DATUM)))
613      (define unquote-splicing? (pattern-predicate '('UNQUOTE-SPLICING DATUM)))
614      (define-transformer '(QUASIQUOTE DATUM)
615        (lambda (form rename compare)
616          (call-with-syntax-error-procedure
617            (lambda (syntax-error)
618              (define (qq-quote datum)
619                (list (rename 'QUOTE) datum))
620              (define (qq-cons car-expression cdr-expression)
621                (list (rename 'CONS) car-expression cdr-expression))
622              (define (qq-append list-expression tail-expression)
623                (list (rename 'APPEND) list-expression tail-expression))
624              (define (qq-list->vector list-expression)
625                (list (rename 'LIST->VECTOR) list-expression))
626              (define (qq-nest keyword template depth)
627                (list (rename 'LIST) (qq-quote keyword) (qq template depth)))
628
629              (define (qq template depth)
630                (cond ((pair? template) (qq-pair template depth))
631                      ((vector? template) (qq-vector template depth))
632                      (else (qq-quote template))))
633
634              (define (qq-pair template depth)
635                (cond ((quasiquote? template rename compare)
636                       (qq-nest 'QUASIQUOTE (cadr template) (+ depth 1)))
637                      ((unquote? template rename compare)
638                       (if (zero? depth)
639                           (cadr template)
640                           (qq-nest 'UNQUOTE (cadr template) (- depth 1))))
641                      ((unquote-splicing? template rename compare)
642                       ;++ Figure out the selector for a better report.
643                       (syntax-error "Misplaced ,@ template:" template))
644                      (else
645                       (qq-list template depth qq))))
646
647              (define (qq-vector template depth)
648                (qq-list->vector
649                 (let recur ((template (vector->list template)) (depth depth))
650                   (if (null? template)
651                       (qq-quote '())
652                       (qq-list template depth recur)))))
653
654              (define (qq-list template depth recur)
655                (let ((element (car template))
656                      (tail (cdr template)))
657                  (if (unquote-splicing? element rename compare)
658                      (if (zero? depth)
659                          (if (null? tail)
660                              (cadr element)
661                              (qq-append (cadr element) (qq tail depth)))
662                          (qq-cons (qq-nest 'UNQUOTE-SPLICING
663                                            (cadr element)
664                                            (- depth 1))
665                                   (recur tail depth)))
666                      (qq-cons (qq element depth) (recur tail depth)))))
667
668              (qq (cadr form) 0))))
669        '(APPEND CONS LIST LIST->VECTOR QUASIQUOTE QUOTE)))))
670
671 ;;;; Non-Standard Primitive Syntax
672
673 ;;; The name of the form for the variant of QUOTE that does not strip
674 ;;; syntax is not standard; there is not even a de facto standard.
675 ;;; Scheme48 calls it CODE-QUOTE; MIT Scheme calls it SYNTAX-QUOTE.
676 ;;; We therefore allow the name to be supplied.
677
678 (define (macrology/syntax-quote name compiler)
679   (make-expression-compiler-macrology
680    (lambda (define-expression-compiler)
681      (define-expression-compiler `(,name DATUM)
682        (lambda (form environment history)
683          environment                    ;ignore
684          (compiler (cadr form) history))))))
685
686 (define (macrology/non-standard-macro-transformers)
687   (make-extended-classifier-macrology
688    (lambda (define-classifier)
689
690      (define (name-list? object)
691        (if (pair? object)
692            (and (name? (car object))
693                 (name-list? (cdr object)))
694            (null? object)))
695
696      (define (define-transformer-classifier name wrapper)
697        (define-classifier `(,name EXPRESSION ? (* NAME))
698          (lambda (form environment history)
699            (let ((finish
700                   (lambda (procedure auxiliary-names)
701                     (values (make-keyword form
702                                           (make-transformer environment
703                                                             auxiliary-names
704                                                             (wrapper procedure)
705                                                             form))
706                             history)))
707                  (expression (cadr form))
708                  (auxiliary-names (if (pair? (cddr form)) (caddr form) #f)))
709              (let ((mumble (meta-evaluate expression environment)))
710                (cond ((procedure? mumble)
711                       (finish mumble auxiliary-names))
712                      ((and (pair? mumble)
713                            (procedure? (car mumble))
714                            (name-list? (cdr mumble)))
715                       (if auxiliary-names
716                           (classify-error "Multiple auxiliary name lists:"
717                                           history
718                                           (cdr mumble)
719                                           auxiliary-names)
720                           (finish (car mumble) (cdr mumble))))
721                      (else
722                       (classify-error "Invalid transformer procedure:"
723                                       history
724                                       mumble))))))))
725
726      (define-transformer-classifier 'ER-MACRO-TRANSFORMER
727        make-er-macro-transformer-procedure)
728
729      (define-transformer-classifier 'SC-MACRO-TRANSFORMER
730        make-sc-macro-transformer-procedure)
731
732      (define-transformer-classifier 'RSC-MACRO-TRANSFORMER
733        make-rsc-macro-transformer-procedure))))
Note: See TracBrowser for help on using the browser.