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