*** empty log message ***
[bpt/guile.git] / ice-9 / psyntax.ss
CommitLineData
a63812a2
JB
1;;; Portable implementation of syntax-case
2;;; Extracted from Chez Scheme Version 5.9f
3;;; Authors: R. Kent Dybvig, Oscar Waddell, Bob Hieb, Carl Bruggeman
4
5;;; Copyright (c) 1992-1997 Cadence Research Systems
6;;; Permission to copy this software, in whole or in part, to use this
7;;; software for any lawful purpose, and to redistribute this software
8;;; is granted subject to the restriction that all copies made of this
9;;; software must include this copyright notice in full. This software
10;;; is provided AS IS, with NO WARRANTY, EITHER EXPRESS OR IMPLIED,
11;;; INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY
12;;; OR FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE
13;;; AUTHORS BE LIABLE FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES OF ANY
14;;; NATURE WHATSOEVER.
15
16
17;;; Before attempting to port this code to a new implementation of
18;;; Scheme, please read the notes below carefully.
19
20
21;;; This file defines the syntax-case expander, sc-expand, and a set
22;;; of associated syntactic forms and procedures. Of these, the
23;;; following are documented in The Scheme Programming Language,
24;;; Second Edition (R. Kent Dybvig, Prentice Hall, 1996). Most are
25;;; also documented in the R4RS and draft R5RS.
26;;;
27;;; bound-identifier=?
28;;; datum->syntax-object
29;;; define-syntax
30;;; fluid-let-syntax
31;;; free-identifier=?
32;;; generate-temporaries
33;;; identifier?
34;;; identifier-syntax
35;;; let-syntax
36;;; letrec-syntax
37;;; syntax
38;;; syntax-case
39;;; syntax-object->datum
40;;; syntax-rules
41;;; with-syntax
42;;;
43;;; All standard Scheme syntactic forms are supported by the expander
44;;; or syntactic abstractions defined in this file. Only the R4RS
45;;; delay is omitted, since its expansion is implementation-dependent.
46
47;;; The remaining exports are listed below:
48;;;
49;;; (sc-expand datum)
50;;; if datum represents a valid expression, sc-expand returns an
51;;; expanded version of datum in a core language that includes no
52;;; syntactic abstractions. The core language includes begin,
53;;; define, if, lambda, letrec, quote, and set!.
54;;; (eval-when situations expr ...)
55;;; conditionally evaluates expr ... at compile-time or run-time
56;;; depending upon situations (see the Chez Scheme System Manual,
57;;; Revision 3, for a complete description)
58;;; (syntax-error object message)
59;;; used to report errors found during expansion
60;;; (install-global-transformer symbol value)
61;;; used by expanded code to install top-level syntactic abstractions
62;;; (syntax-dispatch e p)
63;;; used by expanded code to handle syntax-case matching
64
65;;; The following nonstandard procedures must be provided by the
66;;; implementation for this code to run.
67;;;
68;;; (void)
69;;; returns the implementation's cannonical "unspecified value". This
70;;; usually works: (define void (lambda () (if #f #f))).
71;;;
72;;; (andmap proc list1 list2 ...)
73;;; returns true if proc returns true when applied to each element of list1
74;;; along with the corresponding elements of list2 ....
75;;; The following definition works but does no error checking:
76;;;
77;;; (define andmap
78;;; (lambda (f first . rest)
79;;; (or (null? first)
80;;; (if (null? rest)
81;;; (let andmap ((first first))
82;;; (let ((x (car first)) (first (cdr first)))
83;;; (if (null? first)
84;;; (f x)
85;;; (and (f x) (andmap first)))))
86;;; (let andmap ((first first) (rest rest))
87;;; (let ((x (car first))
88;;; (xr (map car rest))
89;;; (first (cdr first))
90;;; (rest (map cdr rest)))
91;;; (if (null? first)
92;;; (apply f (cons x xr))
93;;; (and (apply f (cons x xr)) (andmap first rest)))))))))
94;;;
95;;; The following nonstandard procedures must also be provided by the
96;;; implementation for this code to run using the standard portable
97;;; hooks and output constructors. They are not used by expanded code,
98;;; and so need be present only at expansion time.
99;;;
100;;; (eval x)
101;;; where x is always in the form ("noexpand" expr).
102;;; returns the value of expr. the "noexpand" flag is used to tell the
103;;; evaluator/expander that no expansion is necessary, since expr has
104;;; already been fully expanded to core forms.
105;;;
106;;; eval will not be invoked during the loading of psyntax.pp. After
107;;; psyntax.pp has been loaded, the expansion of any macro definition,
108;;; whether local or global, will result in a call to eval. If, however,
109;;; sc-expand has already been registered as the expander to be used
110;;; by eval, and eval accepts one argument, nothing special must be done
111;;; to support the "noexpand" flag, since it is handled by sc-expand.
112;;;
113;;; (error who format-string why what)
114;;; where who is either a symbol or #f, format-string is always "~a ~s",
115;;; why is always a string, and what may be any object. error should
116;;; signal an error with a message something like
117;;;
118;;; "error in <who>: <why> <what>"
119;;;
120;;; (gensym)
121;;; returns a unique symbol each time it's called
122;;;
123;;; (putprop symbol key value)
124;;; (getprop symbol key)
125;;; key is always the symbol *sc-expander*; value may be any object.
126;;; putprop should associate the given value with the given symbol in
127;;; some way that it can be retrieved later with getprop.
128
129;;; When porting to a new Scheme implementation, you should define the
130;;; procedures listed above, load the expanded version of psyntax.ss
131;;; (psyntax.pp, which should be available whereever you found
132;;; psyntax.ss), and register sc-expand as the current expander (how
133;;; you do this depends upon your implementation of Scheme). You may
134;;; change the hooks and constructors defined toward the beginning of
135;;; the code below, but to avoid bootstrapping problems, do so only
136;;; after you have a working version of the expander.
137
138;;; Chez Scheme allows the syntactic form (syntax <template>) to be
139;;; abbreviated to #'<template>, just as (quote <datum>) may be
140;;; abbreviated to '<datum>. The #' syntax makes programs written
141;;; using syntax-case shorter and more readable and draws out the
142;;; intuitive connection between syntax and quote.
143
144;;; If you find that this code loads or runs slowly, consider
145;;; switching to faster hardware or a faster implementation of
146;;; Scheme. In Chez Scheme on a 200Mhz Pentium Pro, expanding,
147;;; compiling (with full optimization), and loading this file takes
148;;; between one and two seconds.
149
150;;; In the expander implementation, we sometimes use syntactic abstractions
151;;; when procedural abstractions would suffice. For example, we define
152;;; top-wrap and top-marked? as
153;;; (define-syntax top-wrap (identifier-syntax '((top))))
154;;; (define-syntax top-marked?
155;;; (syntax-rules ()
156;;; ((_ w) (memq 'top (wrap-marks w)))))
157;;; rather than
158;;; (define top-wrap '((top)))
159;;; (define top-marked?
160;;; (lambda (w) (memq 'top (wrap-marks w))))
161;;; On ther other hand, we don't do this consistently; we define make-wrap,
162;;; wrap-marks, and wrap-subst simply as
163;;; (define make-wrap cons)
164;;; (define wrap-marks car)
165;;; (define wrap-subst cdr)
166;;; In Chez Scheme, the syntactic and procedural forms of these
167;;; abstractions are equivalent, since the optimizer consistently
168;;; integrates constants and small procedures. Some Scheme
169;;; implementations, however, may benefit from more consistent use
170;;; of one form or the other.
171
172
173;;; implementation information:
174
175;;; "begin" is treated as a splicing construct at top level and at
176;;; the beginning of bodies. Any sequence of expressions that would
177;;; be allowed where the "begin" occurs is allowed.
178
179;;; "let-syntax" and "letrec-syntax" are also treated as splicing
180;;; constructs, in violation of the R4RS appendix and probably the R5RS
181;;; when it comes out. A consequence, let-syntax and letrec-syntax do
182;;; not create local contours, as do let and letrec. Although the
183;;; functionality is greater as it is presently implemented, we will
184;;; probably change it to conform to the R4RS/expected R5RS.
185
186;;; Objects with no standard print syntax, including objects containing
187;;; cycles and syntax object, are allowed in quoted data as long as they
188;;; are contained within a syntax form or produced by datum->syntax-object.
189;;; Such objects are never copied.
190
191;;; All identifiers that don't have macro definitions and are not bound
192;;; lexically are assumed to be global variables
193
194;;; Top-level definitions of macro-introduced identifiers are allowed.
195;;; This may not be appropriate for implementations in which the
196;;; model is that bindings are created by definitions, as opposed to
197;;; one in which initial values are assigned by definitions.
198
199;;; Top-level variable definitions of syntax keywords is not permitted.
200;;; Any solution allowing this would be kludgey and would yield
201;;; surprising results in some cases. We can provide an undefine-syntax
202;;; form. The questions is, should define be an implicit undefine-syntax?
203;;; We've decided no for now.
204
205;;; Identifiers and syntax objects are implemented as vectors for
206;;; portability. As a result, it is possible to "forge" syntax
207;;; objects.
208
209;;; The implementation of generate-temporaries assumes that it is possible
210;;; to generate globally unique symbols (gensyms).
211
212;;; The input to sc-expand may contain "annotations" describing, e.g., the
213;;; source file and character position from where each object was read if
214;;; it was read from a file. These annotations are handled properly by
215;;; sc-expand only if the annotation? hook (see hooks below) is implemented
216;;; properly and the operators make-annotation, annotation-expression,
217;;; annotation-source, annotation-stripped, and set-annotation-stripped!
218;;; are supplied. If annotations are supplied, the proper annotation
219;;; source is passed to the various output constructors, allowing
220;;; implementations to accurately correlate source and expanded code.
221;;; Contact one of the authors for details if you wish to make use of
222;;; this feature.
223
224
225
226;;; Bootstrapping:
227
228;;; When changing syntax-object representations, it is necessary to support
229;;; both old and new syntax-object representations in id-var-name. It
230;;; should be sufficient to recognize old representations and treat
231;;; them as not lexically bound.
232
233
234
235(let ()
236(define-syntax define-structure
237 (lambda (x)
238 (define construct-name
239 (lambda (template-identifier . args)
240 (datum->syntax-object
241 template-identifier
242 (string->symbol
243 (apply string-append
244 (map (lambda (x)
245 (if (string? x)
246 x
247 (symbol->string (syntax-object->datum x))))
248 args))))))
249 (syntax-case x ()
250 ((_ (name id1 ...))
251 (andmap identifier? (syntax (name id1 ...)))
252 (with-syntax
253 ((constructor (construct-name (syntax name) "make-" (syntax name)))
254 (predicate (construct-name (syntax name) (syntax name) "?"))
255 ((access ...)
256 (map (lambda (x) (construct-name x (syntax name) "-" x))
257 (syntax (id1 ...))))
258 ((assign ...)
259 (map (lambda (x)
260 (construct-name x "set-" (syntax name) "-" x "!"))
261 (syntax (id1 ...))))
262 (structure-length
263 (+ (length (syntax (id1 ...))) 1))
264 ((index ...)
265 (let f ((i 1) (ids (syntax (id1 ...))))
266 (if (null? ids)
267 '()
268 (cons i (f (+ i 1) (cdr ids)))))))
269 (syntax (begin
270 (define constructor
271 (lambda (id1 ...)
272 (vector 'name id1 ... )))
273 (define predicate
274 (lambda (x)
275 (and (vector? x)
276 (= (vector-length x) structure-length)
277 (eq? (vector-ref x 0) 'name))))
278 (define access
279 (lambda (x)
280 (vector-ref x index)))
281 ...
282 (define assign
283 (lambda (x update)
284 (vector-set! x index update)))
285 ...)))))))
286
287(let ()
288(define noexpand "noexpand")
289
290;;; hooks to nonportable run-time helpers
291(begin
292(define fx+ +)
293(define fx- -)
294(define fx= =)
295(define fx< <)
296
297(define annotation? (lambda (x) #f))
298
299(define top-level-eval-hook
300 (lambda (x)
301 (eval `(,noexpand ,x))))
302
303(define local-eval-hook
304 (lambda (x)
305 (eval `(,noexpand ,x))))
306
307(define error-hook
308 (lambda (who why what)
309 (error who "~a ~s" why what)))
310
311(define-syntax gensym-hook
312 (syntax-rules ()
313 ((_) (gensym))))
314
315(define put-global-definition-hook
316 (lambda (symbol binding)
317 (putprop symbol '*sc-expander* binding)))
318
319(define get-global-definition-hook
320 (lambda (symbol)
321 (getprop symbol '*sc-expander*)))
322)
323
324
325;;; output constructors
326(begin
327(define-syntax build-application
328 (syntax-rules ()
329 ((_ source fun-exp arg-exps)
330 `(,fun-exp . ,arg-exps))))
331
332(define-syntax build-conditional
333 (syntax-rules ()
334 ((_ source test-exp then-exp else-exp)
335 `(if ,test-exp ,then-exp ,else-exp))))
336
337(define-syntax build-lexical-reference
338 (syntax-rules ()
339 ((_ type source var)
340 var)))
341
342(define-syntax build-lexical-assignment
343 (syntax-rules ()
344 ((_ source var exp)
345 `(set! ,var ,exp))))
346
347(define-syntax build-global-reference
348 (syntax-rules ()
349 ((_ source var)
350 var)))
351
352(define-syntax build-global-assignment
353 (syntax-rules ()
354 ((_ source var exp)
355 `(set! ,var ,exp))))
356
357(define-syntax build-global-definition
358 (syntax-rules ()
359 ((_ source var exp)
360 `(define ,var ,exp))))
361
362(define-syntax build-lambda
363 (syntax-rules ()
364 ((_ src vars exp)
365 `(lambda ,vars ,exp))))
366
367(define-syntax build-primref
368 (syntax-rules ()
369 ((_ src name) name)
370 ((_ src level name) name)))
371
372(define-syntax build-data
373 (syntax-rules ()
374 ((_ src exp) `',exp)))
375
376(define build-sequence
377 (lambda (src exps)
378 (if (null? (cdr exps))
379 (car exps)
380 `(begin ,@exps))))
381
382(define build-let
383 (lambda (src vars val-exps body-exp)
384 (if (null? vars)
385 body-exp
386 `(let ,(map list vars val-exps) ,body-exp))))
387
388(define build-named-let
389 (lambda (src vars val-exps body-exp)
390 (if (null? vars)
391 body-exp
392 `(let ,(car vars) ,(map list (cdr vars) val-exps) ,body-exp))))
393
394(define build-letrec
395 (lambda (src vars val-exps body-exp)
396 (if (null? vars)
397 body-exp
398 `(letrec ,(map list vars val-exps) ,body-exp))))
399
400(define-syntax build-lexical-var
401 (syntax-rules ()
402 ((_ src id) (gensym id generated-symbols))))
403
404(define-syntax self-evaluating?
405 (syntax-rules ()
406 ((_ e)
407 (let ((x e))
408 (or (boolean? x) (number? x) (string? x) (char? x) (null? x) (keyword? x))))))
409)
410
411(define-structure (syntax-object expression wrap))
412
413(define-syntax unannotate
414 (syntax-rules ()
415 ((_ x)
416 (let ((e x))
417 (if (annotation? e)
418 (annotation-expression e)
419 e)))))
420
421(define-syntax no-source (identifier-syntax #f))
422
423(define source-annotation
424 (lambda (x)
425 (cond
426 ((annotation? x) (annotation-source x))
427 ((syntax-object? x) (source-annotation (syntax-object-expression x)))
428 (else no-source))))
429
430(define-syntax arg-check
431 (syntax-rules ()
432 ((_ pred? e who)
433 (let ((x e))
434 (if (not (pred? x)) (error-hook who "invalid argument" x))))))
435
436;;; compile-time environments
437
438;;; wrap and environment comprise two level mapping.
439;;; wrap : id --> label
440;;; env : label --> <element>
441
442;;; environments are represented in two parts: a lexical part and a global
443;;; part. The lexical part is a simple list of associations from labels
444;;; to bindings. The global part is implemented by
445;;; {put,get}-global-definition-hook and associates symbols with
446;;; bindings.
447
448;;; global (assumed global variable) and displaced-lexical (see below)
449;;; do not show up in any environment; instead, they are fabricated by
450;;; lookup when it finds no other bindings.
451
452;;; <environment> ::= ((<label> . <binding>)*)
453
454;;; identifier bindings include a type and a value
455
456;;; <binding> ::= (macro . <procedure>) macros
457;;; (core . <procedure>) core forms
458;;; (begin) begin
459;;; (define) define
460;;; (define-syntax) define-syntax
461;;; (local-syntax . rec?) let-syntax/letrec-syntax
462;;; (eval-when) eval-when
463;;; (syntax . (<var> . <level>)) pattern variables
464;;; (global) assumed global variable
465;;; (lexical . <var>) lexical variables
466;;; (displaced-lexical) displaced lexicals
467;;; <level> ::= <nonnegative integer>
468;;; <var> ::= variable returned by build-lexical-var
469
470;;; a macro is a user-defined syntactic-form. a core is a system-defined
471;;; syntactic form. begin, define, define-syntax, and eval-when are
472;;; treated specially since they are sensitive to whether the form is
473;;; at top-level and (except for eval-when) can denote valid internal
474;;; definitions.
475
476;;; a pattern variable is a variable introduced by syntax-case and can
477;;; be referenced only within a syntax form.
478
479;;; any identifier for which no top-level syntax definition or local
480;;; binding of any kind has been seen is assumed to be a global
481;;; variable.
482
483;;; a lexical variable is a lambda- or letrec-bound variable.
484
485;;; a displaced-lexical identifier is a lexical identifier removed from
486;;; it's scope by the return of a syntax object containing the identifier.
487;;; a displaced lexical can also appear when a letrec-syntax-bound
488;;; keyword is referenced on the rhs of one of the letrec-syntax clauses.
489;;; a displaced lexical should never occur with properly written macros.
490
491(define-syntax make-binding
492 (syntax-rules (quote)
493 ((_ type value) (cons type value))
494 ((_ 'type) '(type))
495 ((_ type) (cons type '()))))
496(define binding-type car)
497(define binding-value cdr)
498
499(define-syntax null-env (identifier-syntax '()))
500
501(define extend-env
502 (lambda (labels bindings r)
503 (if (null? labels)
504 r
505 (extend-env (cdr labels) (cdr bindings)
506 (cons (cons (car labels) (car bindings)) r)))))
507
508(define extend-var-env
509 ; variant of extend-env that forms "lexical" binding
510 (lambda (labels vars r)
511 (if (null? labels)
512 r
513 (extend-var-env (cdr labels) (cdr vars)
514 (cons (cons (car labels) (make-binding 'lexical (car vars))) r)))))
515
516;;; we use a "macros only" environment in expansion of local macro
517;;; definitions so that their definitions can use local macros without
518;;; attempting to use other lexical identifiers.
519(define macros-only-env
520 (lambda (r)
521 (if (null? r)
522 '()
523 (let ((a (car r)))
524 (if (eq? (cadr a) 'macro)
525 (cons a (macros-only-env (cdr r)))
526 (macros-only-env (cdr r)))))))
527
528(define lookup
529 ; x may be a label or a symbol
530 ; although symbols are usually global, we check the environment first
531 ; anyway because a temporary binding may have been established by
532 ; fluid-let-syntax
533 (lambda (x r)
534 (cond
535 ((assq x r) => cdr)
536 ((symbol? x)
537 (or (get-global-definition-hook x) (make-binding 'global)))
538 (else (make-binding 'displaced-lexical)))))
539
540(define global-extend
541 (lambda (type sym val)
542 (put-global-definition-hook sym (make-binding type val))))
543
544
545;;; Conceptually, identifiers are always syntax objects. Internally,
546;;; however, the wrap is sometimes maintained separately (a source of
547;;; efficiency and confusion), so that symbols are also considered
548;;; identifiers by id?. Externally, they are always wrapped.
549
550(define nonsymbol-id?
551 (lambda (x)
552 (and (syntax-object? x)
553 (symbol? (unannotate (syntax-object-expression x))))))
554
555(define id?
556 (lambda (x)
557 (cond
558 ((symbol? x) #t)
559 ((syntax-object? x) (symbol? (unannotate (syntax-object-expression x))))
560 ((annotation? x) (symbol? (annotation-expression x)))
561 (else #f))))
562
563(define-syntax id-sym-name
564 (syntax-rules ()
565 ((_ e)
566 (let ((x e))
567 (unannotate (if (syntax-object? x) (syntax-object-expression x) x))))))
568
569(define id-sym-name&marks
570 (lambda (x w)
571 (if (syntax-object? x)
572 (values
573 (unannotate (syntax-object-expression x))
574 (join-marks (wrap-marks w) (wrap-marks (syntax-object-wrap x))))
575 (values (unannotate x) (wrap-marks w)))))
576
577;;; syntax object wraps
578
579;;; <wrap> ::= ((<mark> ...) . (<subst> ...))
580;;; <subst> ::= <shift> | <subs>
581;;; <subs> ::= #(<old name> <label> (<mark> ...))
582;;; <shift> ::= positive fixnum
583
584(define make-wrap cons)
585(define wrap-marks car)
586(define wrap-subst cdr)
587
588(define-syntax subst-rename? (identifier-syntax vector?))
589(define-syntax rename-old (syntax-rules () ((_ x) (vector-ref x 0))))
590(define-syntax rename-new (syntax-rules () ((_ x) (vector-ref x 1))))
591(define-syntax rename-marks (syntax-rules () ((_ x) (vector-ref x 2))))
592(define-syntax make-rename
593 (syntax-rules ()
594 ((_ old new marks) (vector old new marks))))
595
596;;; labels must be comparable with "eq?" and distinct from symbols.
597(define gen-label
598 (lambda () (string #\i)))
599
600(define gen-labels
601 (lambda (ls)
602 (if (null? ls)
603 '()
604 (cons (gen-label) (gen-labels (cdr ls))))))
605
606(define-structure (ribcage symnames marks labels))
607
608(define-syntax empty-wrap (identifier-syntax '(())))
609
610(define-syntax top-wrap (identifier-syntax '((top))))
611
612(define-syntax top-marked?
613 (syntax-rules ()
614 ((_ w) (memq 'top (wrap-marks w)))))
615
616;;; Marks must be comparable with "eq?" and distinct from pairs and
617;;; the symbol top. We do not use integers so that marks will remain
618;;; unique even across file compiles.
619
620(define-syntax the-anti-mark (identifier-syntax #f))
621
622(define anti-mark
623 (lambda (w)
624 (make-wrap (cons the-anti-mark (wrap-marks w))
625 (cons 'shift (wrap-subst w)))))
626
627(define-syntax new-mark
628 (syntax-rules ()
629 ((_) (string #\m))))
630
631;;; make-empty-ribcage and extend-ribcage maintain list-based ribcages for
632;;; internal definitions, in which the ribcages are built incrementally
633(define-syntax make-empty-ribcage
634 (syntax-rules ()
635 ((_) (make-ribcage '() '() '()))))
636
637(define extend-ribcage!
638 ; must receive ids with complete wraps
639 (lambda (ribcage id label)
640 (set-ribcage-symnames! ribcage
641 (cons (unannotate (syntax-object-expression id))
642 (ribcage-symnames ribcage)))
643 (set-ribcage-marks! ribcage
644 (cons (wrap-marks (syntax-object-wrap id))
645 (ribcage-marks ribcage)))
646 (set-ribcage-labels! ribcage
647 (cons label (ribcage-labels ribcage)))))
648
649;;; make-binding-wrap creates vector-based ribcages
650(define make-binding-wrap
651 (lambda (ids labels w)
652 (if (null? ids)
653 w
654 (make-wrap
655 (wrap-marks w)
656 (cons
657 (let ((labelvec (list->vector labels)))
658 (let ((n (vector-length labelvec)))
659 (let ((symnamevec (make-vector n)) (marksvec (make-vector n)))
660 (let f ((ids ids) (i 0))
661 (if (not (null? ids))
662 (call-with-values
663 (lambda () (id-sym-name&marks (car ids) w))
664 (lambda (symname marks)
665 (vector-set! symnamevec i symname)
666 (vector-set! marksvec i marks)
667 (f (cdr ids) (fx+ i 1))))))
668 (make-ribcage symnamevec marksvec labelvec))))
669 (wrap-subst w))))))
670
671(define smart-append
672 (lambda (m1 m2)
673 (if (null? m2)
674 m1
675 (append m1 m2))))
676
677(define join-wraps
678 (lambda (w1 w2)
679 (let ((m1 (wrap-marks w1)) (s1 (wrap-subst w1)))
680 (if (null? m1)
681 (if (null? s1)
682 w2
683 (make-wrap
684 (wrap-marks w2)
685 (smart-append s1 (wrap-subst w2))))
686 (make-wrap
687 (smart-append m1 (wrap-marks w2))
688 (smart-append s1 (wrap-subst w2)))))))
689
690(define join-marks
691 (lambda (m1 m2)
692 (smart-append m1 m2)))
693
694(define same-marks?
695 (lambda (x y)
696 (or (eq? x y)
697 (and (not (null? x))
698 (not (null? y))
699 (eq? (car x) (car y))
700 (same-marks? (cdr x) (cdr y))))))
701
702(define id-var-name
703 (lambda (id w)
704 (define-syntax first
705 (syntax-rules ()
706 ((_ e) (call-with-values (lambda () e) (lambda (x . ignore) x)))))
707 (define search
708 (lambda (sym subst marks)
709 (if (null? subst)
710 (values #f marks)
711 (let ((fst (car subst)))
712 (if (eq? fst 'shift)
713 (search sym (cdr subst) (cdr marks))
714 (let ((symnames (ribcage-symnames fst)))
715 (if (vector? symnames)
716 (search-vector-rib sym subst marks symnames fst)
717 (search-list-rib sym subst marks symnames fst))))))))
718 (define search-list-rib
719 (lambda (sym subst marks symnames ribcage)
720 (let f ((symnames symnames) (i 0))
721 (cond
722 ((null? symnames) (search sym (cdr subst) marks))
723 ((and (eq? (car symnames) sym)
724 (same-marks? marks (list-ref (ribcage-marks ribcage) i)))
725 (values (list-ref (ribcage-labels ribcage) i) marks))
726 (else (f (cdr symnames) (fx+ i 1)))))))
727 (define search-vector-rib
728 (lambda (sym subst marks symnames ribcage)
729 (let ((n (vector-length symnames)))
730 (let f ((i 0))
731 (cond
732 ((fx= i n) (search sym (cdr subst) marks))
733 ((and (eq? (vector-ref symnames i) sym)
734 (same-marks? marks (vector-ref (ribcage-marks ribcage) i)))
735 (values (vector-ref (ribcage-labels ribcage) i) marks))
736 (else (f (fx+ i 1))))))))
737 (cond
738 ((symbol? id)
739 (or (first (search id (wrap-subst w) (wrap-marks w))) id))
740 ((syntax-object? id)
741 (let ((id (unannotate (syntax-object-expression id)))
742 (w1 (syntax-object-wrap id)))
743 (let ((marks (join-marks (wrap-marks w) (wrap-marks w1))))
744 (call-with-values (lambda () (search id (wrap-subst w) marks))
745 (lambda (new-id marks)
746 (or new-id
747 (first (search id (wrap-subst w1) marks))
748 id))))))
749 ((annotation? id)
750 (let ((id (unannotate id)))
751 (or (first (search id (wrap-subst w) (wrap-marks w))) id)))
752 (else (error-hook 'id-var-name "invalid id" id)))))
753
754;;; free-id=? must be passed fully wrapped ids since (free-id=? x y)
755;;; may be true even if (free-id=? (wrap x w) (wrap y w)) is not.
756
757(define free-id=?
758 (lambda (i j)
759 (and (eq? (id-sym-name i) (id-sym-name j)) ; accelerator
760 (eq? (id-var-name i empty-wrap) (id-var-name j empty-wrap)))))
761
762;;; bound-id=? may be passed unwrapped (or partially wrapped) ids as
763;;; long as the missing portion of the wrap is common to both of the ids
764;;; since (bound-id=? x y) iff (bound-id=? (wrap x w) (wrap y w))
765
766(define bound-id=?
767 (lambda (i j)
768 (if (and (syntax-object? i) (syntax-object? j))
769 (and (eq? (unannotate (syntax-object-expression i))
770 (unannotate (syntax-object-expression j)))
771 (same-marks? (wrap-marks (syntax-object-wrap i))
772 (wrap-marks (syntax-object-wrap j))))
773 (eq? (unannotate i) (unannotate j)))))
774
775;;; "valid-bound-ids?" returns #t if it receives a list of distinct ids.
776;;; valid-bound-ids? may be passed unwrapped (or partially wrapped) ids
777;;; as long as the missing portion of the wrap is common to all of the
778;;; ids.
779
780(define valid-bound-ids?
781 (lambda (ids)
782 (and (let all-ids? ((ids ids))
783 (or (null? ids)
784 (and (id? (car ids))
785 (all-ids? (cdr ids)))))
786 (distinct-bound-ids? ids))))
787
788;;; distinct-bound-ids? expects a list of ids and returns #t if there are
789;;; no duplicates. It is quadratic on the length of the id list; long
790;;; lists could be sorted to make it more efficient. distinct-bound-ids?
791;;; may be passed unwrapped (or partially wrapped) ids as long as the
792;;; missing portion of the wrap is common to all of the ids.
793
794(define distinct-bound-ids?
795 (lambda (ids)
796 (let distinct? ((ids ids))
797 (or (null? ids)
798 (and (not (bound-id-member? (car ids) (cdr ids)))
799 (distinct? (cdr ids)))))))
800
801(define bound-id-member?
802 (lambda (x list)
803 (and (not (null? list))
804 (or (bound-id=? x (car list))
805 (bound-id-member? x (cdr list))))))
806
807;;; wrapping expressions and identifiers
808
809(define wrap
810 (lambda (x w)
811 (cond
812 ((and (null? (wrap-marks w)) (null? (wrap-subst w))) x)
813 ((syntax-object? x)
814 (make-syntax-object
815 (syntax-object-expression x)
816 (join-wraps w (syntax-object-wrap x))))
817 ((null? x) x)
818 (else (make-syntax-object x w)))))
819
820(define source-wrap
821 (lambda (x w s)
822 (wrap (if s (make-annotation x s #f) x) w)))
823
824;;; expanding
825
826(define chi-sequence
827 (lambda (body r w s)
828 (build-sequence s
829 (let dobody ((body body) (r r) (w w))
830 (if (null? body)
831 '()
832 (let ((first (chi (car body) r w)))
833 (cons first (dobody (cdr body) r w))))))))
834
835(define chi-top-sequence
836 (lambda (body r w s m esew)
837 (build-sequence s
838 (let dobody ((body body) (r r) (w w) (m m) (esew esew))
839 (if (null? body)
840 '()
841 (let ((first (chi-top (car body) r w m esew)))
842 (cons first (dobody (cdr body) r w m esew))))))))
843
844(define chi-install-global
845 (lambda (name e)
846 (build-application no-source
847 (build-primref no-source 'install-global-transformer)
848 (list (build-data no-source name) e))))
849
850(define chi-when-list
851 (lambda (e when-list w)
852 ; when-list is syntax'd version of list of situations
853 (let f ((when-list when-list) (situations '()))
854 (if (null? when-list)
855 situations
856 (f (cdr when-list)
857 (cons (let ((x (car when-list)))
858 (cond
859 ((free-id=? x (syntax compile)) 'compile)
860 ((free-id=? x (syntax load)) 'load)
861 ((free-id=? x (syntax eval)) 'eval)
862 (else (syntax-error (wrap x w)
863 "invalid eval-when situation"))))
864 situations))))))
865
866;;; syntax-type returns five values: type, value, e, w, and s. The first
867;;; two are described in the table below.
868;;;
869;;; type value explanation
870;;; -------------------------------------------------------------------
871;;; core procedure core form (including singleton)
872;;; lexical name lexical variable reference
873;;; global name global variable reference
874;;; begin none begin keyword
875;;; define none define keyword
876;;; define-syntax none define-syntax keyword
877;;; local-syntax rec? letrec-syntax/let-syntax keyword
878;;; eval-when none eval-when keyword
879;;; syntax level pattern variable
880;;; displaced-lexical none displaced lexical identifier
881;;; lexical-call name call to lexical variable
882;;; global-call name call to global variable
883;;; call none any other call
884;;; begin-form none begin expression
885;;; define-form id variable definition
886;;; define-syntax-form id syntax definition
887;;; local-syntax-form rec? syntax definition
888;;; eval-when-form none eval-when form
889;;; constant none self-evaluating datum
890;;; other none anything else
891;;;
892;;; For define-form and define-syntax-form, e is the rhs expression.
893;;; For all others, e is the entire form. w is the wrap for e.
894;;; s is the source for the entire form.
895;;;
896;;; syntax-type expands macros and unwraps as necessary to get to
897;;; one of the forms above. It also parses define and define-syntax
898;;; forms, although perhaps this should be done by the consumer.
899
900(define syntax-type
901 (lambda (e r w s rib)
902 (cond
903 ((symbol? e)
904 (let* ((n (id-var-name e w))
905 (b (lookup n r))
906 (type (binding-type b)))
907 (case type
908 ((lexical) (values type (binding-value b) e w s))
909 ((global) (values type n e w s))
910 ((macro)
911 (syntax-type (chi-macro (binding-value b) e r w rib) r empty-wrap s rib))
912 (else (values type (binding-value b) e w s)))))
913 ((pair? e)
914 (let ((first (car e)))
915 (if (id? first)
916 (let* ((n (id-var-name first w))
917 (b (lookup n r))
918 (type (binding-type b)))
919 (case type
920 ((lexical) (values 'lexical-call (binding-value b) e w s))
921 ((global) (values 'global-call n e w s))
922 ((macro)
923 (syntax-type (chi-macro (binding-value b) e r w rib)
924 r empty-wrap s rib))
925 ((core) (values type (binding-value b) e w s))
926 ((local-syntax)
927 (values 'local-syntax-form (binding-value b) e w s))
928 ((begin) (values 'begin-form #f e w s))
929 ((eval-when) (values 'eval-when-form #f e w s))
930 ((define)
931 (syntax-case e ()
932 ((_ name val)
933 (id? (syntax name))
934 (values 'define-form (syntax name) (syntax val) w s))
935 ((_ (name . args) e1 e2 ...)
936 (and (id? (syntax name))
937 (valid-bound-ids? (lambda-var-list (syntax args))))
938 ; need lambda here...
939 (values 'define-form (wrap (syntax name) w)
940 (cons (syntax lambda) (wrap (syntax (args e1 e2 ...)) w))
941 empty-wrap s))
942 ((_ name)
943 (id? (syntax name))
944 (values 'define-form (wrap (syntax name) w)
945 (syntax (void))
946 empty-wrap s))))
947 ((define-syntax)
948 (syntax-case e ()
949 ((_ name val)
950 (id? (syntax name))
951 (values 'define-syntax-form (syntax name)
952 (syntax val) w s))))
953 (else (values 'call #f e w s))))
954 (values 'call #f e w s))))
955 ((syntax-object? e)
956 ;; s can't be valid source if we've unwrapped
957 (syntax-type (syntax-object-expression e)
958 r
959 (join-wraps w (syntax-object-wrap e))
960 no-source rib))
961 ((annotation? e)
962 (syntax-type (annotation-expression e) r w (annotation-source e) rib))
963 ((self-evaluating? e) (values 'constant #f e w s))
964 (else (values 'other #f e w s)))))
965
966(define chi-top
967 (lambda (e r w m esew)
968 (define-syntax eval-if-c&e
969 (syntax-rules ()
970 ((_ m e)
971 (let ((x e))
972 (if (eq? m 'c&e) (top-level-eval-hook x))
973 x))))
974 (call-with-values
975 (lambda () (syntax-type e r w no-source #f))
976 (lambda (type value e w s)
977 (case type
978 ((begin-form)
979 (syntax-case e ()
980 ((_) (chi-void))
981 ((_ e1 e2 ...)
982 (chi-top-sequence (syntax (e1 e2 ...)) r w s m esew))))
983 ((local-syntax-form)
984 (chi-local-syntax value e r w s
985 (lambda (body r w s)
986 (chi-top-sequence body r w s m esew))))
987 ((eval-when-form)
988 (syntax-case e ()
989 ((_ (x ...) e1 e2 ...)
990 (let ((when-list (chi-when-list e (syntax (x ...)) w))
991 (body (syntax (e1 e2 ...))))
992 (cond
993 ((eq? m 'e)
994 (if (memq 'eval when-list)
995 (chi-top-sequence body r w s 'e '(eval))
996 (chi-void)))
997 ((memq 'load when-list)
998 (if (or (memq 'compile when-list)
999 (and (eq? m 'c&e) (memq 'eval when-list)))
1000 (chi-top-sequence body r w s 'c&e '(compile load))
1001 (if (memq m '(c c&e))
1002 (chi-top-sequence body r w s 'c '(load))
1003 (chi-void))))
1004 ((or (memq 'compile when-list)
1005 (and (eq? m 'c&e) (memq 'eval when-list)))
1006 (top-level-eval-hook
1007 (chi-top-sequence body r w s 'e '(eval)))
1008 (chi-void))
1009 (else (chi-void)))))))
1010 ((define-syntax-form)
1011 (let ((n (id-var-name value w)) (r (macros-only-env r)))
1012 (case m
1013 ((c)
1014 (if (memq 'compile esew)
1015 (let ((e (chi-install-global n (chi e r w))))
1016 (top-level-eval-hook e)
1017 (if (memq 'load esew) e (chi-void)))
1018 (if (memq 'load esew)
1019 (chi-install-global n (chi e r w))
1020 (chi-void))))
1021 ((c&e)
1022 (let ((e (chi-install-global n (chi e r w))))
1023 (top-level-eval-hook e)
1024 e))
1025 (else
1026 (if (memq 'eval esew)
1027 (top-level-eval-hook
1028 (chi-install-global n (chi e r w))))
1029 (chi-void)))))
1030 ((define-form)
1031 (let ((n (id-var-name value w)))
1032 (case (binding-type (lookup n r))
1033 ((global)
1034 (eval-if-c&e m
1035 (build-global-definition s n (chi e r w))))
1036 ((displaced-lexical)
1037 (syntax-error (wrap value w) "identifier out of context"))
1038 (else (syntax-error (wrap value w)
1039 "cannot define keyword at top level")))))
1040 (else (eval-if-c&e m (chi-expr type value e r w s))))))))
1041
1042(define chi
1043 (lambda (e r w)
1044 (call-with-values
1045 (lambda () (syntax-type e r w no-source #f))
1046 (lambda (type value e w s)
1047 (chi-expr type value e r w s)))))
1048
1049(define chi-expr
1050 (lambda (type value e r w s)
1051 (case type
1052 ((lexical)
1053 (build-lexical-reference 'value s value))
1054 ((core) (value e r w s))
1055 ((lexical-call)
1056 (chi-application
1057 (build-lexical-reference 'fun (source-annotation (car e)) value)
1058 e r w s))
1059 ((global-call)
1060 (chi-application
1061 (build-global-reference (source-annotation (car e)) value)
1062 e r w s))
1063 ((constant) (build-data s (strip (source-wrap e w s) empty-wrap)))
1064 ((global) (build-global-reference s value))
1065 ((call) (chi-application (chi (car e) r w) e r w s))
1066 ((begin-form)
1067 (syntax-case e ()
1068 ((_ e1 e2 ...) (chi-sequence (syntax (e1 e2 ...)) r w s))))
1069 ((local-syntax-form)
1070 (chi-local-syntax value e r w s chi-sequence))
1071 ((eval-when-form)
1072 (syntax-case e ()
1073 ((_ (x ...) e1 e2 ...)
1074 (let ((when-list (chi-when-list e (syntax (x ...)) w)))
1075 (if (memq 'eval when-list)
1076 (chi-sequence (syntax (e1 e2 ...)) r w s)
1077 (chi-void))))))
1078 ((define-form define-syntax-form)
1079 (syntax-error (wrap value w) "invalid context for definition of"))
1080 ((syntax)
1081 (syntax-error (source-wrap e w s)
1082 "reference to pattern variable outside syntax form"))
1083 ((displaced-lexical)
1084 (syntax-error (source-wrap e w s)
1085 "reference to identifier outside its scope"))
1086 (else (syntax-error (source-wrap e w s))))))
1087
1088(define chi-application
1089 (lambda (x e r w s)
1090 (syntax-case e ()
1091 ((e0 e1 ...)
1092 (build-application s x
1093 (map (lambda (e) (chi e r w)) (syntax (e1 ...))))))))
1094
1095(define chi-macro
1096 (lambda (p e r w rib)
1097 (define rebuild-macro-output
1098 (lambda (x m)
1099 (cond ((pair? x)
1100 (cons (rebuild-macro-output (car x) m)
1101 (rebuild-macro-output (cdr x) m)))
1102 ((syntax-object? x)
1103 (let ((w (syntax-object-wrap x)))
1104 (let ((ms (wrap-marks w)) (s (wrap-subst w)))
1105 (make-syntax-object (syntax-object-expression x)
1106 (if (and (pair? ms) (eq? (car ms) the-anti-mark))
1107 (make-wrap (cdr ms)
1108 (if rib (cons rib (cdr s)) (cdr s)))
1109 (make-wrap (cons m ms)
1110 (if rib
1111 (cons rib (cons 'shift s))
1112 (cons 'shift s))))))))
1113 ((vector? x)
1114 (let* ((n (vector-length x)) (v (make-vector n)))
1115 (do ((i 0 (fx+ i 1)))
1116 ((fx= i n) v)
1117 (vector-set! v i
1118 (rebuild-macro-output (vector-ref x i) m)))))
1119 ((symbol? x)
1120 (syntax-error x "encountered raw symbol in macro output"))
1121 (else x))))
1122 (rebuild-macro-output (p (wrap e (anti-mark w))) (new-mark))))
1123
1124(define chi-body
1125 ;; In processing the forms of the body, we create a new, empty wrap.
1126 ;; This wrap is augmented (destructively) each time we discover that
1127 ;; the next form is a definition. This is done:
1128 ;;
1129 ;; (1) to allow the first nondefinition form to be a call to
1130 ;; one of the defined ids even if the id previously denoted a
1131 ;; definition keyword or keyword for a macro expanding into a
1132 ;; definition;
1133 ;; (2) to prevent subsequent definition forms (but unfortunately
1134 ;; not earlier ones) and the first nondefinition form from
1135 ;; confusing one of the bound identifiers for an auxiliary
1136 ;; keyword; and
1137 ;; (3) so that we do not need to restart the expansion of the
1138 ;; first nondefinition form, which is problematic anyway
1139 ;; since it might be the first element of a begin that we
1140 ;; have just spliced into the body (meaning if we restarted,
1141 ;; we'd really need to restart with the begin or the macro
1142 ;; call that expanded into the begin, and we'd have to give
1143 ;; up allowing (begin <defn>+ <expr>+), which is itself
1144 ;; problematic since we don't know if a begin contains only
1145 ;; definitions until we've expanded it).
1146 ;;
1147 ;; Before processing the body, we also create a new environment
1148 ;; containing a placeholder for the bindings we will add later and
1149 ;; associate this environment with each form. In processing a
1150 ;; let-syntax or letrec-syntax, the associated environment may be
1151 ;; augmented with local keyword bindings, so the environment may
1152 ;; be different for different forms in the body. Once we have
1153 ;; gathered up all of the definitions, we evaluate the transformer
1154 ;; expressions and splice into r at the placeholder the new variable
1155 ;; and keyword bindings. This allows let-syntax or letrec-syntax
1156 ;; forms local to a portion or all of the body to shadow the
1157 ;; definition bindings.
1158 ;;
1159 ;; Subforms of a begin, let-syntax, or letrec-syntax are spliced
1160 ;; into the body.
1161 ;;
1162 ;; outer-form is fully wrapped w/source
1163 (lambda (body outer-form r w)
1164 (let* ((r (cons '("placeholder" . (placeholder)) r))
1165 (ribcage (make-empty-ribcage))
1166 (w (make-wrap (wrap-marks w) (cons ribcage (wrap-subst w)))))
1167 (let parse ((body (map (lambda (x) (cons r (wrap x w))) body))
1168 (ids '()) (labels '()) (vars '()) (vals '()) (bindings '()))
1169 (if (null? body)
1170 (syntax-error outer-form "no expressions in body")
1171 (let ((e (cdar body)) (er (caar body)))
1172 (call-with-values
1173 (lambda () (syntax-type e er empty-wrap no-source ribcage))
1174 (lambda (type value e w s)
1175 (case type
1176 ((define-form)
1177 (let ((id (wrap value w)) (label (gen-label)))
1178 (let ((var (gen-var id)))
1179 (extend-ribcage! ribcage id label)
1180 (parse (cdr body)
1181 (cons id ids) (cons label labels)
1182 (cons var vars) (cons (cons er (wrap e w)) vals)
1183 (cons (make-binding 'lexical var) bindings)))))
1184 ((define-syntax-form)
1185 (let ((id (wrap value w)) (label (gen-label)))
1186 (extend-ribcage! ribcage id label)
1187 (parse (cdr body)
1188 (cons id ids) (cons label labels)
1189 vars vals
1190 (cons (make-binding 'macro (cons er (wrap e w)))
1191 bindings))))
1192 ((begin-form)
1193 (syntax-case e ()
1194 ((_ e1 ...)
1195 (parse (let f ((forms (syntax (e1 ...))))
1196 (if (null? forms)
1197 (cdr body)
1198 (cons (cons er (wrap (car forms) w))
1199 (f (cdr forms)))))
1200 ids labels vars vals bindings))))
1201 ((local-syntax-form)
1202 (chi-local-syntax value e er w s
1203 (lambda (forms er w s)
1204 (parse (let f ((forms forms))
1205 (if (null? forms)
1206 (cdr body)
1207 (cons (cons er (wrap (car forms) w))
1208 (f (cdr forms)))))
1209 ids labels vars vals bindings))))
1210 (else ; found a non-definition
1211 (if (null? ids)
1212 (build-sequence no-source
1213 (map (lambda (x)
1214 (chi (cdr x) (car x) empty-wrap))
1215 (cons (cons er (source-wrap e w s))
1216 (cdr body))))
1217 (begin
1218 (if (not (valid-bound-ids? ids))
1219 (syntax-error outer-form
1220 "invalid or duplicate identifier in definition"))
1221 (let loop ((bs bindings) (er-cache #f) (r-cache #f))
1222 (if (not (null? bs))
1223 (let* ((b (car bs)))
1224 (if (eq? (car b) 'macro)
1225 (let* ((er (cadr b))
1226 (r-cache
1227 (if (eq? er er-cache)
1228 r-cache
1229 (macros-only-env er))))
1230 (set-cdr! b
1231 (eval-local-transformer
1232 (chi (cddr b) r-cache empty-wrap)))
1233 (loop (cdr bs) er r-cache))
1234 (loop (cdr bs) er-cache r-cache)))))
1235 (set-cdr! r (extend-env labels bindings (cdr r)))
1236 (build-letrec no-source
1237 vars
1238 (map (lambda (x)
1239 (chi (cdr x) (car x) empty-wrap))
1240 vals)
1241 (build-sequence no-source
1242 (map (lambda (x)
1243 (chi (cdr x) (car x) empty-wrap))
1244 (cons (cons er (source-wrap e w s))
1245 (cdr body)))))))))))))))))
1246
1247(define chi-lambda-clause
1248 (lambda (e c r w k)
1249 (syntax-case c ()
1250 (((id ...) e1 e2 ...)
1251 (let ((ids (syntax (id ...))))
1252 (if (not (valid-bound-ids? ids))
1253 (syntax-error e "invalid parameter list in")
1254 (let ((labels (gen-labels ids))
1255 (new-vars (map gen-var ids)))
1256 (k new-vars
1257 (chi-body (syntax (e1 e2 ...))
1258 e
1259 (extend-var-env labels new-vars r)
1260 (make-binding-wrap ids labels w)))))))
1261 ((ids e1 e2 ...)
1262 (let ((old-ids (lambda-var-list (syntax ids))))
1263 (if (not (valid-bound-ids? old-ids))
1264 (syntax-error e "invalid parameter list in")
1265 (let ((labels (gen-labels old-ids))
1266 (new-vars (map gen-var old-ids)))
1267 (k (let f ((ls1 (cdr new-vars)) (ls2 (car new-vars)))
1268 (if (null? ls1)
1269 ls2
1270 (f (cdr ls1) (cons (car ls1) ls2))))
1271 (chi-body (syntax (e1 e2 ...))
1272 e
1273 (extend-var-env labels new-vars r)
1274 (make-binding-wrap old-ids labels w)))))))
1275 (_ (syntax-error e)))))
1276
1277(define chi-local-syntax
1278 (lambda (rec? e r w s k)
1279 (syntax-case e ()
1280 ((_ ((id val) ...) e1 e2 ...)
1281 (let ((ids (syntax (id ...))))
1282 (if (not (valid-bound-ids? ids))
1283 (syntax-error e "duplicate bound keyword in")
1284 (let ((labels (gen-labels ids)))
1285 (let ((new-w (make-binding-wrap ids labels w)))
1286 (k (syntax (e1 e2 ...))
1287 (extend-env
1288 labels
1289 (let ((w (if rec? new-w w))
1290 (trans-r (macros-only-env r)))
1291 (map (lambda (x)
1292 (make-binding 'macro
1293 (eval-local-transformer (chi x trans-r w))))
1294 (syntax (val ...))))
1295 r)
1296 new-w
1297 s))))))
1298 (_ (syntax-error (source-wrap e w s))))))
1299
1300(define eval-local-transformer
1301 (lambda (expanded)
1302 (let ((p (local-eval-hook expanded)))
1303 (if (procedure? p)
1304 p
1305 (syntax-error p "nonprocedure transfomer")))))
1306
1307(define chi-void
1308 (lambda ()
1309 (build-application no-source (build-primref no-source 'void) '())))
1310
1311(define ellipsis?
1312 (lambda (x)
1313 (and (nonsymbol-id? x)
1314 (free-id=? x (syntax (... ...))))))
1315
1316;;; data
1317
1318;;; strips all annotations from potentially circular reader output
1319
1320(define strip-annotation
1321 (lambda (x parent)
1322 (cond
1323 ((pair? x)
1324 (let ((new (cons #f #f)))
1325 (when parent (set-annotation-stripped! parent new))
1326 (set-car! new (strip-annotation (car x) #f))
1327 (set-cdr! new (strip-annotation (cdr x) #f))
1328 new))
1329 ((annotation? x)
1330 (or (annotation-stripped x)
1331 (strip-annotation (annotation-expression x) x)))
1332 ((vector? x)
1333 (let ((new (make-vector (vector-length x))))
1334 (when parent (set-annotation-stripped! parent new))
1335 (let loop ((i (- (vector-length x) 1)))
1336 (unless (fx< i 0)
1337 (vector-set! new i (strip-annotation (vector-ref x i) #f))
1338 (loop (fx- i 1))))
1339 new))
1340 (else x))))
1341
1342;;; strips syntax-objects down to top-wrap; if top-wrap is layered directly
1343;;; on an annotation, strips the annotation as well.
1344;;; since only the head of a list is annotated by the reader, not each pair
1345;;; in the spine, we also check for pairs whose cars are annotated in case
1346;;; we've been passed the cdr of an annotated list
1347
1348(define strip
1349 (lambda (x w)
1350 (if (top-marked? w)
1351 (if (or (annotation? x) (and (pair? x) (annotation? (car x))))
1352 (strip-annotation x #f)
1353 x)
1354 (let f ((x x))
1355 (cond
1356 ((syntax-object? x)
1357 (strip (syntax-object-expression x) (syntax-object-wrap x)))
1358 ((pair? x)
1359 (let ((a (f (car x))) (d (f (cdr x))))
1360 (if (and (eq? a (car x)) (eq? d (cdr x)))
1361 x
1362 (cons a d))))
1363 ((vector? x)
1364 (let ((old (vector->list x)))
1365 (let ((new (map f old)))
1366 (if (andmap eq? old new) x (list->vector new)))))
1367 (else x))))))
1368
1369;;; lexical variables
1370
1371(define gen-var
1372 (lambda (id)
1373 (let ((id (if (syntax-object? id) (syntax-object-expression id) id)))
1374 (if (annotation? id)
1375 (build-lexical-var (annotation-source id) (annotation-expression id))
1376 (build-lexical-var no-source id)))))
1377
1378(define lambda-var-list
1379 (lambda (vars)
1380 (let lvl ((vars vars) (ls '()) (w empty-wrap))
1381 (cond
1382 ((pair? vars) (lvl (cdr vars) (cons (wrap (car vars) w) ls) w))
1383 ((id? vars) (cons (wrap vars w) ls))
1384 ((null? vars) ls)
1385 ((syntax-object? vars)
1386 (lvl (syntax-object-expression vars)
1387 ls
1388 (join-wraps w (syntax-object-wrap vars))))
1389 ((annotation? vars)
1390 (lvl (annotation-expression vars) ls w))
1391 ; include anything else to be caught by subsequent error
1392 ; checking
1393 (else (cons vars ls))))))
1394
1395;;; core transformers
1396
1397(global-extend 'local-syntax 'letrec-syntax #t)
1398(global-extend 'local-syntax 'let-syntax #f)
1399
1400(global-extend 'core 'fluid-let-syntax
1401 (lambda (e r w s)
1402 (syntax-case e ()
1403 ((_ ((var val) ...) e1 e2 ...)
1404 (valid-bound-ids? (syntax (var ...)))
1405 (let ((names (map (lambda (x) (id-var-name x w)) (syntax (var ...)))))
1406 (for-each
1407 (lambda (id n)
1408 (case (binding-type (lookup n r))
1409 ((displaced-lexical)
1410 (syntax-error (source-wrap id w s)
1411 "identifier out of context"))))
1412 (syntax (var ...))
1413 names)
1414 (chi-body
1415 (syntax (e1 e2 ...))
1416 (source-wrap e w s)
1417 (extend-env
1418 names
1419 (let ((trans-r (macros-only-env r)))
1420 (map (lambda (x)
1421 (make-binding 'macro
1422 (eval-local-transformer (chi x trans-r w))))
1423 (syntax (val ...))))
1424 r)
1425 w)))
1426 (_ (syntax-error (source-wrap e w s))))))
1427
1428(global-extend 'core 'quote
1429 (lambda (e r w s)
1430 (syntax-case e ()
1431 ((_ e) (build-data s (strip (syntax e) w)))
1432 (_ (syntax-error (source-wrap e w s))))))
1433
1434(global-extend 'core 'syntax
1435 (let ()
1436 (define gen-syntax
1437 (lambda (src e r maps ellipsis?)
1438 (if (id? e)
1439 (let ((label (id-var-name e empty-wrap)))
1440 (let ((b (lookup label r)))
1441 (if (eq? (binding-type b) 'syntax)
1442 (call-with-values
1443 (lambda ()
1444 (let ((var.lev (binding-value b)))
1445 (gen-ref src (car var.lev) (cdr var.lev) maps)))
1446 (lambda (var maps) (values `(ref ,var) maps)))
1447 (if (ellipsis? e)
1448 (syntax-error src "misplaced ellipsis in syntax form")
1449 (values `(quote ,e) maps)))))
1450 (syntax-case e ()
1451 ((dots e)
1452 (ellipsis? (syntax dots))
1453 (gen-syntax src (syntax e) r maps (lambda (x) #f)))
1454 ((x dots . y)
1455 ; this could be about a dozen lines of code, except that we
1456 ; choose to handle (syntax (x ... ...)) forms
1457 (ellipsis? (syntax dots))
1458 (let f ((y (syntax y))
1459 (k (lambda (maps)
1460 (call-with-values
1461 (lambda ()
1462 (gen-syntax src (syntax x) r
1463 (cons '() maps) ellipsis?))
1464 (lambda (x maps)
1465 (if (null? (car maps))
1466 (syntax-error src
1467 "extra ellipsis in syntax form")
1468 (values (gen-map x (car maps))
1469 (cdr maps))))))))
1470 (syntax-case y ()
1471 ((dots . y)
1472 (ellipsis? (syntax dots))
1473 (f (syntax y)
1474 (lambda (maps)
1475 (call-with-values
1476 (lambda () (k (cons '() maps)))
1477 (lambda (x maps)
1478 (if (null? (car maps))
1479 (syntax-error src
1480 "extra ellipsis in syntax form")
1481 (values (gen-mappend x (car maps))
1482 (cdr maps))))))))
1483 (_ (call-with-values
1484 (lambda () (gen-syntax src y r maps ellipsis?))
1485 (lambda (y maps)
1486 (call-with-values
1487 (lambda () (k maps))
1488 (lambda (x maps)
1489 (values (gen-append x y) maps)))))))))
1490 ((x . y)
1491 (call-with-values
1492 (lambda () (gen-syntax src (syntax x) r maps ellipsis?))
1493 (lambda (x maps)
1494 (call-with-values
1495 (lambda () (gen-syntax src (syntax y) r maps ellipsis?))
1496 (lambda (y maps) (values (gen-cons x y) maps))))))
1497 (#(e1 e2 ...)
1498 (call-with-values
1499 (lambda ()
1500 (gen-syntax src (syntax (e1 e2 ...)) r maps ellipsis?))
1501 (lambda (e maps) (values (gen-vector e) maps))))
1502 (_ (values `(quote ,e) maps))))))
1503
1504 (define gen-ref
1505 (lambda (src var level maps)
1506 (if (fx= level 0)
1507 (values var maps)
1508 (if (null? maps)
1509 (syntax-error src "missing ellipsis in syntax form")
1510 (call-with-values
1511 (lambda () (gen-ref src var (fx- level 1) (cdr maps)))
1512 (lambda (outer-var outer-maps)
1513 (let ((b (assq outer-var (car maps))))
1514 (if b
1515 (values (cdr b) maps)
1516 (let ((inner-var (gen-var 'tmp)))
1517 (values inner-var
1518 (cons (cons (cons outer-var inner-var)
1519 (car maps))
1520 outer-maps)))))))))))
1521
1522 (define gen-mappend
1523 (lambda (e map-env)
1524 `(apply (primitive append) ,(gen-map e map-env))))
1525
1526 (define gen-map
1527 (lambda (e map-env)
1528 (let ((formals (map cdr map-env))
1529 (actuals (map (lambda (x) `(ref ,(car x))) map-env)))
1530 (cond
1531 ((eq? (car e) 'ref)
1532 ; identity map equivalence:
1533 ; (map (lambda (x) x) y) == y
1534 (car actuals))
1535 ((andmap
1536 (lambda (x) (and (eq? (car x) 'ref) (memq (cadr x) formals)))
1537 (cdr e))
1538 ; eta map equivalence:
1539 ; (map (lambda (x ...) (f x ...)) y ...) == (map f y ...)
1540 `(map (primitive ,(car e))
1541 ,@(map (let ((r (map cons formals actuals)))
1542 (lambda (x) (cdr (assq (cadr x) r))))
1543 (cdr e))))
1544 (else `(map (lambda ,formals ,e) ,@actuals))))))
1545
1546 (define gen-cons
1547 (lambda (x y)
1548 (case (car y)
1549 ((quote)
1550 (if (eq? (car x) 'quote)
1551 `(quote (,(cadr x) . ,(cadr y)))
1552 (if (eq? (cadr y) '())
1553 `(list ,x)
1554 `(cons ,x ,y))))
1555 ((list) `(list ,x ,@(cdr y)))
1556 (else `(cons ,x ,y)))))
1557
1558 (define gen-append
1559 (lambda (x y)
1560 (if (equal? y '(quote ()))
1561 x
1562 `(append ,x ,y))))
1563
1564 (define gen-vector
1565 (lambda (x)
1566 (cond
1567 ((eq? (car x) 'list) `(vector ,@(cdr x)))
1568 ((eq? (car x) 'quote) `(quote #(,@(cadr x))))
1569 (else `(list->vector ,x)))))
1570
1571
1572 (define regen
1573 (lambda (x)
1574 (case (car x)
1575 ((ref) (build-lexical-reference 'value no-source (cadr x)))
1576 ((primitive) (build-primref no-source (cadr x)))
1577 ((quote) (build-data no-source (cadr x)))
1578 ((lambda) (build-lambda no-source (cadr x) (regen (caddr x))))
1579 ((map) (let ((ls (map regen (cdr x))))
1580 (build-application no-source
1581 (if (fx= (length ls) 2)
1582 (build-primref no-source 'map)
1583 ; really need to do our own checking here
1584 (build-primref no-source 2 'map)) ; require error check
1585 ls)))
1586 (else (build-application no-source
1587 (build-primref no-source (car x))
1588 (map regen (cdr x)))))))
1589
1590 (lambda (e r w s)
1591 (let ((e (source-wrap e w s)))
1592 (syntax-case e ()
1593 ((_ x)
1594 (call-with-values
1595 (lambda () (gen-syntax e (syntax x) r '() ellipsis?))
1596 (lambda (e maps) (regen e))))
1597 (_ (syntax-error e)))))))
1598
1599
1600(global-extend 'core 'lambda
1601 (lambda (e r w s)
1602 (syntax-case e ()
1603 ((_ . c)
1604 (chi-lambda-clause (source-wrap e w s) (syntax c) r w
1605 (lambda (vars body) (build-lambda s vars body)))))))
1606
1607
1608(global-extend 'core 'let
1609 (let ()
1610 (define (chi-let e r w s constructor ids vals exps)
1611 (if (not (valid-bound-ids? ids))
1612 (syntax-error e "duplicate bound variable in")
1613 (let ((labels (gen-labels ids))
1614 (new-vars (map gen-var ids)))
1615 (let ((nw (make-binding-wrap ids labels w))
1616 (nr (extend-var-env labels new-vars r)))
1617 (constructor s
1618 new-vars
1619 (map (lambda (x) (chi x r w)) vals)
1620 (chi-body exps (source-wrap e nw s) nr nw))))))
1621 (lambda (e r w s)
1622 (syntax-case e ()
1623 ((_ ((id val) ...) e1 e2 ...)
1624 (chi-let e r w s
1625 build-let
1626 (syntax (id ...))
1627 (syntax (val ...))
1628 (syntax (e1 e2 ...))))
1629 ((_ f ((id val) ...) e1 e2 ...)
1630 (id? (syntax f))
1631 (chi-let e r w s
1632 build-named-let
1633 (syntax (f id ...))
1634 (syntax (val ...))
1635 (syntax (e1 e2 ...))))
1636 (_ (syntax-error (source-wrap e w s)))))))
1637
1638
1639(global-extend 'core 'letrec
1640 (lambda (e r w s)
1641 (syntax-case e ()
1642 ((_ ((id val) ...) e1 e2 ...)
1643 (let ((ids (syntax (id ...))))
1644 (if (not (valid-bound-ids? ids))
1645 (syntax-error e "duplicate bound variable in")
1646 (let ((labels (gen-labels ids))
1647 (new-vars (map gen-var ids)))
1648 (let ((w (make-binding-wrap ids labels w))
1649 (r (extend-var-env labels new-vars r)))
1650 (build-letrec s
1651 new-vars
1652 (map (lambda (x) (chi x r w)) (syntax (val ...)))
1653 (chi-body (syntax (e1 e2 ...)) (source-wrap e w s) r w)))))))
1654 (_ (syntax-error (source-wrap e w s))))))
1655
1656
1657(global-extend 'core 'set!
1658 (lambda (e r w s)
1659 (syntax-case e ()
1660 ((_ id val)
1661 (id? (syntax id))
1662 (let ((val (chi (syntax val) r w))
1663 (n (id-var-name (syntax id) w)))
1664 (let ((b (lookup n r)))
1665 (case (binding-type b)
1666 ((lexical)
1667 (build-lexical-assignment s (binding-value b) val))
1668 ((global) (build-global-assignment s n val))
1669 ((displaced-lexical)
1670 (syntax-error (wrap (syntax id) w)
1671 "identifier out of context"))
1672 (else (syntax-error (source-wrap e w s)))))))
1673 (_ (syntax-error (source-wrap e w s))))))
1674
1675(global-extend 'begin 'begin '())
1676
1677(global-extend 'define 'define '())
1678
1679(global-extend 'define-syntax 'define-syntax '())
1680
1681(global-extend 'eval-when 'eval-when '())
1682
1683(global-extend 'core 'syntax-case
1684 (let ()
1685 (define convert-pattern
1686 ; accepts pattern & keys
1687 ; returns syntax-dispatch pattern & ids
1688 (lambda (pattern keys)
1689 (let cvt ((p pattern) (n 0) (ids '()))
1690 (if (id? p)
1691 (if (bound-id-member? p keys)
1692 (values (vector 'free-id p) ids)
1693 (values 'any (cons (cons p n) ids)))
1694 (syntax-case p ()
1695 ((x dots)
1696 (ellipsis? (syntax dots))
1697 (call-with-values
1698 (lambda () (cvt (syntax x) (fx+ n 1) ids))
1699 (lambda (p ids)
1700 (values (if (eq? p 'any) 'each-any (vector 'each p))
1701 ids))))
1702 ((x . y)
1703 (call-with-values
1704 (lambda () (cvt (syntax y) n ids))
1705 (lambda (y ids)
1706 (call-with-values
1707 (lambda () (cvt (syntax x) n ids))
1708 (lambda (x ids)
1709 (values (cons x y) ids))))))
1710 (() (values '() ids))
1711 (#(x ...)
1712 (call-with-values
1713 (lambda () (cvt (syntax (x ...)) n ids))
1714 (lambda (p ids) (values (vector 'vector p) ids))))
1715 (x (values (vector 'atom (strip p empty-wrap)) ids)))))))
1716
1717 (define build-dispatch-call
1718 (lambda (pvars exp y r)
1719 (let ((ids (map car pvars)) (levels (map cdr pvars)))
1720 (let ((labels (gen-labels ids)) (new-vars (map gen-var ids)))
1721 (build-application no-source
1722 (build-primref no-source 'apply)
1723 (list (build-lambda no-source new-vars
1724 (chi exp
1725 (extend-env
1726 labels
1727 (map (lambda (var level)
1728 (make-binding 'syntax `(,var . ,level)))
1729 new-vars
1730 (map cdr pvars))
1731 r)
1732 (make-binding-wrap ids labels empty-wrap)))
1733 y))))))
1734
1735 (define gen-clause
1736 (lambda (x keys clauses r pat fender exp)
1737 (call-with-values
1738 (lambda () (convert-pattern pat keys))
1739 (lambda (p pvars)
1740 (cond
1741 ((not (distinct-bound-ids? (map car pvars)))
1742 (syntax-error pat
1743 "duplicate pattern variable in syntax-case pattern"))
1744 ((not (andmap (lambda (x) (not (ellipsis? (car x)))) pvars))
1745 (syntax-error pat
1746 "misplaced ellipsis in syntax-case pattern"))
1747 (else
1748 (let ((y (gen-var 'tmp)))
1749 ; fat finger binding and references to temp variable y
1750 (build-application no-source
1751 (build-lambda no-source (list y)
1752 (let ((y (build-lexical-reference 'value no-source y)))
1753 (build-conditional no-source
1754 (syntax-case fender ()
1755 (#t y)
1756 (_ (build-conditional no-source
1757 y
1758 (build-dispatch-call pvars fender y r)
1759 (build-data no-source #f))))
1760 (build-dispatch-call pvars exp y r)
1761 (gen-syntax-case x keys clauses r))))
1762 (list (if (eq? p 'any)
1763 (build-application no-source
1764 (build-primref no-source 'list)
1765 (list x))
1766 (build-application no-source
1767 (build-primref no-source 'syntax-dispatch)
1768 (list x (build-data no-source p)))))))))))))
1769
1770 (define gen-syntax-case
1771 (lambda (x keys clauses r)
1772 (if (null? clauses)
1773 (build-application no-source
1774 (build-primref no-source 'syntax-error)
1775 (list x))
1776 (syntax-case (car clauses) ()
1777 ((pat exp)
1778 (if (and (id? (syntax pat))
1779 (andmap (lambda (x) (not (free-id=? (syntax pat) x)))
1780 (cons (syntax (... ...)) keys)))
1781 (let ((labels (list (gen-label)))
1782 (var (gen-var (syntax pat))))
1783 (build-application no-source
1784 (build-lambda no-source (list var)
1785 (chi (syntax exp)
1786 (extend-env labels
1787 (list (make-binding 'syntax `(,var . 0)))
1788 r)
1789 (make-binding-wrap (syntax (pat))
1790 labels empty-wrap)))
1791 (list x)))
1792 (gen-clause x keys (cdr clauses) r
1793 (syntax pat) #t (syntax exp))))
1794 ((pat fender exp)
1795 (gen-clause x keys (cdr clauses) r
1796 (syntax pat) (syntax fender) (syntax exp)))
1797 (_ (syntax-error (car clauses) "invalid syntax-case clause"))))))
1798
1799 (lambda (e r w s)
1800 (let ((e (source-wrap e w s)))
1801 (syntax-case e ()
1802 ((_ val (key ...) m ...)
1803 (if (andmap (lambda (x) (and (id? x) (not (ellipsis? x))))
1804 (syntax (key ...)))
1805 (let ((x (gen-var 'tmp)))
1806 ; fat finger binding and references to temp variable x
1807 (build-application s
1808 (build-lambda no-source (list x)
1809 (gen-syntax-case (build-lexical-reference 'value no-source x)
1810 (syntax (key ...)) (syntax (m ...))
1811 r))
1812 (list (chi (syntax val) r empty-wrap))))
1813 (syntax-error e "invalid literals list in"))))))))
1814
1815;;; The portable sc-expand seeds chi-top's mode m with 'e (for
1816;;; evaluating) and esew (which stands for "eval syntax expanders
1817;;; when") with '(eval). In Chez Scheme, m is set to 'c instead of e
1818;;; if we are compiling a file, and esew is set to
1819;;; (eval-syntactic-expanders-when), which defaults to the list
1820;;; '(compile load eval). This means that, by default, top-level
1821;;; syntactic definitions are evaluated immediately after they are
1822;;; expanded, and the expanded definitions are also residualized into
1823;;; the object file if we are compiling a file.
1824(set! sc-expand
1825 (let ((m 'e) (esew '(eval)))
1826 (lambda (x)
1827 (if (and (pair? x) (equal? (car x) noexpand))
1828 (cadr x)
1829 (chi-top x null-env top-wrap m esew)))))
1830
1831(set! sc-expand3
1832 (let ((m 'e) (esew '(eval)))
1833 (lambda (x . rest)
1834 (if (and (pair? x) (equal? (car x) noexpand))
1835 (cadr x)
1836 (chi-top x
1837 null-env
1838 top-wrap
1839 (if (null? rest) m (car rest))
1840 (if (or (null? rest) (null? (cdr rest)))
1841 esew
1842 (cadr rest)))))))
1843
1844(set! identifier?
1845 (lambda (x)
1846 (nonsymbol-id? x)))
1847
1848(set! datum->syntax-object
1849 (lambda (id datum)
1850 (arg-check nonsymbol-id? id 'datum->syntax-object)
1851 (make-syntax-object datum (syntax-object-wrap id))))
1852
1853(set! syntax-object->datum
1854 ; accepts any object, since syntax objects may consist partially
1855 ; or entirely of unwrapped, nonsymbolic data
1856 (lambda (x)
1857 (strip x empty-wrap)))
1858
1859(set! generate-temporaries
1860 (lambda (ls)
1861 (arg-check list? ls 'generate-temporaries)
1862 (map (lambda (x) (wrap (gensym-hook) top-wrap)) ls)))
1863
1864(set! free-identifier=?
1865 (lambda (x y)
1866 (arg-check nonsymbol-id? x 'free-identifier=?)
1867 (arg-check nonsymbol-id? y 'free-identifier=?)
1868 (free-id=? x y)))
1869
1870(set! bound-identifier=?
1871 (lambda (x y)
1872 (arg-check nonsymbol-id? x 'bound-identifier=?)
1873 (arg-check nonsymbol-id? y 'bound-identifier=?)
1874 (bound-id=? x y)))
1875
1876(set! syntax-error
1877 (lambda (object . messages)
1878 (for-each (lambda (x) (arg-check string? x 'syntax-error)) messages)
1879 (let ((message (if (null? messages)
1880 "invalid syntax"
1881 (apply string-append messages))))
1882 (error-hook #f message (strip object empty-wrap)))))
1883
1884(set! install-global-transformer
1885 (lambda (sym v)
1886 (arg-check symbol? sym 'define-syntax)
1887 (arg-check procedure? v 'define-syntax)
1888 (global-extend 'macro sym v)))
1889
1890;;; syntax-dispatch expects an expression and a pattern. If the expression
1891;;; matches the pattern a list of the matching expressions for each
1892;;; "any" is returned. Otherwise, #f is returned. (This use of #f will
1893;;; not work on r4rs implementations that violate the ieee requirement
1894;;; that #f and () be distinct.)
1895
1896;;; The expression is matched with the pattern as follows:
1897
1898;;; pattern: matches:
1899;;; () empty list
1900;;; any anything
1901;;; (<pattern>1 . <pattern>2) (<pattern>1 . <pattern>2)
1902;;; each-any (any*)
1903;;; #(free-id <key>) <key> with free-identifier=?
1904;;; #(each <pattern>) (<pattern>*)
1905;;; #(vector <pattern>) (list->vector <pattern>)
1906;;; #(atom <object>) <object> with "equal?"
1907
1908;;; Vector cops out to pair under assumption that vectors are rare. If
1909;;; not, should convert to:
1910;;; #(vector <pattern>*) #(<pattern>*)
1911
1912(let ()
1913
1914(define match-each
1915 (lambda (e p w)
1916 (cond
1917 ((annotation? e)
1918 (match-each (annotation-expression e) p w))
1919 ((pair? e)
1920 (let ((first (match (car e) p w '())))
1921 (and first
1922 (let ((rest (match-each (cdr e) p w)))
1923 (and rest (cons first rest))))))
1924 ((null? e) '())
1925 ((syntax-object? e)
1926 (match-each (syntax-object-expression e)
1927 p
1928 (join-wraps w (syntax-object-wrap e))))
1929 (else #f))))
1930
1931(define match-each-any
1932 (lambda (e w)
1933 (cond
1934 ((annotation? e)
1935 (match-each-any (annotation-expression e) w))
1936 ((pair? e)
1937 (let ((l (match-each-any (cdr e) w)))
1938 (and l (cons (wrap (car e) w) l))))
1939 ((null? e) '())
1940 ((syntax-object? e)
1941 (match-each-any (syntax-object-expression e)
1942 (join-wraps w (syntax-object-wrap e))))
1943 (else #f))))
1944
1945(define match-empty
1946 (lambda (p r)
1947 (cond
1948 ((null? p) r)
1949 ((eq? p 'any) (cons '() r))
1950 ((pair? p) (match-empty (car p) (match-empty (cdr p) r)))
1951 ((eq? p 'each-any) (cons '() r))
1952 (else
1953 (case (vector-ref p 0)
1954 ((each) (match-empty (vector-ref p 1) r))
1955 ((free-id atom) r)
1956 ((vector) (match-empty (vector-ref p 1) r)))))))
1957
1958(define match*
1959 (lambda (e p w r)
1960 (cond
1961 ((null? p) (and (null? e) r))
1962 ((pair? p)
1963 (and (pair? e) (match (car e) (car p) w
1964 (match (cdr e) (cdr p) w r))))
1965 ((eq? p 'each-any)
1966 (let ((l (match-each-any e w))) (and l (cons l r))))
1967 (else
1968 (case (vector-ref p 0)
1969 ((each)
1970 (if (null? e)
1971 (match-empty (vector-ref p 1) r)
1972 (let ((l (match-each e (vector-ref p 1) w)))
1973 (and l
1974 (let collect ((l l))
1975 (if (null? (car l))
1976 r
1977 (cons (map car l) (collect (map cdr l)))))))))
1978 ((free-id) (and (id? e) (free-id=? (wrap e w) (vector-ref p 1)) r))
1979 ((atom) (and (equal? (vector-ref p 1) (strip e w)) r))
1980 ((vector)
1981 (and (vector? e)
1982 (match (vector->list e) (vector-ref p 1) w r))))))))
1983
1984(define match
1985 (lambda (e p w r)
1986 (cond
1987 ((not r) #f)
1988 ((eq? p 'any) (cons (wrap e w) r))
1989 ((syntax-object? e)
1990 (match*
1991 (unannotate (syntax-object-expression e))
1992 p
1993 (join-wraps w (syntax-object-wrap e))
1994 r))
1995 (else (match* (unannotate e) p w r)))))
1996
1997(set! syntax-dispatch
1998 (lambda (e p)
1999 (cond
2000 ((eq? p 'any) (list e))
2001 ((syntax-object? e)
2002 (match* (unannotate (syntax-object-expression e))
2003 p (syntax-object-wrap e) '()))
2004 (else (match* (unannotate e) p empty-wrap '())))))
2005))
2006)
2007
2008(define-syntax with-syntax
2009 (lambda (x)
2010 (syntax-case x ()
2011 ((_ () e1 e2 ...)
2012 (syntax (begin e1 e2 ...)))
2013 ((_ ((out in)) e1 e2 ...)
2014 (syntax (syntax-case in () (out (begin e1 e2 ...)))))
2015 ((_ ((out in) ...) e1 e2 ...)
2016 (syntax (syntax-case (list in ...) ()
2017 ((out ...) (begin e1 e2 ...))))))))
2018
2019(define-syntax syntax-rules
2020 (lambda (x)
2021 (syntax-case x ()
2022 ((_ (k ...) ((keyword . pattern) template) ...)
2023 (syntax (lambda (x)
2024 (syntax-case x (k ...)
2025 ((dummy . pattern) (syntax template))
2026 ...)))))))
2027
2028(define-syntax let*
2029 (lambda (x)
2030 (syntax-case x ()
2031 ((let* ((x v) ...) e1 e2 ...)
2032 (andmap identifier? (syntax (x ...)))
2033 (let f ((bindings (syntax ((x v) ...))))
2034 (if (null? bindings)
2035 (syntax (let () e1 e2 ...))
2036 (with-syntax ((body (f (cdr bindings)))
2037 (binding (car bindings)))
2038 (syntax (let (binding) body)))))))))
2039
2040(define-syntax do
2041 (lambda (orig-x)
2042 (syntax-case orig-x ()
2043 ((_ ((var init . step) ...) (e0 e1 ...) c ...)
2044 (with-syntax (((step ...)
2045 (map (lambda (v s)
2046 (syntax-case s ()
2047 (() v)
2048 ((e) (syntax e))
2049 (_ (syntax-error orig-x))))
2050 (syntax (var ...))
2051 (syntax (step ...)))))
2052 (syntax-case (syntax (e1 ...)) ()
2053 (() (syntax (let doloop ((var init) ...)
2054 (if (not e0)
2055 (begin c ... (doloop step ...))))))
2056 ((e1 e2 ...)
2057 (syntax (let doloop ((var init) ...)
2058 (if e0
2059 (begin e1 e2 ...)
2060 (begin c ... (doloop step ...))))))))))))
2061
2062(define-syntax quasiquote
2063 (letrec
2064 ((quasicons
2065 (lambda (x y)
2066 (with-syntax ((x x) (y y))
2067 (syntax-case (syntax y) (quote list)
2068 ((quote dy)
2069 (syntax-case (syntax x) (quote)
2070 ((quote dx) (syntax (quote (dx . dy))))
2071 (_ (if (null? (syntax dy))
2072 (syntax (list x))
2073 (syntax (cons x y))))))
2074 ((list . stuff) (syntax (list x . stuff)))
2075 (else (syntax (cons x y)))))))
2076 (quasiappend
2077 (lambda (x y)
2078 (with-syntax ((x x) (y y))
2079 (syntax-case (syntax y) (quote)
2080 ((quote ()) (syntax x))
2081 (_ (syntax (append x y)))))))
2082 (quasivector
2083 (lambda (x)
2084 (with-syntax ((x x))
2085 (syntax-case (syntax x) (quote list)
2086 ((quote (x ...)) (syntax (quote #(x ...))))
2087 ((list x ...) (syntax (vector x ...)))
2088 (_ (syntax (list->vector x)))))))
2089 (quasi
2090 (lambda (p lev)
2091 (syntax-case p (unquote unquote-splicing quasiquote)
2092 ((unquote p)
2093 (if (= lev 0)
2094 (syntax p)
2095 (quasicons (syntax (quote unquote))
2096 (quasi (syntax (p)) (- lev 1)))))
2097 (((unquote-splicing p) . q)
2098 (if (= lev 0)
2099 (quasiappend (syntax p) (quasi (syntax q) lev))
2100 (quasicons (quasicons (syntax (quote unquote-splicing))
2101 (quasi (syntax (p)) (- lev 1)))
2102 (quasi (syntax q) lev))))
2103 ((quasiquote p)
2104 (quasicons (syntax (quote quasiquote))
2105 (quasi (syntax (p)) (+ lev 1))))
2106 ((p . q)
2107 (quasicons (quasi (syntax p) lev) (quasi (syntax q) lev)))
2108 (#(x ...) (quasivector (quasi (syntax (x ...)) lev)))
2109 (p (syntax (quote p)))))))
2110 (lambda (x)
2111 (syntax-case x ()
2112 ((_ e) (quasi (syntax e) 0))))))
2113
2114(define-syntax include
2115 (lambda (x)
2116 (define read-file
2117 (lambda (fn k)
2118 (let ((p (open-input-file fn)))
2119 (let f ((x (read p)))
2120 (if (eof-object? x)
2121 (begin (close-input-port p) '())
2122 (cons (datum->syntax-object k x)
2123 (f (read p))))))))
2124 (syntax-case x ()
2125 ((k filename)
2126 (let ((fn (syntax-object->datum (syntax filename))))
2127 (with-syntax (((exp ...) (read-file fn (syntax k))))
2128 (syntax (begin exp ...))))))))
2129
2130(define-syntax unquote
2131 (lambda (x)
2132 (syntax-case x ()
2133 ((_ e)
2134 (error 'unquote
2135 "expression ,~s not valid outside of quasiquote"
2136 (syntax-object->datum (syntax e)))))))
2137
2138(define-syntax unquote-splicing
2139 (lambda (x)
2140 (syntax-case x ()
2141 ((_ e)
2142 (error 'unquote-splicing
2143 "expression ,@~s not valid outside of quasiquote"
2144 (syntax-object->datum (syntax e)))))))
2145
2146(define-syntax case
2147 (lambda (x)
2148 (syntax-case x ()
2149 ((_ e m1 m2 ...)
2150 (with-syntax
2151 ((body (let f ((clause (syntax m1)) (clauses (syntax (m2 ...))))
2152 (if (null? clauses)
2153 (syntax-case clause (else)
2154 ((else e1 e2 ...) (syntax (begin e1 e2 ...)))
2155 (((k ...) e1 e2 ...)
2156 (syntax (if (memv t '(k ...)) (begin e1 e2 ...))))
2157 (_ (syntax-error x)))
2158 (with-syntax ((rest (f (car clauses) (cdr clauses))))
2159 (syntax-case clause (else)
2160 (((k ...) e1 e2 ...)
2161 (syntax (if (memv t '(k ...))
2162 (begin e1 e2 ...)
2163 rest)))
2164 (_ (syntax-error x))))))))
2165 (syntax (let ((t e)) body)))))))
2166
2167(define-syntax identifier-syntax
2168 (lambda (x)
2169 (syntax-case x ()
2170 ((_ e)
2171 (syntax
2172 (lambda (x)
2173 (syntax-case x ()
2174 (id
2175 (identifier? (syntax id))
2176 (syntax e))
2177 ((_ x (... ...))
2178 (syntax (e x (... ...)))))))))))
2179