Merge remote-tracking branch 'origin/stable-2.0'
[bpt/guile.git] / module / ice-9 / psyntax.scm
1 ;;;; -*-scheme-*-
2 ;;;;
3 ;;;; Copyright (C) 2001, 2003, 2006, 2009, 2010, 2011,
4 ;;;; 2012 Free Software Foundation, Inc.
5 ;;;;
6 ;;;; This library is free software; you can redistribute it and/or
7 ;;;; modify it under the terms of the GNU Lesser General Public
8 ;;;; License as published by the Free Software Foundation; either
9 ;;;; version 3 of the License, or (at your option) any later version.
10 ;;;;
11 ;;;; This library is distributed in the hope that it will be useful,
12 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ;;;; Lesser General Public License for more details.
15 ;;;;
16 ;;;; You should have received a copy of the GNU Lesser General Public
17 ;;;; License along with this library; if not, write to the Free Software
18 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 ;;;;
20 \f
21
22 ;;; Portable implementation of syntax-case
23 ;;; Originally extracted from Chez Scheme Version 5.9f
24 ;;; Authors: R. Kent Dybvig, Oscar Waddell, Bob Hieb, Carl Bruggeman
25
26 ;;; Copyright (c) 1992-1997 Cadence Research Systems
27 ;;; Permission to copy this software, in whole or in part, to use this
28 ;;; software for any lawful purpose, and to redistribute this software
29 ;;; is granted subject to the restriction that all copies made of this
30 ;;; software must include this copyright notice in full. This software
31 ;;; is provided AS IS, with NO WARRANTY, EITHER EXPRESS OR IMPLIED,
32 ;;; INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY
33 ;;; OR FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE
34 ;;; AUTHORS BE LIABLE FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES OF ANY
35 ;;; NATURE WHATSOEVER.
36
37 ;;; Modified by Mikael Djurfeldt <djurfeldt@nada.kth.se> according
38 ;;; to the ChangeLog distributed in the same directory as this file:
39 ;;; 1997-08-19, 1997-09-03, 1997-09-10, 2000-08-13, 2000-08-24,
40 ;;; 2000-09-12, 2001-03-08
41
42 ;;; Modified by Andy Wingo <wingo@pobox.com> according to the Git
43 ;;; revision control logs corresponding to this file: 2009, 2010.
44
45
46 ;;; This file defines the syntax-case expander, macroexpand, and a set
47 ;;; of associated syntactic forms and procedures. Of these, the
48 ;;; following are documented in The Scheme Programming Language,
49 ;;; Fourth Edition (R. Kent Dybvig, MIT Press, 2009), and in the
50 ;;; R6RS:
51 ;;;
52 ;;; bound-identifier=?
53 ;;; datum->syntax
54 ;;; define-syntax
55 ;;; syntax-parameterize
56 ;;; free-identifier=?
57 ;;; generate-temporaries
58 ;;; identifier?
59 ;;; identifier-syntax
60 ;;; let-syntax
61 ;;; letrec-syntax
62 ;;; syntax
63 ;;; syntax-case
64 ;;; syntax->datum
65 ;;; syntax-rules
66 ;;; with-syntax
67 ;;;
68 ;;; Additionally, the expander provides definitions for a number of core
69 ;;; Scheme syntactic bindings, such as `let', `lambda', and the like.
70
71 ;;; The remaining exports are listed below:
72 ;;;
73 ;;; (macroexpand datum)
74 ;;; if datum represents a valid expression, macroexpand returns an
75 ;;; expanded version of datum in a core language that includes no
76 ;;; syntactic abstractions. The core language includes begin,
77 ;;; define, if, lambda, letrec, quote, and set!.
78 ;;; (eval-when situations expr ...)
79 ;;; conditionally evaluates expr ... at compile-time or run-time
80 ;;; depending upon situations (see the Chez Scheme System Manual,
81 ;;; Revision 3, for a complete description)
82 ;;; (syntax-violation who message form [subform])
83 ;;; used to report errors found during expansion
84 ;;; ($sc-dispatch e p)
85 ;;; used by expanded code to handle syntax-case matching
86
87 ;;; This file is shipped along with an expanded version of itself,
88 ;;; psyntax-pp.scm, which is loaded when psyntax.scm has not yet been
89 ;;; compiled. In this way, psyntax bootstraps off of an expanded
90 ;;; version of itself.
91
92 ;;; This implementation of the expander sometimes uses syntactic
93 ;;; abstractions when procedural abstractions would suffice. For
94 ;;; example, we define top-wrap and top-marked? as
95 ;;;
96 ;;; (define-syntax top-wrap (identifier-syntax '((top))))
97 ;;; (define-syntax top-marked?
98 ;;; (syntax-rules ()
99 ;;; ((_ w) (memq 'top (wrap-marks w)))))
100 ;;;
101 ;;; rather than
102 ;;;
103 ;;; (define top-wrap '((top)))
104 ;;; (define top-marked?
105 ;;; (lambda (w) (memq 'top (wrap-marks w))))
106 ;;;
107 ;;; On the other hand, we don't do this consistently; we define
108 ;;; make-wrap, wrap-marks, and wrap-subst simply as
109 ;;;
110 ;;; (define make-wrap cons)
111 ;;; (define wrap-marks car)
112 ;;; (define wrap-subst cdr)
113 ;;;
114 ;;; In Chez Scheme, the syntactic and procedural forms of these
115 ;;; abstractions are equivalent, since the optimizer consistently
116 ;;; integrates constants and small procedures. This will be true of
117 ;;; Guile as well, once we implement a proper inliner.
118
119
120 ;;; Implementation notes:
121
122 ;;; Objects with no standard print syntax, including objects containing
123 ;;; cycles and syntax object, are allowed in quoted data as long as they
124 ;;; are contained within a syntax form or produced by datum->syntax.
125 ;;; Such objects are never copied.
126
127 ;;; All identifiers that don't have macro definitions and are not bound
128 ;;; lexically are assumed to be global variables.
129
130 ;;; Top-level definitions of macro-introduced identifiers are allowed.
131 ;;; This may not be appropriate for implementations in which the
132 ;;; model is that bindings are created by definitions, as opposed to
133 ;;; one in which initial values are assigned by definitions.
134
135 ;;; Identifiers and syntax objects are implemented as vectors for
136 ;;; portability. As a result, it is possible to "forge" syntax objects.
137
138 ;;; The implementation of generate-temporaries assumes that it is
139 ;;; possible to generate globally unique symbols (gensyms).
140
141 ;;; The source location associated with incoming expressions is tracked
142 ;;; via the source-properties mechanism, a weak map from expression to
143 ;;; source information. At times the source is separated from the
144 ;;; expression; see the note below about "efficiency and confusion".
145
146
147 ;;; Bootstrapping:
148
149 ;;; When changing syntax-object representations, it is necessary to support
150 ;;; both old and new syntax-object representations in id-var-name. It
151 ;;; should be sufficient to recognize old representations and treat
152 ;;; them as not lexically bound.
153
154
155
156 (eval-when (compile)
157 (set-current-module (resolve-module '(guile))))
158
159 (let ()
160 (define-syntax define-expansion-constructors
161 (lambda (x)
162 (syntax-case x ()
163 ((_)
164 (let lp ((n 0) (out '()))
165 (if (< n (vector-length %expanded-vtables))
166 (lp (1+ n)
167 (let* ((vtable (vector-ref %expanded-vtables n))
168 (stem (struct-ref vtable (+ vtable-offset-user 0)))
169 (fields (struct-ref vtable (+ vtable-offset-user 2)))
170 (sfields (map (lambda (f) (datum->syntax x f)) fields))
171 (ctor (datum->syntax x (symbol-append 'make- stem))))
172 (cons #`(define (#,ctor #,@sfields)
173 (make-struct (vector-ref %expanded-vtables #,n) 0
174 #,@sfields))
175 out)))
176 #`(begin #,@(reverse out))))))))
177
178 (define-syntax define-expansion-accessors
179 (lambda (x)
180 (syntax-case x ()
181 ((_ stem field ...)
182 (let lp ((n 0))
183 (let ((vtable (vector-ref %expanded-vtables n))
184 (stem (syntax->datum #'stem)))
185 (if (eq? (struct-ref vtable (+ vtable-offset-user 0)) stem)
186 #`(begin
187 (define (#,(datum->syntax x (symbol-append stem '?)) x)
188 (and (struct? x)
189 (eq? (struct-vtable x)
190 (vector-ref %expanded-vtables #,n))))
191 #,@(map
192 (lambda (f)
193 (let ((get (datum->syntax x (symbol-append stem '- f)))
194 (set (datum->syntax x (symbol-append 'set- stem '- f '!)))
195 (idx (list-index (struct-ref vtable
196 (+ vtable-offset-user 2))
197 f)))
198 #`(begin
199 (define (#,get x)
200 (struct-ref x #,idx))
201 (define (#,set x v)
202 (struct-set! x #,idx v)))))
203 (syntax->datum #'(field ...))))
204 (lp (1+ n)))))))))
205
206 (define-syntax define-structure
207 (lambda (x)
208 (define construct-name
209 (lambda (template-identifier . args)
210 (datum->syntax
211 template-identifier
212 (string->symbol
213 (apply string-append
214 (map (lambda (x)
215 (if (string? x)
216 x
217 (symbol->string (syntax->datum x))))
218 args))))))
219 (syntax-case x ()
220 ((_ (name id1 ...))
221 (and-map identifier? #'(name id1 ...))
222 (with-syntax
223 ((constructor (construct-name #'name "make-" #'name))
224 (predicate (construct-name #'name #'name "?"))
225 ((access ...)
226 (map (lambda (x) (construct-name x #'name "-" x))
227 #'(id1 ...)))
228 ((assign ...)
229 (map (lambda (x)
230 (construct-name x "set-" #'name "-" x "!"))
231 #'(id1 ...)))
232 (structure-length
233 (+ (length #'(id1 ...)) 1))
234 ((index ...)
235 (let f ((i 1) (ids #'(id1 ...)))
236 (if (null? ids)
237 '()
238 (cons i (f (+ i 1) (cdr ids)))))))
239 #'(begin
240 (define constructor
241 (lambda (id1 ...)
242 (vector 'name id1 ... )))
243 (define predicate
244 (lambda (x)
245 (and (vector? x)
246 (= (vector-length x) structure-length)
247 (eq? (vector-ref x 0) 'name))))
248 (define access
249 (lambda (x)
250 (vector-ref x index)))
251 ...
252 (define assign
253 (lambda (x update)
254 (vector-set! x index update)))
255 ...))))))
256
257 (let ()
258 (define-expansion-constructors)
259 (define-expansion-accessors lambda meta)
260
261 ;; hooks to nonportable run-time helpers
262 (begin
263 (define-syntax fx+ (identifier-syntax +))
264 (define-syntax fx- (identifier-syntax -))
265 (define-syntax fx= (identifier-syntax =))
266 (define-syntax fx< (identifier-syntax <))
267
268 (define top-level-eval-hook
269 (lambda (x mod)
270 (primitive-eval x)))
271
272 (define local-eval-hook
273 (lambda (x mod)
274 (primitive-eval x)))
275
276 (define-syntax-rule (gensym-hook)
277 (gensym))
278
279 (define put-global-definition-hook
280 (lambda (symbol type val)
281 (module-define! (current-module)
282 symbol
283 (make-syntax-transformer symbol type val))))
284
285 (define get-global-definition-hook
286 (lambda (symbol module)
287 (if (and (not module) (current-module))
288 (warn "module system is booted, we should have a module" symbol))
289 (let ((v (module-variable (if module
290 (resolve-module (cdr module))
291 (current-module))
292 symbol)))
293 (and v (variable-bound? v)
294 (let ((val (variable-ref v)))
295 (and (macro? val) (macro-type val)
296 (cons (macro-type val)
297 (macro-binding val)))))))))
298
299
300 (define (decorate-source e s)
301 (if (and (pair? e) s)
302 (set-source-properties! e s))
303 e)
304
305 (define (maybe-name-value! name val)
306 (if (lambda? val)
307 (let ((meta (lambda-meta val)))
308 (if (not (assq 'name meta))
309 (set-lambda-meta! val (acons 'name name meta))))))
310
311 ;; output constructors
312 (define build-void
313 (lambda (source)
314 (make-void source)))
315
316 (define build-call
317 (lambda (source fun-exp arg-exps)
318 (make-call source fun-exp arg-exps)))
319
320 (define build-conditional
321 (lambda (source test-exp then-exp else-exp)
322 (make-conditional source test-exp then-exp else-exp)))
323
324 (define build-dynlet
325 (lambda (source fluids vals body)
326 (make-dynlet source fluids vals body)))
327
328 (define build-lexical-reference
329 (lambda (type source name var)
330 (make-lexical-ref source name var)))
331
332 (define build-lexical-assignment
333 (lambda (source name var exp)
334 (maybe-name-value! name exp)
335 (make-lexical-set source name var exp)))
336
337 (define (analyze-variable mod var modref-cont bare-cont)
338 (if (not mod)
339 (bare-cont var)
340 (let ((kind (car mod))
341 (mod (cdr mod)))
342 (case kind
343 ((public) (modref-cont mod var #t))
344 ((private) (if (not (equal? mod (module-name (current-module))))
345 (modref-cont mod var #f)
346 (bare-cont var)))
347 ((bare) (bare-cont var))
348 ((hygiene) (if (and (not (equal? mod (module-name (current-module))))
349 (module-variable (resolve-module mod) var))
350 (modref-cont mod var #f)
351 (bare-cont var)))
352 (else (syntax-violation #f "bad module kind" var mod))))))
353
354 (define build-global-reference
355 (lambda (source var mod)
356 (analyze-variable
357 mod var
358 (lambda (mod var public?)
359 (make-module-ref source mod var public?))
360 (lambda (var)
361 (make-toplevel-ref source var)))))
362
363 (define build-global-assignment
364 (lambda (source var exp mod)
365 (maybe-name-value! var exp)
366 (analyze-variable
367 mod var
368 (lambda (mod var public?)
369 (make-module-set source mod var public? exp))
370 (lambda (var)
371 (make-toplevel-set source var exp)))))
372
373 (define build-global-definition
374 (lambda (source var exp)
375 (maybe-name-value! var exp)
376 (make-toplevel-define source var exp)))
377
378 (define build-simple-lambda
379 (lambda (src req rest vars meta exp)
380 (make-lambda src
381 meta
382 ;; hah, a case in which kwargs would be nice.
383 (make-lambda-case
384 ;; src req opt rest kw inits vars body else
385 src req #f rest #f '() vars exp #f))))
386
387 (define build-case-lambda
388 (lambda (src meta body)
389 (make-lambda src meta body)))
390
391 (define build-lambda-case
392 ;; req := (name ...)
393 ;; opt := (name ...) | #f
394 ;; rest := name | #f
395 ;; kw := (allow-other-keys? (keyword name var) ...) | #f
396 ;; inits: (init ...)
397 ;; vars: (sym ...)
398 ;; vars map to named arguments in the following order:
399 ;; required, optional (positional), rest, keyword.
400 ;; the body of a lambda: anything, already expanded
401 ;; else: lambda-case | #f
402 (lambda (src req opt rest kw inits vars body else-case)
403 (make-lambda-case src req opt rest kw inits vars body else-case)))
404
405 (define build-primcall
406 (lambda (src name args)
407 (make-primcall src name args)))
408
409 (define build-primref
410 (lambda (src name)
411 (make-primitive-ref src name)))
412
413 (define (build-data src exp)
414 (make-const src exp))
415
416 (define build-sequence
417 (lambda (src exps)
418 (if (null? (cdr exps))
419 (car exps)
420 (make-seq src (car exps) (build-sequence #f (cdr exps))))))
421
422 (define build-let
423 (lambda (src ids vars val-exps body-exp)
424 (for-each maybe-name-value! ids val-exps)
425 (if (null? vars)
426 body-exp
427 (make-let src ids vars val-exps body-exp))))
428
429 (define build-named-let
430 (lambda (src ids vars val-exps body-exp)
431 (let ((f (car vars))
432 (f-name (car ids))
433 (vars (cdr vars))
434 (ids (cdr ids)))
435 (let ((proc (build-simple-lambda src ids #f vars '() body-exp)))
436 (maybe-name-value! f-name proc)
437 (for-each maybe-name-value! ids val-exps)
438 (make-letrec
439 src #f
440 (list f-name) (list f) (list proc)
441 (build-call src (build-lexical-reference 'fun src f-name f)
442 val-exps))))))
443
444 (define build-letrec
445 (lambda (src in-order? ids vars val-exps body-exp)
446 (if (null? vars)
447 body-exp
448 (begin
449 (for-each maybe-name-value! ids val-exps)
450 (make-letrec src in-order? ids vars val-exps body-exp)))))
451
452
453 ;; FIXME: use a faster gensym
454 (define-syntax-rule (build-lexical-var src id)
455 (gensym (string-append (symbol->string id) " ")))
456
457 (define-structure (syntax-object expression wrap module))
458
459 (define-syntax no-source (identifier-syntax #f))
460
461 (define source-annotation
462 (lambda (x)
463 (cond
464 ((syntax-object? x)
465 (source-annotation (syntax-object-expression x)))
466 ((pair? x) (let ((props (source-properties x)))
467 (if (pair? props)
468 props
469 #f)))
470 (else #f))))
471
472 (define-syntax-rule (arg-check pred? e who)
473 (let ((x e))
474 (if (not (pred? x)) (syntax-violation who "invalid argument" x))))
475
476 ;; compile-time environments
477
478 ;; wrap and environment comprise two level mapping.
479 ;; wrap : id --> label
480 ;; env : label --> <element>
481
482 ;; environments are represented in two parts: a lexical part and a global
483 ;; part. The lexical part is a simple list of associations from labels
484 ;; to bindings. The global part is implemented by
485 ;; {put,get}-global-definition-hook and associates symbols with
486 ;; bindings.
487
488 ;; global (assumed global variable) and displaced-lexical (see below)
489 ;; do not show up in any environment; instead, they are fabricated by
490 ;; resolve-identifier when it finds no other bindings.
491
492 ;; <environment> ::= ((<label> . <binding>)*)
493
494 ;; identifier bindings include a type and a value
495
496 ;; <binding> ::= (macro . <procedure>) macros
497 ;; (syntax-parameter . (<procedure>)) syntax parameters
498 ;; (core . <procedure>) core forms
499 ;; (module-ref . <procedure>) @ or @@
500 ;; (begin) begin
501 ;; (define) define
502 ;; (define-syntax) define-syntax
503 ;; (define-syntax-parameter) define-syntax-parameter
504 ;; (local-syntax . rec?) let-syntax/letrec-syntax
505 ;; (eval-when) eval-when
506 ;; (syntax . (<var> . <level>)) pattern variables
507 ;; (global) assumed global variable
508 ;; (lexical . <var>) lexical variables
509 ;; (displaced-lexical) displaced lexicals
510 ;; <level> ::= <nonnegative integer>
511 ;; <var> ::= variable returned by build-lexical-var
512
513 ;; a macro is a user-defined syntactic-form. a core is a
514 ;; system-defined syntactic form. begin, define, define-syntax,
515 ;; define-syntax-parameter, and eval-when are treated specially
516 ;; since they are sensitive to whether the form is at top-level and
517 ;; (except for eval-when) can denote valid internal definitions.
518
519 ;; a pattern variable is a variable introduced by syntax-case and can
520 ;; be referenced only within a syntax form.
521
522 ;; any identifier for which no top-level syntax definition or local
523 ;; binding of any kind has been seen is assumed to be a global
524 ;; variable.
525
526 ;; a lexical variable is a lambda- or letrec-bound variable.
527
528 ;; a displaced-lexical identifier is a lexical identifier removed from
529 ;; it's scope by the return of a syntax object containing the identifier.
530 ;; a displaced lexical can also appear when a letrec-syntax-bound
531 ;; keyword is referenced on the rhs of one of the letrec-syntax clauses.
532 ;; a displaced lexical should never occur with properly written macros.
533
534 (define-syntax make-binding
535 (syntax-rules (quote)
536 ((_ type value) (cons type value))
537 ((_ 'type) '(type))
538 ((_ type) (cons type '()))))
539 (define-syntax-rule (binding-type x)
540 (car x))
541 (define-syntax-rule (binding-value x)
542 (cdr x))
543
544 (define-syntax null-env (identifier-syntax '()))
545
546 (define extend-env
547 (lambda (labels bindings r)
548 (if (null? labels)
549 r
550 (extend-env (cdr labels) (cdr bindings)
551 (cons (cons (car labels) (car bindings)) r)))))
552
553 (define extend-var-env
554 ;; variant of extend-env that forms "lexical" binding
555 (lambda (labels vars r)
556 (if (null? labels)
557 r
558 (extend-var-env (cdr labels) (cdr vars)
559 (cons (cons (car labels) (make-binding 'lexical (car vars))) r)))))
560
561 ;; we use a "macros only" environment in expansion of local macro
562 ;; definitions so that their definitions can use local macros without
563 ;; attempting to use other lexical identifiers.
564 (define macros-only-env
565 (lambda (r)
566 (if (null? r)
567 '()
568 (let ((a (car r)))
569 (if (memq (cadr a) '(macro syntax-parameter))
570 (cons a (macros-only-env (cdr r)))
571 (macros-only-env (cdr r)))))))
572
573 (define global-extend
574 (lambda (type sym val)
575 (put-global-definition-hook sym type val)))
576
577
578 ;; Conceptually, identifiers are always syntax objects. Internally,
579 ;; however, the wrap is sometimes maintained separately (a source of
580 ;; efficiency and confusion), so that symbols are also considered
581 ;; identifiers by id?. Externally, they are always wrapped.
582
583 (define nonsymbol-id?
584 (lambda (x)
585 (and (syntax-object? x)
586 (symbol? (syntax-object-expression x)))))
587
588 (define id?
589 (lambda (x)
590 (cond
591 ((symbol? x) #t)
592 ((syntax-object? x) (symbol? (syntax-object-expression x)))
593 (else #f))))
594
595 (define-syntax-rule (id-sym-name e)
596 (let ((x e))
597 (if (syntax-object? x)
598 (syntax-object-expression x)
599 x)))
600
601 (define id-sym-name&marks
602 (lambda (x w)
603 (if (syntax-object? x)
604 (values
605 (syntax-object-expression x)
606 (join-marks (wrap-marks w) (wrap-marks (syntax-object-wrap x))))
607 (values x (wrap-marks w)))))
608
609 ;; syntax object wraps
610
611 ;; <wrap> ::= ((<mark> ...) . (<subst> ...))
612 ;; <subst> ::= <shift> | <subs>
613 ;; <subs> ::= #(<old name> <label> (<mark> ...))
614 ;; <shift> ::= positive fixnum
615
616 (define-syntax make-wrap (identifier-syntax cons))
617 (define-syntax wrap-marks (identifier-syntax car))
618 (define-syntax wrap-subst (identifier-syntax cdr))
619
620 (define-syntax subst-rename? (identifier-syntax vector?))
621 (define-syntax-rule (rename-old x) (vector-ref x 0))
622 (define-syntax-rule (rename-new x) (vector-ref x 1))
623 (define-syntax-rule (rename-marks x) (vector-ref x 2))
624 (define-syntax-rule (make-rename old new marks)
625 (vector old new marks))
626
627 ;; labels must be comparable with "eq?", have read-write invariance,
628 ;; and distinct from symbols.
629 (define gen-label
630 (lambda () (symbol->string (gensym "i"))))
631
632 (define gen-labels
633 (lambda (ls)
634 (if (null? ls)
635 '()
636 (cons (gen-label) (gen-labels (cdr ls))))))
637
638 (define-structure (ribcage symnames marks labels))
639
640 (define-syntax empty-wrap (identifier-syntax '(())))
641
642 (define-syntax top-wrap (identifier-syntax '((top))))
643
644 (define-syntax-rule (top-marked? w)
645 (memq 'top (wrap-marks w)))
646
647 ;; Marks must be comparable with "eq?" and distinct from pairs and
648 ;; the symbol top. We do not use integers so that marks will remain
649 ;; unique even across file compiles.
650
651 (define-syntax the-anti-mark (identifier-syntax #f))
652
653 (define anti-mark
654 (lambda (w)
655 (make-wrap (cons the-anti-mark (wrap-marks w))
656 (cons 'shift (wrap-subst w)))))
657
658 (define-syntax-rule (new-mark)
659 (gensym "m"))
660
661 ;; make-empty-ribcage and extend-ribcage maintain list-based ribcages for
662 ;; internal definitions, in which the ribcages are built incrementally
663 (define-syntax-rule (make-empty-ribcage)
664 (make-ribcage '() '() '()))
665
666 (define extend-ribcage!
667 ;; must receive ids with complete wraps
668 (lambda (ribcage id label)
669 (set-ribcage-symnames! ribcage
670 (cons (syntax-object-expression id)
671 (ribcage-symnames ribcage)))
672 (set-ribcage-marks! ribcage
673 (cons (wrap-marks (syntax-object-wrap id))
674 (ribcage-marks ribcage)))
675 (set-ribcage-labels! ribcage
676 (cons label (ribcage-labels ribcage)))))
677
678 ;; make-binding-wrap creates vector-based ribcages
679 (define make-binding-wrap
680 (lambda (ids labels w)
681 (if (null? ids)
682 w
683 (make-wrap
684 (wrap-marks w)
685 (cons
686 (let ((labelvec (list->vector labels)))
687 (let ((n (vector-length labelvec)))
688 (let ((symnamevec (make-vector n)) (marksvec (make-vector n)))
689 (let f ((ids ids) (i 0))
690 (if (not (null? ids))
691 (call-with-values
692 (lambda () (id-sym-name&marks (car ids) w))
693 (lambda (symname marks)
694 (vector-set! symnamevec i symname)
695 (vector-set! marksvec i marks)
696 (f (cdr ids) (fx+ i 1))))))
697 (make-ribcage symnamevec marksvec labelvec))))
698 (wrap-subst w))))))
699
700 (define smart-append
701 (lambda (m1 m2)
702 (if (null? m2)
703 m1
704 (append m1 m2))))
705
706 (define join-wraps
707 (lambda (w1 w2)
708 (let ((m1 (wrap-marks w1)) (s1 (wrap-subst w1)))
709 (if (null? m1)
710 (if (null? s1)
711 w2
712 (make-wrap
713 (wrap-marks w2)
714 (smart-append s1 (wrap-subst w2))))
715 (make-wrap
716 (smart-append m1 (wrap-marks w2))
717 (smart-append s1 (wrap-subst w2)))))))
718
719 (define join-marks
720 (lambda (m1 m2)
721 (smart-append m1 m2)))
722
723 (define same-marks?
724 (lambda (x y)
725 (or (eq? x y)
726 (and (not (null? x))
727 (not (null? y))
728 (eq? (car x) (car y))
729 (same-marks? (cdr x) (cdr y))))))
730
731 (define id-var-name
732 ;; Syntax objects use wraps to associate names with marked
733 ;; identifiers. This function returns the name corresponding to
734 ;; the given identifier and wrap, or the original identifier if no
735 ;; corresponding name was found.
736 ;;
737 ;; The name may be a string created by gen-label, indicating a
738 ;; lexical binding, or another syntax object, indicating a
739 ;; reference to a top-level definition created during a previous
740 ;; macroexpansion.
741 ;;
742 ;; For lexical variables, finding a label simply amounts to
743 ;; looking for an entry with the same symbolic name and the same
744 ;; marks. Finding a toplevel definition is the same, except we
745 ;; also have to compare modules, hence the `mod' parameter.
746 ;; Instead of adding a separate entry in the ribcage for modules,
747 ;; which wouldn't be used for lexicals, we arrange for the entry
748 ;; for the name entry to be a pair with the module in its car, and
749 ;; the name itself in the cdr. So if the name that we find is a
750 ;; pair, we have to check modules.
751 ;;
752 ;; The identifer may be passed in wrapped or unwrapped. In any
753 ;; case, this routine returns either a symbol, a syntax object, or
754 ;; a string label.
755 ;;
756 (lambda (id w mod)
757 (define-syntax-rule (first e)
758 ;; Rely on Guile's multiple-values truncation.
759 e)
760 (define search
761 (lambda (sym subst marks mod)
762 (if (null? subst)
763 (values #f marks)
764 (let ((fst (car subst)))
765 (if (eq? fst 'shift)
766 (search sym (cdr subst) (cdr marks) mod)
767 (let ((symnames (ribcage-symnames fst)))
768 (if (vector? symnames)
769 (search-vector-rib sym subst marks symnames fst mod)
770 (search-list-rib sym subst marks symnames fst mod))))))))
771 (define search-list-rib
772 (lambda (sym subst marks symnames ribcage mod)
773 (let f ((symnames symnames) (i 0))
774 (cond
775 ((null? symnames) (search sym (cdr subst) marks mod))
776 ((and (eq? (car symnames) sym)
777 (same-marks? marks (list-ref (ribcage-marks ribcage) i)))
778 (let ((n (list-ref (ribcage-labels ribcage) i)))
779 (if (pair? n)
780 (if (equal? mod (car n))
781 (values (cdr n) marks)
782 (f (cdr symnames) (fx+ i 1)))
783 (values n marks))))
784 (else (f (cdr symnames) (fx+ i 1)))))))
785 (define search-vector-rib
786 (lambda (sym subst marks symnames ribcage mod)
787 (let ((n (vector-length symnames)))
788 (let f ((i 0))
789 (cond
790 ((fx= i n) (search sym (cdr subst) marks mod))
791 ((and (eq? (vector-ref symnames i) sym)
792 (same-marks? marks (vector-ref (ribcage-marks ribcage) i)))
793 (let ((n (vector-ref (ribcage-labels ribcage) i)))
794 (if (pair? n)
795 (if (equal? mod (car n))
796 (values (cdr n) marks)
797 (f (fx+ i 1)))
798 (values n marks))))
799 (else (f (fx+ i 1))))))))
800 (cond
801 ((symbol? id)
802 (or (first (search id (wrap-subst w) (wrap-marks w) mod)) id))
803 ((syntax-object? id)
804 (let ((id (syntax-object-expression id))
805 (w1 (syntax-object-wrap id))
806 (mod (syntax-object-module id)))
807 (let ((marks (join-marks (wrap-marks w) (wrap-marks w1))))
808 (call-with-values (lambda () (search id (wrap-subst w) marks mod))
809 (lambda (new-id marks)
810 (or new-id
811 (first (search id (wrap-subst w1) marks mod))
812 id))))))
813 (else (syntax-violation 'id-var-name "invalid id" id)))))
814
815 ;; Returns three values: binding type, binding value, the module (for
816 ;; resolving toplevel vars).
817 (define (resolve-identifier id w r mod resolve-syntax-parameters?)
818 (define (resolve-syntax-parameters b)
819 (if (and resolve-syntax-parameters?
820 (eq? (binding-type b) 'syntax-parameter))
821 (or (assq-ref r (binding-value b))
822 (make-binding 'macro (car (binding-value b))))
823 b))
824 (define (resolve-global var mod)
825 (let ((b (resolve-syntax-parameters
826 (or (get-global-definition-hook var mod)
827 (make-binding 'global)))))
828 (if (eq? (binding-type b) 'global)
829 (values 'global var mod)
830 (values (binding-type b) (binding-value b) mod))))
831 (define (resolve-lexical label mod)
832 (let ((b (resolve-syntax-parameters
833 (or (assq-ref r label)
834 (make-binding 'displaced-lexical)))))
835 (values (binding-type b) (binding-value b) mod)))
836 (let ((n (id-var-name id w mod)))
837 (cond
838 ((syntax-object? n)
839 ;; Recursing allows syntax-parameterize to override
840 ;; macro-introduced syntax parameters.
841 (resolve-identifier n w r mod resolve-syntax-parameters?))
842 ((symbol? n)
843 (resolve-global n (if (syntax-object? id)
844 (syntax-object-module id)
845 mod)))
846 ((string? n)
847 (resolve-lexical n (if (syntax-object? id)
848 (syntax-object-module id)
849 mod)))
850 (else
851 (error "unexpected id-var-name" id w n)))))
852
853 ;; free-id=? must be passed fully wrapped ids since (free-id=? x y)
854 ;; may be true even if (free-id=? (wrap x w) (wrap y w)) is not.
855
856 (define free-id=?
857 (lambda (i j)
858 (let* ((mi (and (syntax-object? i) (syntax-object-module i)))
859 (mj (and (syntax-object? j) (syntax-object-module j)))
860 (ni (id-var-name i empty-wrap mi))
861 (nj (id-var-name j empty-wrap mj)))
862 (define (id-module-binding id mod)
863 (module-variable
864 (if mod
865 ;; The normal case.
866 (resolve-module (cdr mod))
867 ;; Either modules have not been booted, or we have a
868 ;; raw symbol coming in, which is possible.
869 (current-module))
870 (id-sym-name id)))
871 (cond
872 ((syntax-object? ni) (free-id=? ni j))
873 ((syntax-object? nj) (free-id=? i nj))
874 ((symbol? ni)
875 ;; `i' is not lexically bound. Assert that `j' is free,
876 ;; and if so, compare their bindings, that they are either
877 ;; bound to the same variable, or both unbound and have
878 ;; the same name.
879 (and (eq? nj (id-sym-name j))
880 (let ((bi (id-module-binding i mi)))
881 (if bi
882 (eq? bi (id-module-binding j mj))
883 (and (not (id-module-binding j mj))
884 (eq? ni nj))))
885 (eq? (id-module-binding i mi) (id-module-binding j mj))))
886 (else
887 ;; Otherwise `i' is bound, so check that `j' is bound, and
888 ;; bound to the same thing.
889 (equal? ni nj))))))
890
891 ;; bound-id=? may be passed unwrapped (or partially wrapped) ids as
892 ;; long as the missing portion of the wrap is common to both of the ids
893 ;; since (bound-id=? x y) iff (bound-id=? (wrap x w) (wrap y w))
894
895 (define bound-id=?
896 (lambda (i j)
897 (if (and (syntax-object? i) (syntax-object? j))
898 (and (eq? (syntax-object-expression i)
899 (syntax-object-expression j))
900 (same-marks? (wrap-marks (syntax-object-wrap i))
901 (wrap-marks (syntax-object-wrap j))))
902 (eq? i j))))
903
904 ;; "valid-bound-ids?" returns #t if it receives a list of distinct ids.
905 ;; valid-bound-ids? may be passed unwrapped (or partially wrapped) ids
906 ;; as long as the missing portion of the wrap is common to all of the
907 ;; ids.
908
909 (define valid-bound-ids?
910 (lambda (ids)
911 (and (let all-ids? ((ids ids))
912 (or (null? ids)
913 (and (id? (car ids))
914 (all-ids? (cdr ids)))))
915 (distinct-bound-ids? ids))))
916
917 ;; distinct-bound-ids? expects a list of ids and returns #t if there are
918 ;; no duplicates. It is quadratic on the length of the id list; long
919 ;; lists could be sorted to make it more efficient. distinct-bound-ids?
920 ;; may be passed unwrapped (or partially wrapped) ids as long as the
921 ;; missing portion of the wrap is common to all of the ids.
922
923 (define distinct-bound-ids?
924 (lambda (ids)
925 (let distinct? ((ids ids))
926 (or (null? ids)
927 (and (not (bound-id-member? (car ids) (cdr ids)))
928 (distinct? (cdr ids)))))))
929
930 (define bound-id-member?
931 (lambda (x list)
932 (and (not (null? list))
933 (or (bound-id=? x (car list))
934 (bound-id-member? x (cdr list))))))
935
936 ;; wrapping expressions and identifiers
937
938 (define wrap
939 (lambda (x w defmod)
940 (cond
941 ((and (null? (wrap-marks w)) (null? (wrap-subst w))) x)
942 ((syntax-object? x)
943 (make-syntax-object
944 (syntax-object-expression x)
945 (join-wraps w (syntax-object-wrap x))
946 (syntax-object-module x)))
947 ((null? x) x)
948 (else (make-syntax-object x w defmod)))))
949
950 (define source-wrap
951 (lambda (x w s defmod)
952 (wrap (decorate-source x s) w defmod)))
953
954 ;; expanding
955
956 (define expand-sequence
957 (lambda (body r w s mod)
958 (build-sequence s
959 (let dobody ((body body) (r r) (w w) (mod mod))
960 (if (null? body)
961 '()
962 (let ((first (expand (car body) r w mod)))
963 (cons first (dobody (cdr body) r w mod))))))))
964
965 ;; At top-level, we allow mixed definitions and expressions. Like
966 ;; expand-body we expand in two passes.
967 ;;
968 ;; First, from left to right, we expand just enough to know what
969 ;; expressions are definitions, syntax definitions, and splicing
970 ;; statements (`begin'). If we anything needs evaluating at
971 ;; expansion-time, it is expanded directly.
972 ;;
973 ;; Otherwise we collect expressions to expand, in thunks, and then
974 ;; expand them all at the end. This allows all syntax expanders
975 ;; visible in a toplevel sequence to be visible during the
976 ;; expansions of all normal definitions and expressions in the
977 ;; sequence.
978 ;;
979 (define expand-top-sequence
980 (lambda (body r w s m esew mod)
981 (let* ((r (cons '("placeholder" . (placeholder)) r))
982 (ribcage (make-empty-ribcage))
983 (w (make-wrap (wrap-marks w) (cons ribcage (wrap-subst w)))))
984 (define (record-definition! id var)
985 (let ((mod (cons 'hygiene (module-name (current-module)))))
986 ;; Ribcages map symbol+marks to names, mostly for
987 ;; resolving lexicals. Here to add a mapping for toplevel
988 ;; definitions we also need to match the module. So, we
989 ;; put it in the name instead, and make id-var-name handle
990 ;; the special case of names that are pairs. See the
991 ;; comments in id-var-name for more.
992 (extend-ribcage! ribcage id
993 (cons (syntax-object-module id)
994 (wrap var top-wrap mod)))))
995 (define (macro-introduced-identifier? id)
996 (not (equal? (wrap-marks (syntax-object-wrap id)) '(top))))
997 (define (fresh-derived-name id orig-form)
998 (symbol-append
999 (syntax-object-expression id)
1000 '-
1001 (string->symbol
1002 ;; FIXME: `hash' currently stops descending into nested
1003 ;; data at some point, so it's less unique than we would
1004 ;; like. Also this encodes hash values into the ABI of
1005 ;; compiled modules; a problem?
1006 (number->string
1007 (hash (syntax->datum orig-form) most-positive-fixnum)
1008 16))))
1009 (define (parse body r w s m esew mod)
1010 (let lp ((body body) (exps '()))
1011 (if (null? body)
1012 exps
1013 (lp (cdr body)
1014 (append (parse1 (car body) r w s m esew mod)
1015 exps)))))
1016 (define (parse1 x r w s m esew mod)
1017 (call-with-values
1018 (lambda ()
1019 (syntax-type x r w (source-annotation x) ribcage mod #f))
1020 (lambda (type value e w s mod)
1021 (case type
1022 ((define-form)
1023 (let* ((id (wrap value w mod))
1024 (label (gen-label))
1025 (var (if (macro-introduced-identifier? id)
1026 (fresh-derived-name id x)
1027 (syntax-object-expression id))))
1028 (record-definition! id var)
1029 (list
1030 (if (eq? m 'c&e)
1031 (let ((x (build-global-definition s var (expand e r w mod))))
1032 (top-level-eval-hook x mod)
1033 (lambda () x))
1034 (lambda ()
1035 (build-global-definition s var (expand e r w mod)))))))
1036 ((define-syntax-form define-syntax-parameter-form)
1037 (let* ((id (wrap value w mod))
1038 (label (gen-label))
1039 (var (if (macro-introduced-identifier? id)
1040 (fresh-derived-name id x)
1041 (syntax-object-expression id))))
1042 (record-definition! id var)
1043 (case m
1044 ((c)
1045 (cond
1046 ((memq 'compile esew)
1047 (let ((e (expand-install-global var type (expand e r w mod))))
1048 (top-level-eval-hook e mod)
1049 (if (memq 'load esew)
1050 (list (lambda () e))
1051 '())))
1052 ((memq 'load esew)
1053 (list (lambda ()
1054 (expand-install-global var type (expand e r w mod)))))
1055 (else '())))
1056 ((c&e)
1057 (let ((e (expand-install-global var type (expand e r w mod))))
1058 (top-level-eval-hook e mod)
1059 (list (lambda () e))))
1060 (else
1061 (if (memq 'eval esew)
1062 (top-level-eval-hook
1063 (expand-install-global var type (expand e r w mod))
1064 mod))
1065 '()))))
1066 ((begin-form)
1067 (syntax-case e ()
1068 ((_ e1 ...)
1069 (parse #'(e1 ...) r w s m esew mod))))
1070 ((local-syntax-form)
1071 (expand-local-syntax value e r w s mod
1072 (lambda (forms r w s mod)
1073 (parse forms r w s m esew mod))))
1074 ((eval-when-form)
1075 (syntax-case e ()
1076 ((_ (x ...) e1 e2 ...)
1077 (let ((when-list (parse-when-list e #'(x ...)))
1078 (body #'(e1 e2 ...)))
1079 (define (recurse m esew)
1080 (parse body r w s m esew mod))
1081 (cond
1082 ((eq? m 'e)
1083 (if (memq 'eval when-list)
1084 (recurse (if (memq 'expand when-list) 'c&e 'e)
1085 '(eval))
1086 (begin
1087 (if (memq 'expand when-list)
1088 (top-level-eval-hook
1089 (expand-top-sequence body r w s 'e '(eval) mod)
1090 mod))
1091 '())))
1092 ((memq 'load when-list)
1093 (if (or (memq 'compile when-list)
1094 (memq 'expand when-list)
1095 (and (eq? m 'c&e) (memq 'eval when-list)))
1096 (recurse 'c&e '(compile load))
1097 (if (memq m '(c c&e))
1098 (recurse 'c '(load))
1099 '())))
1100 ((or (memq 'compile when-list)
1101 (memq 'expand when-list)
1102 (and (eq? m 'c&e) (memq 'eval when-list)))
1103 (top-level-eval-hook
1104 (expand-top-sequence body r w s 'e '(eval) mod)
1105 mod)
1106 '())
1107 (else
1108 '()))))))
1109 (else
1110 (list
1111 (if (eq? m 'c&e)
1112 (let ((x (expand-expr type value e r w s mod)))
1113 (top-level-eval-hook x mod)
1114 (lambda () x))
1115 (lambda ()
1116 (expand-expr type value e r w s mod)))))))))
1117 (let ((exps (map (lambda (x) (x))
1118 (reverse (parse body r w s m esew mod)))))
1119 (if (null? exps)
1120 (build-void s)
1121 (build-sequence s exps))))))
1122
1123 (define expand-install-global
1124 (lambda (name type e)
1125 (build-global-definition
1126 no-source
1127 name
1128 (build-primcall
1129 no-source
1130 'make-syntax-transformer
1131 (if (eq? type 'define-syntax-parameter-form)
1132 (list (build-data no-source name)
1133 (build-data no-source 'syntax-parameter)
1134 (build-primcall no-source 'list (list e)))
1135 (list (build-data no-source name)
1136 (build-data no-source 'macro)
1137 e))))))
1138
1139 (define parse-when-list
1140 (lambda (e when-list)
1141 ;; `when-list' is syntax'd version of list of situations. We
1142 ;; could match these keywords lexically, via free-id=?, but then
1143 ;; we twingle the definition of eval-when to the bindings of
1144 ;; eval, load, expand, and compile, which is totally unintended.
1145 ;; So do a symbolic match instead.
1146 (let ((result (strip when-list empty-wrap)))
1147 (let lp ((l result))
1148 (if (null? l)
1149 result
1150 (if (memq (car l) '(compile load eval expand))
1151 (lp (cdr l))
1152 (syntax-violation 'eval-when "invalid situation" e
1153 (car l))))))))
1154
1155 ;; syntax-type returns six values: type, value, e, w, s, and mod. The
1156 ;; first two are described in the table below.
1157 ;;
1158 ;; type value explanation
1159 ;; -------------------------------------------------------------------
1160 ;; core procedure core singleton
1161 ;; core-form procedure core form
1162 ;; module-ref procedure @ or @@ singleton
1163 ;; lexical name lexical variable reference
1164 ;; global name global variable reference
1165 ;; begin none begin keyword
1166 ;; define none define keyword
1167 ;; define-syntax none define-syntax keyword
1168 ;; define-syntax-parameter none define-syntax-parameter keyword
1169 ;; local-syntax rec? letrec-syntax/let-syntax keyword
1170 ;; eval-when none eval-when keyword
1171 ;; syntax level pattern variable
1172 ;; displaced-lexical none displaced lexical identifier
1173 ;; lexical-call name call to lexical variable
1174 ;; global-call name call to global variable
1175 ;; call none any other call
1176 ;; begin-form none begin expression
1177 ;; define-form id variable definition
1178 ;; define-syntax-form id syntax definition
1179 ;; define-syntax-parameter-form id syntax parameter definition
1180 ;; local-syntax-form rec? syntax definition
1181 ;; eval-when-form none eval-when form
1182 ;; constant none self-evaluating datum
1183 ;; other none anything else
1184 ;;
1185 ;; For definition forms (define-form, define-syntax-parameter-form,
1186 ;; and define-syntax-form), e is the rhs expression. For all
1187 ;; others, e is the entire form. w is the wrap for e. s is the
1188 ;; source for the entire form. mod is the module for e.
1189 ;;
1190 ;; syntax-type expands macros and unwraps as necessary to get to one
1191 ;; of the forms above. It also parses definition forms, although
1192 ;; perhaps this should be done by the consumer.
1193
1194 (define syntax-type
1195 (lambda (e r w s rib mod for-car?)
1196 (cond
1197 ((symbol? e)
1198 (call-with-values (lambda () (resolve-identifier e w r mod #t))
1199 (lambda (type value mod*)
1200 (case type
1201 ((macro)
1202 (if for-car?
1203 (values type value e w s mod)
1204 (syntax-type (expand-macro value e r w s rib mod)
1205 r empty-wrap s rib mod #f)))
1206 ((global)
1207 ;; Toplevel definitions may resolve to bindings with
1208 ;; different names or in different modules.
1209 (values type value value w s mod*))
1210 (else (values type value e w s mod))))))
1211 ((pair? e)
1212 (let ((first (car e)))
1213 (call-with-values
1214 (lambda () (syntax-type first r w s rib mod #t))
1215 (lambda (ftype fval fe fw fs fmod)
1216 (case ftype
1217 ((lexical)
1218 (values 'lexical-call fval e w s mod))
1219 ((global)
1220 ;; If we got here via an (@@ ...) expansion, we need to
1221 ;; make sure the fmod information is propagated back
1222 ;; correctly -- hence this consing.
1223 (values 'global-call (make-syntax-object fval w fmod)
1224 e w s mod))
1225 ((macro)
1226 (syntax-type (expand-macro fval e r w s rib mod)
1227 r empty-wrap s rib mod for-car?))
1228 ((module-ref)
1229 (call-with-values (lambda () (fval e r w))
1230 (lambda (e r w s mod)
1231 (syntax-type e r w s rib mod for-car?))))
1232 ((core)
1233 (values 'core-form fval e w s mod))
1234 ((local-syntax)
1235 (values 'local-syntax-form fval e w s mod))
1236 ((begin)
1237 (values 'begin-form #f e w s mod))
1238 ((eval-when)
1239 (values 'eval-when-form #f e w s mod))
1240 ((define)
1241 (syntax-case e ()
1242 ((_ name val)
1243 (id? #'name)
1244 (values 'define-form #'name #'val w s mod))
1245 ((_ (name . args) e1 e2 ...)
1246 (and (id? #'name)
1247 (valid-bound-ids? (lambda-var-list #'args)))
1248 ;; need lambda here...
1249 (values 'define-form (wrap #'name w mod)
1250 (decorate-source
1251 (cons #'lambda (wrap #'(args e1 e2 ...) w mod))
1252 s)
1253 empty-wrap s mod))
1254 ((_ name)
1255 (id? #'name)
1256 (values 'define-form (wrap #'name w mod)
1257 #'(if #f #f)
1258 empty-wrap s mod))))
1259 ((define-syntax)
1260 (syntax-case e ()
1261 ((_ name val)
1262 (id? #'name)
1263 (values 'define-syntax-form #'name #'val w s mod))))
1264 ((define-syntax-parameter)
1265 (syntax-case e ()
1266 ((_ name val)
1267 (id? #'name)
1268 (values 'define-syntax-parameter-form #'name #'val w s mod))))
1269 (else
1270 (values 'call #f e w s mod)))))))
1271 ((syntax-object? e)
1272 (syntax-type (syntax-object-expression e)
1273 r
1274 (join-wraps w (syntax-object-wrap e))
1275 (or (source-annotation e) s) rib
1276 (or (syntax-object-module e) mod) for-car?))
1277 ((self-evaluating? e) (values 'constant #f e w s mod))
1278 (else (values 'other #f e w s mod)))))
1279
1280 (define expand
1281 (lambda (e r w mod)
1282 (call-with-values
1283 (lambda () (syntax-type e r w (source-annotation e) #f mod #f))
1284 (lambda (type value e w s mod)
1285 (expand-expr type value e r w s mod)))))
1286
1287 (define expand-expr
1288 (lambda (type value e r w s mod)
1289 (case type
1290 ((lexical)
1291 (build-lexical-reference 'value s e value))
1292 ((core core-form)
1293 ;; apply transformer
1294 (value e r w s mod))
1295 ((module-ref)
1296 (call-with-values (lambda () (value e r w))
1297 (lambda (e r w s mod)
1298 (expand e r w mod))))
1299 ((lexical-call)
1300 (expand-call
1301 (let ((id (car e)))
1302 (build-lexical-reference 'fun (source-annotation id)
1303 (if (syntax-object? id)
1304 (syntax->datum id)
1305 id)
1306 value))
1307 e r w s mod))
1308 ((global-call)
1309 (expand-call
1310 (build-global-reference (source-annotation (car e))
1311 (if (syntax-object? value)
1312 (syntax-object-expression value)
1313 value)
1314 (if (syntax-object? value)
1315 (syntax-object-module value)
1316 mod))
1317 e r w s mod))
1318 ((constant) (build-data s (strip (source-wrap e w s mod) empty-wrap)))
1319 ((global) (build-global-reference s value mod))
1320 ((call) (expand-call (expand (car e) r w mod) e r w s mod))
1321 ((begin-form)
1322 (syntax-case e ()
1323 ((_ e1 e2 ...) (expand-sequence #'(e1 e2 ...) r w s mod))
1324 ((_)
1325 (syntax-violation #f "sequence of zero expressions"
1326 (source-wrap e w s mod)))))
1327 ((local-syntax-form)
1328 (expand-local-syntax value e r w s mod expand-sequence))
1329 ((eval-when-form)
1330 (syntax-case e ()
1331 ((_ (x ...) e1 e2 ...)
1332 (let ((when-list (parse-when-list e #'(x ...))))
1333 (if (memq 'eval when-list)
1334 (expand-sequence #'(e1 e2 ...) r w s mod)
1335 (expand-void))))))
1336 ((define-form define-syntax-form define-syntax-parameter-form)
1337 (syntax-violation #f "definition in expression context"
1338 e (wrap value w mod)))
1339 ((syntax)
1340 (syntax-violation #f "reference to pattern variable outside syntax form"
1341 (source-wrap e w s mod)))
1342 ((displaced-lexical)
1343 (syntax-violation #f "reference to identifier outside its scope"
1344 (source-wrap e w s mod)))
1345 (else (syntax-violation #f "unexpected syntax"
1346 (source-wrap e w s mod))))))
1347
1348 (define expand-call
1349 (lambda (x e r w s mod)
1350 (syntax-case e ()
1351 ((e0 e1 ...)
1352 (build-call s x
1353 (map (lambda (e) (expand e r w mod)) #'(e1 ...)))))))
1354
1355 ;; (What follows is my interpretation of what's going on here -- Andy)
1356 ;;
1357 ;; A macro takes an expression, a tree, the leaves of which are identifiers
1358 ;; and datums. Identifiers are symbols along with a wrap and a module. For
1359 ;; efficiency, subtrees that share wraps and modules may be grouped as one
1360 ;; syntax object.
1361 ;;
1362 ;; Going into the expansion, the expression is given an anti-mark, which
1363 ;; logically propagates to all leaves. Then, in the new expression returned
1364 ;; from the transfomer, if we see an expression with an anti-mark, we know it
1365 ;; pertains to the original expression; conversely, expressions without the
1366 ;; anti-mark are known to be introduced by the transformer.
1367 ;;
1368 ;; OK, good until now. We know this algorithm does lexical scoping
1369 ;; appropriately because it's widely known in the literature, and psyntax is
1370 ;; widely used. But what about modules? Here we're on our own. What we do is
1371 ;; to mark the module of expressions produced by a macro as pertaining to the
1372 ;; module that was current when the macro was defined -- that is, free
1373 ;; identifiers introduced by a macro are scoped in the macro's module, not in
1374 ;; the expansion's module. Seems to work well.
1375 ;;
1376 ;; The only wrinkle is when we want a macro to expand to code in another
1377 ;; module, as is the case for the r6rs `library' form -- the body expressions
1378 ;; should be scoped relative the the new module, the one defined by the macro.
1379 ;; For that, use `(@@ mod-name body)'.
1380 ;;
1381 ;; Part of the macro output will be from the site of the macro use and part
1382 ;; from the macro definition. We allow source information from the macro use
1383 ;; to pass through, but we annotate the parts coming from the macro with the
1384 ;; source location information corresponding to the macro use. It would be
1385 ;; really nice if we could also annotate introduced expressions with the
1386 ;; locations corresponding to the macro definition, but that is not yet
1387 ;; possible.
1388 (define expand-macro
1389 (lambda (p e r w s rib mod)
1390 (define rebuild-macro-output
1391 (lambda (x m)
1392 (cond ((pair? x)
1393 (decorate-source
1394 (cons (rebuild-macro-output (car x) m)
1395 (rebuild-macro-output (cdr x) m))
1396 s))
1397 ((syntax-object? x)
1398 (let ((w (syntax-object-wrap x)))
1399 (let ((ms (wrap-marks w)) (s (wrap-subst w)))
1400 (if (and (pair? ms) (eq? (car ms) the-anti-mark))
1401 ;; output is from original text
1402 (make-syntax-object
1403 (syntax-object-expression x)
1404 (make-wrap (cdr ms) (if rib (cons rib (cdr s)) (cdr s)))
1405 (syntax-object-module x))
1406 ;; output introduced by macro
1407 (make-syntax-object
1408 (decorate-source (syntax-object-expression x) s)
1409 (make-wrap (cons m ms)
1410 (if rib
1411 (cons rib (cons 'shift s))
1412 (cons 'shift s)))
1413 (syntax-object-module x))))))
1414
1415 ((vector? x)
1416 (let* ((n (vector-length x))
1417 (v (decorate-source (make-vector n) x)))
1418 (do ((i 0 (fx+ i 1)))
1419 ((fx= i n) v)
1420 (vector-set! v i
1421 (rebuild-macro-output (vector-ref x i) m)))))
1422 ((symbol? x)
1423 (syntax-violation #f "encountered raw symbol in macro output"
1424 (source-wrap e w (wrap-subst w) mod) x))
1425 (else (decorate-source x s)))))
1426 (rebuild-macro-output (p (source-wrap e (anti-mark w) s mod))
1427 (new-mark))))
1428
1429 (define expand-body
1430 ;; In processing the forms of the body, we create a new, empty wrap.
1431 ;; This wrap is augmented (destructively) each time we discover that
1432 ;; the next form is a definition. This is done:
1433 ;;
1434 ;; (1) to allow the first nondefinition form to be a call to
1435 ;; one of the defined ids even if the id previously denoted a
1436 ;; definition keyword or keyword for a macro expanding into a
1437 ;; definition;
1438 ;; (2) to prevent subsequent definition forms (but unfortunately
1439 ;; not earlier ones) and the first nondefinition form from
1440 ;; confusing one of the bound identifiers for an auxiliary
1441 ;; keyword; and
1442 ;; (3) so that we do not need to restart the expansion of the
1443 ;; first nondefinition form, which is problematic anyway
1444 ;; since it might be the first element of a begin that we
1445 ;; have just spliced into the body (meaning if we restarted,
1446 ;; we'd really need to restart with the begin or the macro
1447 ;; call that expanded into the begin, and we'd have to give
1448 ;; up allowing (begin <defn>+ <expr>+), which is itself
1449 ;; problematic since we don't know if a begin contains only
1450 ;; definitions until we've expanded it).
1451 ;;
1452 ;; Before processing the body, we also create a new environment
1453 ;; containing a placeholder for the bindings we will add later and
1454 ;; associate this environment with each form. In processing a
1455 ;; let-syntax or letrec-syntax, the associated environment may be
1456 ;; augmented with local keyword bindings, so the environment may
1457 ;; be different for different forms in the body. Once we have
1458 ;; gathered up all of the definitions, we evaluate the transformer
1459 ;; expressions and splice into r at the placeholder the new variable
1460 ;; and keyword bindings. This allows let-syntax or letrec-syntax
1461 ;; forms local to a portion or all of the body to shadow the
1462 ;; definition bindings.
1463 ;;
1464 ;; Subforms of a begin, let-syntax, or letrec-syntax are spliced
1465 ;; into the body.
1466 ;;
1467 ;; outer-form is fully wrapped w/source
1468 (lambda (body outer-form r w mod)
1469 (let* ((r (cons '("placeholder" . (placeholder)) r))
1470 (ribcage (make-empty-ribcage))
1471 (w (make-wrap (wrap-marks w) (cons ribcage (wrap-subst w)))))
1472 (let parse ((body (map (lambda (x) (cons r (wrap x w mod))) body))
1473 (ids '()) (labels '())
1474 (var-ids '()) (vars '()) (vals '()) (bindings '()))
1475 (if (null? body)
1476 (syntax-violation #f "no expressions in body" outer-form)
1477 (let ((e (cdar body)) (er (caar body)))
1478 (call-with-values
1479 (lambda () (syntax-type e er empty-wrap (source-annotation er) ribcage mod #f))
1480 (lambda (type value e w s mod)
1481 (case type
1482 ((define-form)
1483 (let ((id (wrap value w mod)) (label (gen-label)))
1484 (let ((var (gen-var id)))
1485 (extend-ribcage! ribcage id label)
1486 (parse (cdr body)
1487 (cons id ids) (cons label labels)
1488 (cons id var-ids)
1489 (cons var vars) (cons (cons er (wrap e w mod)) vals)
1490 (cons (make-binding 'lexical var) bindings)))))
1491 ((define-syntax-form define-syntax-parameter-form)
1492 (let ((id (wrap value w mod)) (label (gen-label)))
1493 (extend-ribcage! ribcage id label)
1494 (parse (cdr body)
1495 (cons id ids) (cons label labels)
1496 var-ids vars vals
1497 (cons (make-binding
1498 (if (eq? type 'define-syntax-parameter-form)
1499 'syntax-parameter
1500 'macro)
1501 (cons er (wrap e w mod)))
1502 bindings))))
1503 ((begin-form)
1504 (syntax-case e ()
1505 ((_ e1 ...)
1506 (parse (let f ((forms #'(e1 ...)))
1507 (if (null? forms)
1508 (cdr body)
1509 (cons (cons er (wrap (car forms) w mod))
1510 (f (cdr forms)))))
1511 ids labels var-ids vars vals bindings))))
1512 ((local-syntax-form)
1513 (expand-local-syntax value e er w s mod
1514 (lambda (forms er w s mod)
1515 (parse (let f ((forms forms))
1516 (if (null? forms)
1517 (cdr body)
1518 (cons (cons er (wrap (car forms) w mod))
1519 (f (cdr forms)))))
1520 ids labels var-ids vars vals bindings))))
1521 (else ; found a non-definition
1522 (if (null? ids)
1523 (build-sequence no-source
1524 (map (lambda (x)
1525 (expand (cdr x) (car x) empty-wrap mod))
1526 (cons (cons er (source-wrap e w s mod))
1527 (cdr body))))
1528 (begin
1529 (if (not (valid-bound-ids? ids))
1530 (syntax-violation
1531 #f "invalid or duplicate identifier in definition"
1532 outer-form))
1533 (let loop ((bs bindings) (er-cache #f) (r-cache #f))
1534 (if (not (null? bs))
1535 (let* ((b (car bs)))
1536 (if (memq (car b) '(macro syntax-parameter))
1537 (let* ((er (cadr b))
1538 (r-cache
1539 (if (eq? er er-cache)
1540 r-cache
1541 (macros-only-env er))))
1542 (set-cdr! b
1543 (eval-local-transformer
1544 (expand (cddr b) r-cache empty-wrap mod)
1545 mod))
1546 (if (eq? (car b) 'syntax-parameter)
1547 (set-cdr! b (list (cdr b))))
1548 (loop (cdr bs) er r-cache))
1549 (loop (cdr bs) er-cache r-cache)))))
1550 (set-cdr! r (extend-env labels bindings (cdr r)))
1551 (build-letrec no-source #t
1552 (reverse (map syntax->datum var-ids))
1553 (reverse vars)
1554 (map (lambda (x)
1555 (expand (cdr x) (car x) empty-wrap mod))
1556 (reverse vals))
1557 (build-sequence no-source
1558 (map (lambda (x)
1559 (expand (cdr x) (car x) empty-wrap mod))
1560 (cons (cons er (source-wrap e w s mod))
1561 (cdr body)))))))))))))))))
1562
1563 (define expand-local-syntax
1564 (lambda (rec? e r w s mod k)
1565 (syntax-case e ()
1566 ((_ ((id val) ...) e1 e2 ...)
1567 (let ((ids #'(id ...)))
1568 (if (not (valid-bound-ids? ids))
1569 (syntax-violation #f "duplicate bound keyword" e)
1570 (let ((labels (gen-labels ids)))
1571 (let ((new-w (make-binding-wrap ids labels w)))
1572 (k #'(e1 e2 ...)
1573 (extend-env
1574 labels
1575 (let ((w (if rec? new-w w))
1576 (trans-r (macros-only-env r)))
1577 (map (lambda (x)
1578 (make-binding 'macro
1579 (eval-local-transformer
1580 (expand x trans-r w mod)
1581 mod)))
1582 #'(val ...)))
1583 r)
1584 new-w
1585 s
1586 mod))))))
1587 (_ (syntax-violation #f "bad local syntax definition"
1588 (source-wrap e w s mod))))))
1589
1590 (define eval-local-transformer
1591 (lambda (expanded mod)
1592 (let ((p (local-eval-hook expanded mod)))
1593 (if (procedure? p)
1594 p
1595 (syntax-violation #f "nonprocedure transformer" p)))))
1596
1597 (define expand-void
1598 (lambda ()
1599 (build-void no-source)))
1600
1601 (define ellipsis?
1602 (lambda (x)
1603 (and (nonsymbol-id? x)
1604 (free-id=? x #'(... ...)))))
1605
1606 (define lambda-formals
1607 (lambda (orig-args)
1608 (define (req args rreq)
1609 (syntax-case args ()
1610 (()
1611 (check (reverse rreq) #f))
1612 ((a . b) (id? #'a)
1613 (req #'b (cons #'a rreq)))
1614 (r (id? #'r)
1615 (check (reverse rreq) #'r))
1616 (else
1617 (syntax-violation 'lambda "invalid argument list" orig-args args))))
1618 (define (check req rest)
1619 (cond
1620 ((distinct-bound-ids? (if rest (cons rest req) req))
1621 (values req #f rest #f))
1622 (else
1623 (syntax-violation 'lambda "duplicate identifier in argument list"
1624 orig-args))))
1625 (req orig-args '())))
1626
1627 (define expand-simple-lambda
1628 (lambda (e r w s mod req rest meta body)
1629 (let* ((ids (if rest (append req (list rest)) req))
1630 (vars (map gen-var ids))
1631 (labels (gen-labels ids)))
1632 (build-simple-lambda
1633 s
1634 (map syntax->datum req) (and rest (syntax->datum rest)) vars
1635 meta
1636 (expand-body body (source-wrap e w s mod)
1637 (extend-var-env labels vars r)
1638 (make-binding-wrap ids labels w)
1639 mod)))))
1640
1641 (define lambda*-formals
1642 (lambda (orig-args)
1643 (define (req args rreq)
1644 (syntax-case args ()
1645 (()
1646 (check (reverse rreq) '() #f '()))
1647 ((a . b) (id? #'a)
1648 (req #'b (cons #'a rreq)))
1649 ((a . b) (eq? (syntax->datum #'a) #:optional)
1650 (opt #'b (reverse rreq) '()))
1651 ((a . b) (eq? (syntax->datum #'a) #:key)
1652 (key #'b (reverse rreq) '() '()))
1653 ((a b) (eq? (syntax->datum #'a) #:rest)
1654 (rest #'b (reverse rreq) '() '()))
1655 (r (id? #'r)
1656 (rest #'r (reverse rreq) '() '()))
1657 (else
1658 (syntax-violation 'lambda* "invalid argument list" orig-args args))))
1659 (define (opt args req ropt)
1660 (syntax-case args ()
1661 (()
1662 (check req (reverse ropt) #f '()))
1663 ((a . b) (id? #'a)
1664 (opt #'b req (cons #'(a #f) ropt)))
1665 (((a init) . b) (id? #'a)
1666 (opt #'b req (cons #'(a init) ropt)))
1667 ((a . b) (eq? (syntax->datum #'a) #:key)
1668 (key #'b req (reverse ropt) '()))
1669 ((a b) (eq? (syntax->datum #'a) #:rest)
1670 (rest #'b req (reverse ropt) '()))
1671 (r (id? #'r)
1672 (rest #'r req (reverse ropt) '()))
1673 (else
1674 (syntax-violation 'lambda* "invalid optional argument list"
1675 orig-args args))))
1676 (define (key args req opt rkey)
1677 (syntax-case args ()
1678 (()
1679 (check req opt #f (cons #f (reverse rkey))))
1680 ((a . b) (id? #'a)
1681 (with-syntax ((k (symbol->keyword (syntax->datum #'a))))
1682 (key #'b req opt (cons #'(k a #f) rkey))))
1683 (((a init) . b) (id? #'a)
1684 (with-syntax ((k (symbol->keyword (syntax->datum #'a))))
1685 (key #'b req opt (cons #'(k a init) rkey))))
1686 (((a init k) . b) (and (id? #'a)
1687 (keyword? (syntax->datum #'k)))
1688 (key #'b req opt (cons #'(k a init) rkey)))
1689 ((aok) (eq? (syntax->datum #'aok) #:allow-other-keys)
1690 (check req opt #f (cons #t (reverse rkey))))
1691 ((aok a b) (and (eq? (syntax->datum #'aok) #:allow-other-keys)
1692 (eq? (syntax->datum #'a) #:rest))
1693 (rest #'b req opt (cons #t (reverse rkey))))
1694 ((aok . r) (and (eq? (syntax->datum #'aok) #:allow-other-keys)
1695 (id? #'r))
1696 (rest #'r req opt (cons #t (reverse rkey))))
1697 ((a b) (eq? (syntax->datum #'a) #:rest)
1698 (rest #'b req opt (cons #f (reverse rkey))))
1699 (r (id? #'r)
1700 (rest #'r req opt (cons #f (reverse rkey))))
1701 (else
1702 (syntax-violation 'lambda* "invalid keyword argument list"
1703 orig-args args))))
1704 (define (rest args req opt kw)
1705 (syntax-case args ()
1706 (r (id? #'r)
1707 (check req opt #'r kw))
1708 (else
1709 (syntax-violation 'lambda* "invalid rest argument"
1710 orig-args args))))
1711 (define (check req opt rest kw)
1712 (cond
1713 ((distinct-bound-ids?
1714 (append req (map car opt) (if rest (list rest) '())
1715 (if (pair? kw) (map cadr (cdr kw)) '())))
1716 (values req opt rest kw))
1717 (else
1718 (syntax-violation 'lambda* "duplicate identifier in argument list"
1719 orig-args))))
1720 (req orig-args '())))
1721
1722 (define expand-lambda-case
1723 (lambda (e r w s mod get-formals clauses)
1724 (define (parse-req req opt rest kw body)
1725 (let ((vars (map gen-var req))
1726 (labels (gen-labels req)))
1727 (let ((r* (extend-var-env labels vars r))
1728 (w* (make-binding-wrap req labels w)))
1729 (parse-opt (map syntax->datum req)
1730 opt rest kw body (reverse vars) r* w* '() '()))))
1731 (define (parse-opt req opt rest kw body vars r* w* out inits)
1732 (cond
1733 ((pair? opt)
1734 (syntax-case (car opt) ()
1735 ((id i)
1736 (let* ((v (gen-var #'id))
1737 (l (gen-labels (list v)))
1738 (r** (extend-var-env l (list v) r*))
1739 (w** (make-binding-wrap (list #'id) l w*)))
1740 (parse-opt req (cdr opt) rest kw body (cons v vars)
1741 r** w** (cons (syntax->datum #'id) out)
1742 (cons (expand #'i r* w* mod) inits))))))
1743 (rest
1744 (let* ((v (gen-var rest))
1745 (l (gen-labels (list v)))
1746 (r* (extend-var-env l (list v) r*))
1747 (w* (make-binding-wrap (list rest) l w*)))
1748 (parse-kw req (if (pair? out) (reverse out) #f)
1749 (syntax->datum rest)
1750 (if (pair? kw) (cdr kw) kw)
1751 body (cons v vars) r* w*
1752 (if (pair? kw) (car kw) #f)
1753 '() inits)))
1754 (else
1755 (parse-kw req (if (pair? out) (reverse out) #f) #f
1756 (if (pair? kw) (cdr kw) kw)
1757 body vars r* w*
1758 (if (pair? kw) (car kw) #f)
1759 '() inits))))
1760 (define (parse-kw req opt rest kw body vars r* w* aok out inits)
1761 (cond
1762 ((pair? kw)
1763 (syntax-case (car kw) ()
1764 ((k id i)
1765 (let* ((v (gen-var #'id))
1766 (l (gen-labels (list v)))
1767 (r** (extend-var-env l (list v) r*))
1768 (w** (make-binding-wrap (list #'id) l w*)))
1769 (parse-kw req opt rest (cdr kw) body (cons v vars)
1770 r** w** aok
1771 (cons (list (syntax->datum #'k)
1772 (syntax->datum #'id)
1773 v)
1774 out)
1775 (cons (expand #'i r* w* mod) inits))))))
1776 (else
1777 (parse-body req opt rest
1778 (if (or aok (pair? out)) (cons aok (reverse out)) #f)
1779 body (reverse vars) r* w* (reverse inits) '()))))
1780 (define (parse-body req opt rest kw body vars r* w* inits meta)
1781 (syntax-case body ()
1782 ((docstring e1 e2 ...) (string? (syntax->datum #'docstring))
1783 (parse-body req opt rest kw #'(e1 e2 ...) vars r* w* inits
1784 (append meta
1785 `((documentation
1786 . ,(syntax->datum #'docstring))))))
1787 ((#((k . v) ...) e1 e2 ...)
1788 (parse-body req opt rest kw #'(e1 e2 ...) vars r* w* inits
1789 (append meta (syntax->datum #'((k . v) ...)))))
1790 ((e1 e2 ...)
1791 (values meta req opt rest kw inits vars
1792 (expand-body #'(e1 e2 ...) (source-wrap e w s mod)
1793 r* w* mod)))))
1794
1795 (syntax-case clauses ()
1796 (() (values '() #f))
1797 (((args e1 e2 ...) (args* e1* e2* ...) ...)
1798 (call-with-values (lambda () (get-formals #'args))
1799 (lambda (req opt rest kw)
1800 (call-with-values (lambda ()
1801 (parse-req req opt rest kw #'(e1 e2 ...)))
1802 (lambda (meta req opt rest kw inits vars body)
1803 (call-with-values
1804 (lambda ()
1805 (expand-lambda-case e r w s mod get-formals
1806 #'((args* e1* e2* ...) ...)))
1807 (lambda (meta* else*)
1808 (values
1809 (append meta meta*)
1810 (build-lambda-case s req opt rest kw inits vars
1811 body else*))))))))))))
1812
1813 ;; data
1814
1815 ;; strips syntax-objects down to top-wrap
1816 ;;
1817 ;; since only the head of a list is annotated by the reader, not each pair
1818 ;; in the spine, we also check for pairs whose cars are annotated in case
1819 ;; we've been passed the cdr of an annotated list
1820
1821 (define strip
1822 (lambda (x w)
1823 (if (top-marked? w)
1824 x
1825 (let f ((x x))
1826 (cond
1827 ((syntax-object? x)
1828 (strip (syntax-object-expression x) (syntax-object-wrap x)))
1829 ((pair? x)
1830 (let ((a (f (car x))) (d (f (cdr x))))
1831 (if (and (eq? a (car x)) (eq? d (cdr x)))
1832 x
1833 (cons a d))))
1834 ((vector? x)
1835 (let ((old (vector->list x)))
1836 (let ((new (map f old)))
1837 ;; inlined and-map with two args
1838 (let lp ((l1 old) (l2 new))
1839 (if (null? l1)
1840 x
1841 (if (eq? (car l1) (car l2))
1842 (lp (cdr l1) (cdr l2))
1843 (list->vector new)))))))
1844 (else x))))))
1845
1846 ;; lexical variables
1847
1848 (define gen-var
1849 (lambda (id)
1850 (let ((id (if (syntax-object? id) (syntax-object-expression id) id)))
1851 (build-lexical-var no-source id))))
1852
1853 ;; appears to return a reversed list
1854 (define lambda-var-list
1855 (lambda (vars)
1856 (let lvl ((vars vars) (ls '()) (w empty-wrap))
1857 (cond
1858 ((pair? vars) (lvl (cdr vars) (cons (wrap (car vars) w #f) ls) w))
1859 ((id? vars) (cons (wrap vars w #f) ls))
1860 ((null? vars) ls)
1861 ((syntax-object? vars)
1862 (lvl (syntax-object-expression vars)
1863 ls
1864 (join-wraps w (syntax-object-wrap vars))))
1865 ;; include anything else to be caught by subsequent error
1866 ;; checking
1867 (else (cons vars ls))))))
1868
1869 ;; core transformers
1870
1871 (global-extend 'local-syntax 'letrec-syntax #t)
1872 (global-extend 'local-syntax 'let-syntax #f)
1873
1874 (global-extend
1875 'core 'syntax-parameterize
1876 (lambda (e r w s mod)
1877 (syntax-case e ()
1878 ((_ ((var val) ...) e1 e2 ...)
1879 (valid-bound-ids? #'(var ...))
1880 (let ((names
1881 (map (lambda (x)
1882 (call-with-values
1883 (lambda () (resolve-identifier x w r mod #f))
1884 (lambda (type value mod)
1885 (case type
1886 ((displaced-lexical)
1887 (syntax-violation 'syntax-parameterize
1888 "identifier out of context"
1889 e
1890 (source-wrap x w s mod)))
1891 ((syntax-parameter)
1892 value)
1893 (else
1894 (syntax-violation 'syntax-parameterize
1895 "invalid syntax parameter"
1896 e
1897 (source-wrap x w s mod)))))))
1898 #'(var ...)))
1899 (bindings
1900 (let ((trans-r (macros-only-env r)))
1901 (map (lambda (x)
1902 (make-binding
1903 'macro
1904 (eval-local-transformer (expand x trans-r w mod) mod)))
1905 #'(val ...)))))
1906 (expand-body #'(e1 e2 ...)
1907 (source-wrap e w s mod)
1908 (extend-env names bindings r)
1909 w
1910 mod)))
1911 (_ (syntax-violation 'syntax-parameterize "bad syntax"
1912 (source-wrap e w s mod))))))
1913
1914 (global-extend 'core 'quote
1915 (lambda (e r w s mod)
1916 (syntax-case e ()
1917 ((_ e) (build-data s (strip #'e w)))
1918 (_ (syntax-violation 'quote "bad syntax"
1919 (source-wrap e w s mod))))))
1920
1921 (global-extend
1922 'core 'syntax
1923 (let ()
1924 (define gen-syntax
1925 (lambda (src e r maps ellipsis? mod)
1926 (if (id? e)
1927 (call-with-values (lambda ()
1928 (resolve-identifier e empty-wrap r mod #f))
1929 (lambda (type value mod)
1930 (case type
1931 ((syntax)
1932 (call-with-values
1933 (lambda () (gen-ref src (car value) (cdr value) maps))
1934 (lambda (var maps)
1935 (values `(ref ,var) maps))))
1936 (else
1937 (if (ellipsis? e)
1938 (syntax-violation 'syntax "misplaced ellipsis" src)
1939 (values `(quote ,e) maps))))))
1940 (syntax-case e ()
1941 ((dots e)
1942 (ellipsis? #'dots)
1943 (gen-syntax src #'e r maps (lambda (x) #f) mod))
1944 ((x dots . y)
1945 ;; this could be about a dozen lines of code, except that we
1946 ;; choose to handle #'(x ... ...) forms
1947 (ellipsis? #'dots)
1948 (let f ((y #'y)
1949 (k (lambda (maps)
1950 (call-with-values
1951 (lambda ()
1952 (gen-syntax src #'x r
1953 (cons '() maps) ellipsis? mod))
1954 (lambda (x maps)
1955 (if (null? (car maps))
1956 (syntax-violation 'syntax "extra ellipsis"
1957 src)
1958 (values (gen-map x (car maps))
1959 (cdr maps))))))))
1960 (syntax-case y ()
1961 ((dots . y)
1962 (ellipsis? #'dots)
1963 (f #'y
1964 (lambda (maps)
1965 (call-with-values
1966 (lambda () (k (cons '() maps)))
1967 (lambda (x maps)
1968 (if (null? (car maps))
1969 (syntax-violation 'syntax "extra ellipsis" src)
1970 (values (gen-mappend x (car maps))
1971 (cdr maps))))))))
1972 (_ (call-with-values
1973 (lambda () (gen-syntax src y r maps ellipsis? mod))
1974 (lambda (y maps)
1975 (call-with-values
1976 (lambda () (k maps))
1977 (lambda (x maps)
1978 (values (gen-append x y) maps)))))))))
1979 ((x . y)
1980 (call-with-values
1981 (lambda () (gen-syntax src #'x r maps ellipsis? mod))
1982 (lambda (x maps)
1983 (call-with-values
1984 (lambda () (gen-syntax src #'y r maps ellipsis? mod))
1985 (lambda (y maps) (values (gen-cons x y) maps))))))
1986 (#(e1 e2 ...)
1987 (call-with-values
1988 (lambda ()
1989 (gen-syntax src #'(e1 e2 ...) r maps ellipsis? mod))
1990 (lambda (e maps) (values (gen-vector e) maps))))
1991 (_ (values `(quote ,e) maps))))))
1992
1993 (define gen-ref
1994 (lambda (src var level maps)
1995 (if (fx= level 0)
1996 (values var maps)
1997 (if (null? maps)
1998 (syntax-violation 'syntax "missing ellipsis" src)
1999 (call-with-values
2000 (lambda () (gen-ref src var (fx- level 1) (cdr maps)))
2001 (lambda (outer-var outer-maps)
2002 (let ((b (assq outer-var (car maps))))
2003 (if b
2004 (values (cdr b) maps)
2005 (let ((inner-var (gen-var 'tmp)))
2006 (values inner-var
2007 (cons (cons (cons outer-var inner-var)
2008 (car maps))
2009 outer-maps)))))))))))
2010
2011 (define gen-mappend
2012 (lambda (e map-env)
2013 `(apply (primitive append) ,(gen-map e map-env))))
2014
2015 (define gen-map
2016 (lambda (e map-env)
2017 (let ((formals (map cdr map-env))
2018 (actuals (map (lambda (x) `(ref ,(car x))) map-env)))
2019 (cond
2020 ((eq? (car e) 'ref)
2021 ;; identity map equivalence:
2022 ;; (map (lambda (x) x) y) == y
2023 (car actuals))
2024 ((and-map
2025 (lambda (x) (and (eq? (car x) 'ref) (memq (cadr x) formals)))
2026 (cdr e))
2027 ;; eta map equivalence:
2028 ;; (map (lambda (x ...) (f x ...)) y ...) == (map f y ...)
2029 `(map (primitive ,(car e))
2030 ,@(map (let ((r (map cons formals actuals)))
2031 (lambda (x) (cdr (assq (cadr x) r))))
2032 (cdr e))))
2033 (else `(map (lambda ,formals ,e) ,@actuals))))))
2034
2035 (define gen-cons
2036 (lambda (x y)
2037 (case (car y)
2038 ((quote)
2039 (if (eq? (car x) 'quote)
2040 `(quote (,(cadr x) . ,(cadr y)))
2041 (if (eq? (cadr y) '())
2042 `(list ,x)
2043 `(cons ,x ,y))))
2044 ((list) `(list ,x ,@(cdr y)))
2045 (else `(cons ,x ,y)))))
2046
2047 (define gen-append
2048 (lambda (x y)
2049 (if (equal? y '(quote ()))
2050 x
2051 `(append ,x ,y))))
2052
2053 (define gen-vector
2054 (lambda (x)
2055 (cond
2056 ((eq? (car x) 'list) `(vector ,@(cdr x)))
2057 ((eq? (car x) 'quote) `(quote #(,@(cadr x))))
2058 (else `(list->vector ,x)))))
2059
2060
2061 (define regen
2062 (lambda (x)
2063 (case (car x)
2064 ((ref) (build-lexical-reference 'value no-source (cadr x) (cadr x)))
2065 ((primitive) (build-primref no-source (cadr x)))
2066 ((quote) (build-data no-source (cadr x)))
2067 ((lambda)
2068 (if (list? (cadr x))
2069 (build-simple-lambda no-source (cadr x) #f (cadr x) '() (regen (caddr x)))
2070 (error "how did we get here" x)))
2071 (else (build-primcall no-source (car x) (map regen (cdr x)))))))
2072
2073 (lambda (e r w s mod)
2074 (let ((e (source-wrap e w s mod)))
2075 (syntax-case e ()
2076 ((_ x)
2077 (call-with-values
2078 (lambda () (gen-syntax e #'x r '() ellipsis? mod))
2079 (lambda (e maps) (regen e))))
2080 (_ (syntax-violation 'syntax "bad `syntax' form" e)))))))
2081
2082 (global-extend 'core 'lambda
2083 (lambda (e r w s mod)
2084 (syntax-case e ()
2085 ((_ args e1 e2 ...)
2086 (call-with-values (lambda () (lambda-formals #'args))
2087 (lambda (req opt rest kw)
2088 (let lp ((body #'(e1 e2 ...)) (meta '()))
2089 (syntax-case body ()
2090 ((docstring e1 e2 ...) (string? (syntax->datum #'docstring))
2091 (lp #'(e1 e2 ...)
2092 (append meta
2093 `((documentation
2094 . ,(syntax->datum #'docstring))))))
2095 ((#((k . v) ...) e1 e2 ...)
2096 (lp #'(e1 e2 ...)
2097 (append meta (syntax->datum #'((k . v) ...)))))
2098 (_ (expand-simple-lambda e r w s mod req rest meta body)))))))
2099 (_ (syntax-violation 'lambda "bad lambda" e)))))
2100
2101 (global-extend 'core 'lambda*
2102 (lambda (e r w s mod)
2103 (syntax-case e ()
2104 ((_ args e1 e2 ...)
2105 (call-with-values
2106 (lambda ()
2107 (expand-lambda-case e r w s mod
2108 lambda*-formals #'((args e1 e2 ...))))
2109 (lambda (meta lcase)
2110 (build-case-lambda s meta lcase))))
2111 (_ (syntax-violation 'lambda "bad lambda*" e)))))
2112
2113 (global-extend 'core 'case-lambda
2114 (lambda (e r w s mod)
2115 (syntax-case e ()
2116 ((_ (args e1 e2 ...) (args* e1* e2* ...) ...)
2117 (call-with-values
2118 (lambda ()
2119 (expand-lambda-case e r w s mod
2120 lambda-formals
2121 #'((args e1 e2 ...) (args* e1* e2* ...) ...)))
2122 (lambda (meta lcase)
2123 (build-case-lambda s meta lcase))))
2124 (_ (syntax-violation 'case-lambda "bad case-lambda" e)))))
2125
2126 (global-extend 'core 'case-lambda*
2127 (lambda (e r w s mod)
2128 (syntax-case e ()
2129 ((_ (args e1 e2 ...) (args* e1* e2* ...) ...)
2130 (call-with-values
2131 (lambda ()
2132 (expand-lambda-case e r w s mod
2133 lambda*-formals
2134 #'((args e1 e2 ...) (args* e1* e2* ...) ...)))
2135 (lambda (meta lcase)
2136 (build-case-lambda s meta lcase))))
2137 (_ (syntax-violation 'case-lambda "bad case-lambda*" e)))))
2138
2139 (global-extend 'core 'let
2140 (let ()
2141 (define (expand-let e r w s mod constructor ids vals exps)
2142 (if (not (valid-bound-ids? ids))
2143 (syntax-violation 'let "duplicate bound variable" e)
2144 (let ((labels (gen-labels ids))
2145 (new-vars (map gen-var ids)))
2146 (let ((nw (make-binding-wrap ids labels w))
2147 (nr (extend-var-env labels new-vars r)))
2148 (constructor s
2149 (map syntax->datum ids)
2150 new-vars
2151 (map (lambda (x) (expand x r w mod)) vals)
2152 (expand-body exps (source-wrap e nw s mod)
2153 nr nw mod))))))
2154 (lambda (e r w s mod)
2155 (syntax-case e ()
2156 ((_ ((id val) ...) e1 e2 ...)
2157 (and-map id? #'(id ...))
2158 (expand-let e r w s mod
2159 build-let
2160 #'(id ...)
2161 #'(val ...)
2162 #'(e1 e2 ...)))
2163 ((_ f ((id val) ...) e1 e2 ...)
2164 (and (id? #'f) (and-map id? #'(id ...)))
2165 (expand-let e r w s mod
2166 build-named-let
2167 #'(f id ...)
2168 #'(val ...)
2169 #'(e1 e2 ...)))
2170 (_ (syntax-violation 'let "bad let" (source-wrap e w s mod)))))))
2171
2172
2173 (global-extend 'core 'letrec
2174 (lambda (e r w s mod)
2175 (syntax-case e ()
2176 ((_ ((id val) ...) e1 e2 ...)
2177 (and-map id? #'(id ...))
2178 (let ((ids #'(id ...)))
2179 (if (not (valid-bound-ids? ids))
2180 (syntax-violation 'letrec "duplicate bound variable" e)
2181 (let ((labels (gen-labels ids))
2182 (new-vars (map gen-var ids)))
2183 (let ((w (make-binding-wrap ids labels w))
2184 (r (extend-var-env labels new-vars r)))
2185 (build-letrec s #f
2186 (map syntax->datum ids)
2187 new-vars
2188 (map (lambda (x) (expand x r w mod)) #'(val ...))
2189 (expand-body #'(e1 e2 ...)
2190 (source-wrap e w s mod) r w mod)))))))
2191 (_ (syntax-violation 'letrec "bad letrec" (source-wrap e w s mod))))))
2192
2193
2194 (global-extend 'core 'letrec*
2195 (lambda (e r w s mod)
2196 (syntax-case e ()
2197 ((_ ((id val) ...) e1 e2 ...)
2198 (and-map id? #'(id ...))
2199 (let ((ids #'(id ...)))
2200 (if (not (valid-bound-ids? ids))
2201 (syntax-violation 'letrec* "duplicate bound variable" e)
2202 (let ((labels (gen-labels ids))
2203 (new-vars (map gen-var ids)))
2204 (let ((w (make-binding-wrap ids labels w))
2205 (r (extend-var-env labels new-vars r)))
2206 (build-letrec s #t
2207 (map syntax->datum ids)
2208 new-vars
2209 (map (lambda (x) (expand x r w mod)) #'(val ...))
2210 (expand-body #'(e1 e2 ...)
2211 (source-wrap e w s mod) r w mod)))))))
2212 (_ (syntax-violation 'letrec* "bad letrec*" (source-wrap e w s mod))))))
2213
2214
2215 (global-extend
2216 'core 'set!
2217 (lambda (e r w s mod)
2218 (syntax-case e ()
2219 ((_ id val)
2220 (id? #'id)
2221 (call-with-values
2222 (lambda () (resolve-identifier #'id w r mod #t))
2223 (lambda (type value id-mod)
2224 (case type
2225 ((lexical)
2226 (build-lexical-assignment s (syntax->datum #'id) value
2227 (expand #'val r w mod)))
2228 ((global)
2229 (build-global-assignment s value (expand #'val r w mod) id-mod))
2230 ((macro)
2231 (if (procedure-property value 'variable-transformer)
2232 ;; As syntax-type does, call expand-macro with
2233 ;; the mod of the expression. Hmm.
2234 (expand (expand-macro value e r w s #f mod) r empty-wrap mod)
2235 (syntax-violation 'set! "not a variable transformer"
2236 (wrap e w mod)
2237 (wrap #'id w id-mod))))
2238 ((displaced-lexical)
2239 (syntax-violation 'set! "identifier out of context"
2240 (wrap #'id w mod)))
2241 (else
2242 (syntax-violation 'set! "bad set!" (source-wrap e w s mod)))))))
2243 ((_ (head tail ...) val)
2244 (call-with-values
2245 (lambda () (syntax-type #'head r empty-wrap no-source #f mod #t))
2246 (lambda (type value ee ww ss modmod)
2247 (case type
2248 ((module-ref)
2249 (let ((val (expand #'val r w mod)))
2250 (call-with-values (lambda () (value #'(head tail ...) r w))
2251 (lambda (e r w s* mod)
2252 (syntax-case e ()
2253 (e (id? #'e)
2254 (build-global-assignment s (syntax->datum #'e)
2255 val mod)))))))
2256 (else
2257 (build-call s
2258 (expand #'(setter head) r w mod)
2259 (map (lambda (e) (expand e r w mod))
2260 #'(tail ... val))))))))
2261 (_ (syntax-violation 'set! "bad set!" (source-wrap e w s mod))))))
2262
2263 (global-extend 'module-ref '@
2264 (lambda (e r w)
2265 (syntax-case e ()
2266 ((_ (mod ...) id)
2267 (and (and-map id? #'(mod ...)) (id? #'id))
2268 (values (syntax->datum #'id) r w #f
2269 (syntax->datum
2270 #'(public mod ...)))))))
2271
2272 (global-extend 'module-ref '@@
2273 (lambda (e r w)
2274 (define remodulate
2275 (lambda (x mod)
2276 (cond ((pair? x)
2277 (cons (remodulate (car x) mod)
2278 (remodulate (cdr x) mod)))
2279 ((syntax-object? x)
2280 (make-syntax-object
2281 (remodulate (syntax-object-expression x) mod)
2282 (syntax-object-wrap x)
2283 ;; hither the remodulation
2284 mod))
2285 ((vector? x)
2286 (let* ((n (vector-length x)) (v (make-vector n)))
2287 (do ((i 0 (fx+ i 1)))
2288 ((fx= i n) v)
2289 (vector-set! v i (remodulate (vector-ref x i) mod)))))
2290 (else x))))
2291 (syntax-case e ()
2292 ((_ (mod ...) exp)
2293 (and-map id? #'(mod ...))
2294 (let ((mod (syntax->datum #'(private mod ...))))
2295 (values (remodulate #'exp mod)
2296 r w (source-annotation #'exp)
2297 mod))))))
2298
2299 (global-extend 'core 'if
2300 (lambda (e r w s mod)
2301 (syntax-case e ()
2302 ((_ test then)
2303 (build-conditional
2304 s
2305 (expand #'test r w mod)
2306 (expand #'then r w mod)
2307 (build-void no-source)))
2308 ((_ test then else)
2309 (build-conditional
2310 s
2311 (expand #'test r w mod)
2312 (expand #'then r w mod)
2313 (expand #'else r w mod))))))
2314
2315 (global-extend 'core 'with-fluids
2316 (lambda (e r w s mod)
2317 (syntax-case e ()
2318 ((_ ((fluid val) ...) b b* ...)
2319 (build-dynlet
2320 s
2321 (map (lambda (x) (expand x r w mod)) #'(fluid ...))
2322 (map (lambda (x) (expand x r w mod)) #'(val ...))
2323 (expand-body #'(b b* ...)
2324 (source-wrap e w s mod) r w mod))))))
2325
2326 (global-extend 'begin 'begin '())
2327
2328 (global-extend 'define 'define '())
2329
2330 (global-extend 'define-syntax 'define-syntax '())
2331 (global-extend 'define-syntax-parameter 'define-syntax-parameter '())
2332
2333 (global-extend 'eval-when 'eval-when '())
2334
2335 (global-extend 'core 'syntax-case
2336 (let ()
2337 (define convert-pattern
2338 ;; accepts pattern & keys
2339 ;; returns $sc-dispatch pattern & ids
2340 (lambda (pattern keys)
2341 (define cvt*
2342 (lambda (p* n ids)
2343 (if (not (pair? p*))
2344 (cvt p* n ids)
2345 (call-with-values
2346 (lambda () (cvt* (cdr p*) n ids))
2347 (lambda (y ids)
2348 (call-with-values
2349 (lambda () (cvt (car p*) n ids))
2350 (lambda (x ids)
2351 (values (cons x y) ids))))))))
2352
2353 (define (v-reverse x)
2354 (let loop ((r '()) (x x))
2355 (if (not (pair? x))
2356 (values r x)
2357 (loop (cons (car x) r) (cdr x)))))
2358
2359 (define cvt
2360 (lambda (p n ids)
2361 (if (id? p)
2362 (cond
2363 ((bound-id-member? p keys)
2364 (values (vector 'free-id p) ids))
2365 ((free-id=? p #'_)
2366 (values '_ ids))
2367 (else
2368 (values 'any (cons (cons p n) ids))))
2369 (syntax-case p ()
2370 ((x dots)
2371 (ellipsis? (syntax dots))
2372 (call-with-values
2373 (lambda () (cvt (syntax x) (fx+ n 1) ids))
2374 (lambda (p ids)
2375 (values (if (eq? p 'any) 'each-any (vector 'each p))
2376 ids))))
2377 ((x dots . ys)
2378 (ellipsis? (syntax dots))
2379 (call-with-values
2380 (lambda () (cvt* (syntax ys) n ids))
2381 (lambda (ys ids)
2382 (call-with-values
2383 (lambda () (cvt (syntax x) (+ n 1) ids))
2384 (lambda (x ids)
2385 (call-with-values
2386 (lambda () (v-reverse ys))
2387 (lambda (ys e)
2388 (values `#(each+ ,x ,ys ,e)
2389 ids))))))))
2390 ((x . y)
2391 (call-with-values
2392 (lambda () (cvt (syntax y) n ids))
2393 (lambda (y ids)
2394 (call-with-values
2395 (lambda () (cvt (syntax x) n ids))
2396 (lambda (x ids)
2397 (values (cons x y) ids))))))
2398 (() (values '() ids))
2399 (#(x ...)
2400 (call-with-values
2401 (lambda () (cvt (syntax (x ...)) n ids))
2402 (lambda (p ids) (values (vector 'vector p) ids))))
2403 (x (values (vector 'atom (strip p empty-wrap)) ids))))))
2404 (cvt pattern 0 '())))
2405
2406 (define build-dispatch-call
2407 (lambda (pvars exp y r mod)
2408 (let ((ids (map car pvars)) (levels (map cdr pvars)))
2409 (let ((labels (gen-labels ids)) (new-vars (map gen-var ids)))
2410 (build-primcall
2411 no-source
2412 'apply
2413 (list (build-simple-lambda no-source (map syntax->datum ids) #f new-vars '()
2414 (expand exp
2415 (extend-env
2416 labels
2417 (map (lambda (var level)
2418 (make-binding 'syntax `(,var . ,level)))
2419 new-vars
2420 (map cdr pvars))
2421 r)
2422 (make-binding-wrap ids labels empty-wrap)
2423 mod))
2424 y))))))
2425
2426 (define gen-clause
2427 (lambda (x keys clauses r pat fender exp mod)
2428 (call-with-values
2429 (lambda () (convert-pattern pat keys))
2430 (lambda (p pvars)
2431 (cond
2432 ((not (distinct-bound-ids? (map car pvars)))
2433 (syntax-violation 'syntax-case "duplicate pattern variable" pat))
2434 ((not (and-map (lambda (x) (not (ellipsis? (car x)))) pvars))
2435 (syntax-violation 'syntax-case "misplaced ellipsis" pat))
2436 (else
2437 (let ((y (gen-var 'tmp)))
2438 ;; fat finger binding and references to temp variable y
2439 (build-call no-source
2440 (build-simple-lambda no-source (list 'tmp) #f (list y) '()
2441 (let ((y (build-lexical-reference 'value no-source
2442 'tmp y)))
2443 (build-conditional no-source
2444 (syntax-case fender ()
2445 (#t y)
2446 (_ (build-conditional no-source
2447 y
2448 (build-dispatch-call pvars fender y r mod)
2449 (build-data no-source #f))))
2450 (build-dispatch-call pvars exp y r mod)
2451 (gen-syntax-case x keys clauses r mod))))
2452 (list (if (eq? p 'any)
2453 (build-primcall no-source 'list (list x))
2454 (build-primcall no-source '$sc-dispatch
2455 (list x (build-data no-source p)))))))))))))
2456
2457 (define gen-syntax-case
2458 (lambda (x keys clauses r mod)
2459 (if (null? clauses)
2460 (build-primcall no-source 'syntax-violation
2461 (list (build-data no-source #f)
2462 (build-data no-source
2463 "source expression failed to match any pattern")
2464 x))
2465 (syntax-case (car clauses) ()
2466 ((pat exp)
2467 (if (and (id? #'pat)
2468 (and-map (lambda (x) (not (free-id=? #'pat x)))
2469 (cons #'(... ...) keys)))
2470 (if (free-id=? #'pad #'_)
2471 (expand #'exp r empty-wrap mod)
2472 (let ((labels (list (gen-label)))
2473 (var (gen-var #'pat)))
2474 (build-call no-source
2475 (build-simple-lambda
2476 no-source (list (syntax->datum #'pat)) #f (list var)
2477 '()
2478 (expand #'exp
2479 (extend-env labels
2480 (list (make-binding 'syntax `(,var . 0)))
2481 r)
2482 (make-binding-wrap #'(pat)
2483 labels empty-wrap)
2484 mod))
2485 (list x))))
2486 (gen-clause x keys (cdr clauses) r
2487 #'pat #t #'exp mod)))
2488 ((pat fender exp)
2489 (gen-clause x keys (cdr clauses) r
2490 #'pat #'fender #'exp mod))
2491 (_ (syntax-violation 'syntax-case "invalid clause"
2492 (car clauses)))))))
2493
2494 (lambda (e r w s mod)
2495 (let ((e (source-wrap e w s mod)))
2496 (syntax-case e ()
2497 ((_ val (key ...) m ...)
2498 (if (and-map (lambda (x) (and (id? x) (not (ellipsis? x))))
2499 #'(key ...))
2500 (let ((x (gen-var 'tmp)))
2501 ;; fat finger binding and references to temp variable x
2502 (build-call s
2503 (build-simple-lambda no-source (list 'tmp) #f (list x) '()
2504 (gen-syntax-case (build-lexical-reference 'value no-source
2505 'tmp x)
2506 #'(key ...) #'(m ...)
2507 r
2508 mod))
2509 (list (expand #'val r empty-wrap mod))))
2510 (syntax-violation 'syntax-case "invalid literals list" e))))))))
2511
2512 ;; The portable macroexpand seeds expand-top's mode m with 'e (for
2513 ;; evaluating) and esew (which stands for "eval syntax expanders
2514 ;; when") with '(eval). In Chez Scheme, m is set to 'c instead of e
2515 ;; if we are compiling a file, and esew is set to
2516 ;; (eval-syntactic-expanders-when), which defaults to the list
2517 ;; '(compile load eval). This means that, by default, top-level
2518 ;; syntactic definitions are evaluated immediately after they are
2519 ;; expanded, and the expanded definitions are also residualized into
2520 ;; the object file if we are compiling a file.
2521 (set! macroexpand
2522 (lambda* (x #:optional (m 'e) (esew '(eval)))
2523 (expand-top-sequence (list x) null-env top-wrap #f m esew
2524 (cons 'hygiene (module-name (current-module))))))
2525
2526 (set! identifier?
2527 (lambda (x)
2528 (nonsymbol-id? x)))
2529
2530 (set! datum->syntax
2531 (lambda (id datum)
2532 (make-syntax-object datum (syntax-object-wrap id)
2533 (syntax-object-module id))))
2534
2535 (set! syntax->datum
2536 ;; accepts any object, since syntax objects may consist partially
2537 ;; or entirely of unwrapped, nonsymbolic data
2538 (lambda (x)
2539 (strip x empty-wrap)))
2540
2541 (set! syntax-source
2542 (lambda (x) (source-annotation x)))
2543
2544 (set! generate-temporaries
2545 (lambda (ls)
2546 (arg-check list? ls 'generate-temporaries)
2547 (let ((mod (cons 'hygiene (module-name (current-module)))))
2548 (map (lambda (x) (wrap (gensym-hook) top-wrap mod)) ls))))
2549
2550 (set! free-identifier=?
2551 (lambda (x y)
2552 (arg-check nonsymbol-id? x 'free-identifier=?)
2553 (arg-check nonsymbol-id? y 'free-identifier=?)
2554 (free-id=? x y)))
2555
2556 (set! bound-identifier=?
2557 (lambda (x y)
2558 (arg-check nonsymbol-id? x 'bound-identifier=?)
2559 (arg-check nonsymbol-id? y 'bound-identifier=?)
2560 (bound-id=? x y)))
2561
2562 (set! syntax-violation
2563 (lambda* (who message form #:optional subform)
2564 (arg-check (lambda (x) (or (not x) (string? x) (symbol? x)))
2565 who 'syntax-violation)
2566 (arg-check string? message 'syntax-violation)
2567 (throw 'syntax-error who message
2568 (source-annotation (or form subform))
2569 (strip form empty-wrap)
2570 (and subform (strip subform empty-wrap)))))
2571
2572 ;; $sc-dispatch expects an expression and a pattern. If the expression
2573 ;; matches the pattern a list of the matching expressions for each
2574 ;; "any" is returned. Otherwise, #f is returned. (This use of #f will
2575 ;; not work on r4rs implementations that violate the ieee requirement
2576 ;; that #f and () be distinct.)
2577
2578 ;; The expression is matched with the pattern as follows:
2579
2580 ;; pattern: matches:
2581 ;; () empty list
2582 ;; any anything
2583 ;; (<pattern>1 . <pattern>2) (<pattern>1 . <pattern>2)
2584 ;; each-any (any*)
2585 ;; #(free-id <key>) <key> with free-identifier=?
2586 ;; #(each <pattern>) (<pattern>*)
2587 ;; #(each+ p1 (p2_1 ... p2_n) p3) (p1* (p2_n ... p2_1) . p3)
2588 ;; #(vector <pattern>) (list->vector <pattern>)
2589 ;; #(atom <object>) <object> with "equal?"
2590
2591 ;; Vector cops out to pair under assumption that vectors are rare. If
2592 ;; not, should convert to:
2593 ;; #(vector <pattern>*) #(<pattern>*)
2594
2595 (let ()
2596
2597 (define match-each
2598 (lambda (e p w mod)
2599 (cond
2600 ((pair? e)
2601 (let ((first (match (car e) p w '() mod)))
2602 (and first
2603 (let ((rest (match-each (cdr e) p w mod)))
2604 (and rest (cons first rest))))))
2605 ((null? e) '())
2606 ((syntax-object? e)
2607 (match-each (syntax-object-expression e)
2608 p
2609 (join-wraps w (syntax-object-wrap e))
2610 (syntax-object-module e)))
2611 (else #f))))
2612
2613 (define match-each+
2614 (lambda (e x-pat y-pat z-pat w r mod)
2615 (let f ((e e) (w w))
2616 (cond
2617 ((pair? e)
2618 (call-with-values (lambda () (f (cdr e) w))
2619 (lambda (xr* y-pat r)
2620 (if r
2621 (if (null? y-pat)
2622 (let ((xr (match (car e) x-pat w '() mod)))
2623 (if xr
2624 (values (cons xr xr*) y-pat r)
2625 (values #f #f #f)))
2626 (values
2627 '()
2628 (cdr y-pat)
2629 (match (car e) (car y-pat) w r mod)))
2630 (values #f #f #f)))))
2631 ((syntax-object? e)
2632 (f (syntax-object-expression e) (join-wraps w e)))
2633 (else
2634 (values '() y-pat (match e z-pat w r mod)))))))
2635
2636 (define match-each-any
2637 (lambda (e w mod)
2638 (cond
2639 ((pair? e)
2640 (let ((l (match-each-any (cdr e) w mod)))
2641 (and l (cons (wrap (car e) w mod) l))))
2642 ((null? e) '())
2643 ((syntax-object? e)
2644 (match-each-any (syntax-object-expression e)
2645 (join-wraps w (syntax-object-wrap e))
2646 mod))
2647 (else #f))))
2648
2649 (define match-empty
2650 (lambda (p r)
2651 (cond
2652 ((null? p) r)
2653 ((eq? p '_) r)
2654 ((eq? p 'any) (cons '() r))
2655 ((pair? p) (match-empty (car p) (match-empty (cdr p) r)))
2656 ((eq? p 'each-any) (cons '() r))
2657 (else
2658 (case (vector-ref p 0)
2659 ((each) (match-empty (vector-ref p 1) r))
2660 ((each+) (match-empty (vector-ref p 1)
2661 (match-empty
2662 (reverse (vector-ref p 2))
2663 (match-empty (vector-ref p 3) r))))
2664 ((free-id atom) r)
2665 ((vector) (match-empty (vector-ref p 1) r)))))))
2666
2667 (define combine
2668 (lambda (r* r)
2669 (if (null? (car r*))
2670 r
2671 (cons (map car r*) (combine (map cdr r*) r)))))
2672
2673 (define match*
2674 (lambda (e p w r mod)
2675 (cond
2676 ((null? p) (and (null? e) r))
2677 ((pair? p)
2678 (and (pair? e) (match (car e) (car p) w
2679 (match (cdr e) (cdr p) w r mod)
2680 mod)))
2681 ((eq? p 'each-any)
2682 (let ((l (match-each-any e w mod))) (and l (cons l r))))
2683 (else
2684 (case (vector-ref p 0)
2685 ((each)
2686 (if (null? e)
2687 (match-empty (vector-ref p 1) r)
2688 (let ((l (match-each e (vector-ref p 1) w mod)))
2689 (and l
2690 (let collect ((l l))
2691 (if (null? (car l))
2692 r
2693 (cons (map car l) (collect (map cdr l)))))))))
2694 ((each+)
2695 (call-with-values
2696 (lambda ()
2697 (match-each+ e (vector-ref p 1) (vector-ref p 2) (vector-ref p 3) w r mod))
2698 (lambda (xr* y-pat r)
2699 (and r
2700 (null? y-pat)
2701 (if (null? xr*)
2702 (match-empty (vector-ref p 1) r)
2703 (combine xr* r))))))
2704 ((free-id) (and (id? e) (free-id=? (wrap e w mod) (vector-ref p 1)) r))
2705 ((atom) (and (equal? (vector-ref p 1) (strip e w)) r))
2706 ((vector)
2707 (and (vector? e)
2708 (match (vector->list e) (vector-ref p 1) w r mod))))))))
2709
2710 (define match
2711 (lambda (e p w r mod)
2712 (cond
2713 ((not r) #f)
2714 ((eq? p '_) r)
2715 ((eq? p 'any) (cons (wrap e w mod) r))
2716 ((syntax-object? e)
2717 (match*
2718 (syntax-object-expression e)
2719 p
2720 (join-wraps w (syntax-object-wrap e))
2721 r
2722 (syntax-object-module e)))
2723 (else (match* e p w r mod)))))
2724
2725 (set! $sc-dispatch
2726 (lambda (e p)
2727 (cond
2728 ((eq? p 'any) (list e))
2729 ((eq? p '_) '())
2730 ((syntax-object? e)
2731 (match* (syntax-object-expression e)
2732 p (syntax-object-wrap e) '() (syntax-object-module e)))
2733 (else (match* e p empty-wrap '() #f))))))))
2734
2735
2736 (define-syntax with-syntax
2737 (lambda (x)
2738 (syntax-case x ()
2739 ((_ () e1 e2 ...)
2740 #'(let () e1 e2 ...))
2741 ((_ ((out in)) e1 e2 ...)
2742 #'(syntax-case in ()
2743 (out (let () e1 e2 ...))))
2744 ((_ ((out in) ...) e1 e2 ...)
2745 #'(syntax-case (list in ...) ()
2746 ((out ...) (let () e1 e2 ...)))))))
2747
2748 (define-syntax syntax-rules
2749 (lambda (x)
2750 (syntax-case x ()
2751 ((_ (k ...) ((keyword . pattern) template) ...)
2752 #'(lambda (x)
2753 ;; embed patterns as procedure metadata
2754 #((macro-type . syntax-rules)
2755 (patterns pattern ...))
2756 (syntax-case x (k ...)
2757 ((_ . pattern) #'template)
2758 ...)))
2759 ((_ (k ...) docstring ((keyword . pattern) template) ...)
2760 (string? (syntax->datum #'docstring))
2761 #'(lambda (x)
2762 ;; the same, but allow a docstring
2763 docstring
2764 #((macro-type . syntax-rules)
2765 (patterns pattern ...))
2766 (syntax-case x (k ...)
2767 ((_ . pattern) #'template)
2768 ...))))))
2769
2770 (define-syntax define-syntax-rule
2771 (lambda (x)
2772 (syntax-case x ()
2773 ((_ (name . pattern) template)
2774 #'(define-syntax name
2775 (syntax-rules ()
2776 ((_ . pattern) template))))
2777 ((_ (name . pattern) docstring template)
2778 (string? (syntax->datum #'docstring))
2779 #'(define-syntax name
2780 (syntax-rules ()
2781 docstring
2782 ((_ . pattern) template)))))))
2783
2784 (define-syntax let*
2785 (lambda (x)
2786 (syntax-case x ()
2787 ((let* ((x v) ...) e1 e2 ...)
2788 (and-map identifier? #'(x ...))
2789 (let f ((bindings #'((x v) ...)))
2790 (if (null? bindings)
2791 #'(let () e1 e2 ...)
2792 (with-syntax ((body (f (cdr bindings)))
2793 (binding (car bindings)))
2794 #'(let (binding) body))))))))
2795
2796 (define-syntax do
2797 (lambda (orig-x)
2798 (syntax-case orig-x ()
2799 ((_ ((var init . step) ...) (e0 e1 ...) c ...)
2800 (with-syntax (((step ...)
2801 (map (lambda (v s)
2802 (syntax-case s ()
2803 (() v)
2804 ((e) #'e)
2805 (_ (syntax-violation
2806 'do "bad step expression"
2807 orig-x s))))
2808 #'(var ...)
2809 #'(step ...))))
2810 (syntax-case #'(e1 ...) ()
2811 (() #'(let doloop ((var init) ...)
2812 (if (not e0)
2813 (begin c ... (doloop step ...)))))
2814 ((e1 e2 ...)
2815 #'(let doloop ((var init) ...)
2816 (if e0
2817 (begin e1 e2 ...)
2818 (begin c ... (doloop step ...)))))))))))
2819
2820 (define-syntax quasiquote
2821 (let ()
2822 (define (quasi p lev)
2823 (syntax-case p (unquote quasiquote)
2824 ((unquote p)
2825 (if (= lev 0)
2826 #'("value" p)
2827 (quasicons #'("quote" unquote) (quasi #'(p) (- lev 1)))))
2828 ((quasiquote p) (quasicons #'("quote" quasiquote) (quasi #'(p) (+ lev 1))))
2829 ((p . q)
2830 (syntax-case #'p (unquote unquote-splicing)
2831 ((unquote p ...)
2832 (if (= lev 0)
2833 (quasilist* #'(("value" p) ...) (quasi #'q lev))
2834 (quasicons
2835 (quasicons #'("quote" unquote) (quasi #'(p ...) (- lev 1)))
2836 (quasi #'q lev))))
2837 ((unquote-splicing p ...)
2838 (if (= lev 0)
2839 (quasiappend #'(("value" p) ...) (quasi #'q lev))
2840 (quasicons
2841 (quasicons #'("quote" unquote-splicing) (quasi #'(p ...) (- lev 1)))
2842 (quasi #'q lev))))
2843 (_ (quasicons (quasi #'p lev) (quasi #'q lev)))))
2844 (#(x ...) (quasivector (vquasi #'(x ...) lev)))
2845 (p #'("quote" p))))
2846 (define (vquasi p lev)
2847 (syntax-case p ()
2848 ((p . q)
2849 (syntax-case #'p (unquote unquote-splicing)
2850 ((unquote p ...)
2851 (if (= lev 0)
2852 (quasilist* #'(("value" p) ...) (vquasi #'q lev))
2853 (quasicons
2854 (quasicons #'("quote" unquote) (quasi #'(p ...) (- lev 1)))
2855 (vquasi #'q lev))))
2856 ((unquote-splicing p ...)
2857 (if (= lev 0)
2858 (quasiappend #'(("value" p) ...) (vquasi #'q lev))
2859 (quasicons
2860 (quasicons
2861 #'("quote" unquote-splicing)
2862 (quasi #'(p ...) (- lev 1)))
2863 (vquasi #'q lev))))
2864 (_ (quasicons (quasi #'p lev) (vquasi #'q lev)))))
2865 (() #'("quote" ()))))
2866 (define (quasicons x y)
2867 (with-syntax ((x x) (y y))
2868 (syntax-case #'y ()
2869 (("quote" dy)
2870 (syntax-case #'x ()
2871 (("quote" dx) #'("quote" (dx . dy)))
2872 (_ (if (null? #'dy) #'("list" x) #'("list*" x y)))))
2873 (("list" . stuff) #'("list" x . stuff))
2874 (("list*" . stuff) #'("list*" x . stuff))
2875 (_ #'("list*" x y)))))
2876 (define (quasiappend x y)
2877 (syntax-case y ()
2878 (("quote" ())
2879 (cond
2880 ((null? x) #'("quote" ()))
2881 ((null? (cdr x)) (car x))
2882 (else (with-syntax (((p ...) x)) #'("append" p ...)))))
2883 (_
2884 (cond
2885 ((null? x) y)
2886 (else (with-syntax (((p ...) x) (y y)) #'("append" p ... y)))))))
2887 (define (quasilist* x y)
2888 (let f ((x x))
2889 (if (null? x)
2890 y
2891 (quasicons (car x) (f (cdr x))))))
2892 (define (quasivector x)
2893 (syntax-case x ()
2894 (("quote" (x ...)) #'("quote" #(x ...)))
2895 (_
2896 (let f ((y x) (k (lambda (ls) #`("vector" #,@ls))))
2897 (syntax-case y ()
2898 (("quote" (y ...)) (k #'(("quote" y) ...)))
2899 (("list" y ...) (k #'(y ...)))
2900 (("list*" y ... z) (f #'z (lambda (ls) (k (append #'(y ...) ls)))))
2901 (else #`("list->vector" #,x)))))))
2902 (define (emit x)
2903 (syntax-case x ()
2904 (("quote" x) #''x)
2905 (("list" x ...) #`(list #,@(map emit #'(x ...))))
2906 ;; could emit list* for 3+ arguments if implementation supports
2907 ;; list*
2908 (("list*" x ... y)
2909 (let f ((x* #'(x ...)))
2910 (if (null? x*)
2911 (emit #'y)
2912 #`(cons #,(emit (car x*)) #,(f (cdr x*))))))
2913 (("append" x ...) #`(append #,@(map emit #'(x ...))))
2914 (("vector" x ...) #`(vector #,@(map emit #'(x ...))))
2915 (("list->vector" x) #`(list->vector #,(emit #'x)))
2916 (("value" x) #'x)))
2917 (lambda (x)
2918 (syntax-case x ()
2919 ;; convert to intermediate language, combining introduced (but
2920 ;; not unquoted source) quote expressions where possible and
2921 ;; choosing optimal construction code otherwise, then emit
2922 ;; Scheme code corresponding to the intermediate language forms.
2923 ((_ e) (emit (quasi #'e 0)))))))
2924
2925 (define-syntax include
2926 (lambda (x)
2927 (define read-file
2928 (lambda (fn k)
2929 (let ((p (open-input-file fn)))
2930 (let f ((x (read p))
2931 (result '()))
2932 (if (eof-object? x)
2933 (begin
2934 (close-input-port p)
2935 (reverse result))
2936 (f (read p)
2937 (cons (datum->syntax k x) result)))))))
2938 (syntax-case x ()
2939 ((k filename)
2940 (let ((fn (syntax->datum #'filename)))
2941 (with-syntax (((exp ...) (read-file fn #'filename)))
2942 #'(begin exp ...)))))))
2943
2944 (define-syntax include-from-path
2945 (lambda (x)
2946 (syntax-case x ()
2947 ((k filename)
2948 (let ((fn (syntax->datum #'filename)))
2949 (with-syntax ((fn (datum->syntax
2950 #'filename
2951 (or (%search-load-path fn)
2952 (syntax-violation 'include-from-path
2953 "file not found in path"
2954 x #'filename)))))
2955 #'(include fn)))))))
2956
2957 (define-syntax unquote
2958 (lambda (x)
2959 (syntax-violation 'unquote
2960 "expression not valid outside of quasiquote"
2961 x)))
2962
2963 (define-syntax unquote-splicing
2964 (lambda (x)
2965 (syntax-violation 'unquote-splicing
2966 "expression not valid outside of quasiquote"
2967 x)))
2968
2969 (define-syntax case
2970 (lambda (x)
2971 (syntax-case x ()
2972 ((_ e m1 m2 ...)
2973 (with-syntax
2974 ((body (let f ((clause #'m1) (clauses #'(m2 ...)))
2975 (if (null? clauses)
2976 (syntax-case clause (else)
2977 ((else e1 e2 ...) #'(begin e1 e2 ...))
2978 (((k ...) e1 e2 ...)
2979 #'(if (memv t '(k ...)) (begin e1 e2 ...)))
2980 (_ (syntax-violation 'case "bad clause" x clause)))
2981 (with-syntax ((rest (f (car clauses) (cdr clauses))))
2982 (syntax-case clause (else)
2983 (((k ...) e1 e2 ...)
2984 #'(if (memv t '(k ...))
2985 (begin e1 e2 ...)
2986 rest))
2987 (_ (syntax-violation 'case "bad clause" x
2988 clause))))))))
2989 #'(let ((t e)) body))))))
2990
2991 (define (make-variable-transformer proc)
2992 (if (procedure? proc)
2993 (let ((trans (lambda (x)
2994 #((macro-type . variable-transformer))
2995 (proc x))))
2996 (set-procedure-property! trans 'variable-transformer #t)
2997 trans)
2998 (error "variable transformer not a procedure" proc)))
2999
3000 (define-syntax identifier-syntax
3001 (lambda (x)
3002 (syntax-case x (set!)
3003 ((_ e)
3004 #'(lambda (x)
3005 #((macro-type . identifier-syntax))
3006 (syntax-case x ()
3007 (id
3008 (identifier? #'id)
3009 #'e)
3010 ((_ x (... ...))
3011 #'(e x (... ...))))))
3012 ((_ (id exp1) ((set! var val) exp2))
3013 (and (identifier? #'id) (identifier? #'var))
3014 #'(make-variable-transformer
3015 (lambda (x)
3016 #((macro-type . variable-transformer))
3017 (syntax-case x (set!)
3018 ((set! var val) #'exp2)
3019 ((id x (... ...)) #'(exp1 x (... ...)))
3020 (id (identifier? #'id) #'exp1))))))))
3021
3022 (define-syntax define*
3023 (lambda (x)
3024 (syntax-case x ()
3025 ((_ (id . args) b0 b1 ...)
3026 #'(define id (lambda* args b0 b1 ...)))
3027 ((_ id val) (identifier? #'x)
3028 #'(define id val)))))