1 ;;; Portable implementation of syntax-case
2 ;;; Extracted from Chez Scheme Version 6.3
3 ;;; Authors: R. Kent Dybvig, Oscar Waddell, Bob Hieb, Carl Bruggeman
5 ;;; Copyright (c) 1992-2000 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.
16 ;;; Before attempting to port this code to a new implementation of
17 ;;; Scheme, please read the notes below carefully.
19 ;;; This file defines the syntax-case expander, sc-expand, and a set
20 ;;; of associated syntactic forms and procedures. Of these, the
21 ;;; following are documented in The Scheme Programming Language,
22 ;;; Second Edition (R. Kent Dybvig, Prentice Hall, 1996), which can be
23 ;;; found online at http://www.scheme.com. Most are also documented
24 ;;; in the R4RS and draft R5RS.
26 ;;; bound-identifier=?
27 ;;; datum->syntax-object
31 ;;; generate-temporaries
38 ;;; syntax-object->datum
42 ;;; All standard Scheme syntactic forms are supported by the expander
43 ;;; or syntactic abstractions defined in this file. Only the R4RS
44 ;;; delay is omitted, since its expansion is implementation-dependent.
46 ;;; Also defined are three forms that support modules: module, import,
47 ;;; and import-only. These are documented in the Chez Scheme User's
48 ;;; Guide (R. Kent Dybvig, Cadence Research Systems, 1998), which can
49 ;;; also be found online at http://www.scheme.com. They are described
50 ;;; briefly here as well.
52 ;;; Both are definitions and may appear where and only where other
53 ;;; definitions may appear. modules may be named:
55 ;;; (module id (ex ...) defn ... init ...)
59 ;;; (module (ex ...) defn ... init ...)
61 ;;; The latter form is semantically equivalent to:
63 ;;; (module T (ex ...) defn ... init ...)
66 ;;; where T is a fresh identifier.
68 ;;; In either form, each of the exports in (ex ...) is either an
69 ;;; identifier or of the form (id ex ...). In the former case, the
70 ;;; single identifier ex is exported. In the latter, the identifier
71 ;;; id is exported and the exports ex ... are "implicitly" exported.
72 ;;; This listing of implicit exports is useful only when id is a
73 ;;; keyword bound to a transformer that expands into references to
74 ;;; the listed implicit exports. In the present implementation,
75 ;;; listing of implicit exports is necessary only for top-level
76 ;;; modules and allows the implementation to avoid placing all
77 ;;; identifiers into the top-level environment where subsequent passes
78 ;;; of the compiler will be unable to deal effectively with them.
80 ;;; Named modules may be referenced in import statements, which
81 ;;; always take one of the forms:
86 ;;; id must name a module. Each exported identifier becomes visible
87 ;;; within the scope of the import form. In the case of import-only,
88 ;;; all other identifiers become invisible in the scope of the
89 ;;; import-only form, except for those established by definitions
90 ;;; that appear textually after the import-only form.
92 ;;; The remaining exports are listed below. sc-expand, eval-when, and
93 ;;; syntax-error are described in the Chez Scheme User's Guide.
96 ;;; if datum represents a valid expression, sc-expand returns an
97 ;;; expanded version of datum in a core language that includes no
98 ;;; syntactic abstractions. The core language includes begin,
99 ;;; define, if, lambda, letrec, quote, and set!.
100 ;;; (eval-when situations expr ...)
101 ;;; conditionally evaluates expr ... at compile-time or run-time
102 ;;; depending upon situations
103 ;;; (syntax-error object message)
104 ;;; used to report errors found during expansion
105 ;;; ($syntax-dispatch e p)
106 ;;; used by expanded code to handle syntax-case matching
107 ;;; ($sc-put-cte symbol val)
108 ;;; used to establish top-level compile-time (expand-time) bindings.
110 ;;; The following nonstandard procedures must be provided by the
111 ;;; implementation for this code to run.
114 ;;; returns the implementation's cannonical "unspecified value". The
115 ;;; following usually works:
117 ;;; (define void (lambda () (if #f #f))).
119 ;;; (andmap proc list1 list2 ...)
120 ;;; returns true if proc returns true when applied to each element of list1
121 ;;; along with the corresponding elements of list2 .... The following
122 ;;; definition works but does no error checking:
125 ;;; (lambda (f first . rest)
126 ;;; (or (null? first)
128 ;;; (let andmap ((first first))
129 ;;; (let ((x (car first)) (first (cdr first)))
130 ;;; (if (null? first)
132 ;;; (and (f x) (andmap first)))))
133 ;;; (let andmap ((first first) (rest rest))
134 ;;; (let ((x (car first))
135 ;;; (xr (map car rest))
136 ;;; (first (cdr first))
137 ;;; (rest (map cdr rest)))
138 ;;; (if (null? first)
139 ;;; (apply f (cons x xr))
140 ;;; (and (apply f (cons x xr)) (andmap first rest)))))))))
142 ;;; (ormap proc list1)
143 ;;; returns the first non-false return result of proc applied to
144 ;;; the elements of list1 or false if none. The following definition
145 ;;; works but does no error checking:
148 ;;; (lambda (proc list1)
149 ;;; (and (not (null? list1))
150 ;;; (or (proc (car list1)) (ormap proc (cdr list1))))))
152 ;;; The following nonstandard procedures must also be provided by the
153 ;;; implementation for this code to run using the standard portable
154 ;;; hooks and output constructors. They are not used by expanded code,
155 ;;; and so need be present only at expansion time.
158 ;;; where x is always in the form ("noexpand" expr).
159 ;;; returns the value of expr. the "noexpand" flag is used to tell the
160 ;;; evaluator/expander that no expansion is necessary, since expr has
161 ;;; already been fully expanded to core forms.
163 ;;; eval will not be invoked during the loading of psyntax.pp. After
164 ;;; psyntax.pp has been loaded, the expansion of any macro definition,
165 ;;; whether local or global, results in a call to eval. If, however,
166 ;;; sc-expand has already been registered as the expander to be used
167 ;;; by eval, and eval accepts one argument, nothing special must be done
168 ;;; to support the "noexpand" flag, since it is handled by sc-expand.
170 ;;; (error who format-string why what)
171 ;;; where who is either a symbol or #f, format-string is always "~a ~s",
172 ;;; why is always a string, and what may be any object. error should
173 ;;; signal an error with a message something like
175 ;;; "error in <who>: <why> <what>"
178 ;;; returns a unique symbol each time it's called. In Chez Scheme, gensym
179 ;;; returns a symbol with a "globally" unique name so that gensyms that
180 ;;; end up in the object code of separately compiled files cannot conflict.
181 ;;; This is necessary only if you intend to support compiled files.
183 ;;; (putprop symbol key value)
184 ;;; (getprop symbol key)
185 ;;; (remprop symbol key)
186 ;;; key is always a symbol; value may be any object. putprop should
187 ;;; associate the given value with the given symbol and key in some way
188 ;;; that it can be retrieved later with getprop. getprop should return
189 ;;; #f if no value is associated with the given symbol and key. remprop
190 ;;; should remove the association between the given symbol and key.
192 ;;; When porting to a new Scheme implementation, you should define the
193 ;;; procedures listed above, load the expanded version of psyntax.ss
194 ;;; (psyntax.pp, which should be available whereever you found
195 ;;; psyntax.ss), and register sc-expand as the current expander (how
196 ;;; you do this depends upon your implementation of Scheme). You may
197 ;;; change the hooks and constructors defined toward the beginning of
198 ;;; the code below, but to avoid bootstrapping problems, do so only
199 ;;; after you have a working version of the expander.
201 ;;; Chez Scheme allows the syntactic form (syntax <template>) to be
202 ;;; abbreviated to #'<template>, just as (quote <datum>) may be
203 ;;; abbreviated to '<datum>. The #' syntax makes programs written
204 ;;; using syntax-case shorter and more readable and draws out the
205 ;;; intuitive connection between syntax and quote. If you have access
206 ;;; to the source code of your Scheme system's reader, you might want
207 ;;; to implement this extension.
209 ;;; If you find that this code loads or runs slowly, consider
210 ;;; switching to faster hardware or a faster implementation of
211 ;;; Scheme. In Chez Scheme on a 200Mhz Pentium Pro, expanding,
212 ;;; compiling (with full optimization), and loading this file takes
213 ;;; between one and two seconds.
215 ;;; In the expander implementation, we sometimes use syntactic abstractions
216 ;;; when procedural abstractions would suffice. For example, we define
217 ;;; top-wrap and top-marked? as
218 ;;; (define-syntax top-wrap (identifier-syntax '((top))))
219 ;;; (define-syntax top-marked?
221 ;;; ((_ w) (memq 'top (wrap-marks w)))))
223 ;;; (define top-wrap '((top)))
224 ;;; (define top-marked?
225 ;;; (lambda (w) (memq 'top (wrap-marks w))))
226 ;;; On ther other hand, we don't do this consistently; we define make-wrap,
227 ;;; wrap-marks, and wrap-subst simply as
228 ;;; (define make-wrap cons)
229 ;;; (define wrap-marks car)
230 ;;; (define wrap-subst cdr)
231 ;;; In Chez Scheme, the syntactic and procedural forms of these
232 ;;; abstractions are equivalent, since the optimizer consistently
233 ;;; integrates constants and small procedures. Some Scheme
234 ;;; implementations, however, may benefit from more consistent use
235 ;;; of one form or the other.
238 ;;; Implementation notes:
240 ;;; "begin" is treated as a splicing construct at top level and at
241 ;;; the beginning of bodies. Any sequence of expressions that would
242 ;;; be allowed where the "begin" occurs is allowed.
244 ;;; "let-syntax" and "letrec-syntax" are also treated as splicing
245 ;;; constructs, in violation of the R5RS. A consequence is that let-syntax
246 ;;; and letrec-syntax do not create local contours, as do let and letrec.
247 ;;; Although the functionality is greater as it is presently implemented,
248 ;;; we will probably change it to conform to the R5RS. modules provide
249 ;;; similar functionality to nonsplicing letrec-syntax when the latter is
250 ;;; used as a definition.
252 ;;; Objects with no standard print syntax, including objects containing
253 ;;; cycles and syntax objects, are allowed in quoted data as long as they
254 ;;; are contained within a syntax form or produced by datum->syntax-object.
255 ;;; Such objects are never copied.
257 ;;; When the expander encounters a reference to an identifier that has
258 ;;; no global or lexical binding, it treats it as a global-variable
259 ;;; reference. This allows one to write mutually recursive top-level
260 ;;; definitions, e.g.:
262 ;;; (define f (lambda (x) (g x)))
263 ;;; (define g (lambda (x) (f x)))
265 ;;; but may not always yield the intended when the variable in question
266 ;;; is later defined as a keyword.
268 ;;; Top-level variable definitions of syntax keywords are permitted.
269 ;;; In order to make this work, top-level define not only produces a
270 ;;; top-level definition in the core language, but also modifies the
271 ;;; compile-time environment (using $sc-put-cte) to record the fact
272 ;;; that the identifier is a variable.
274 ;;; Top-level definitions of macro-introduced identifiers are visible
275 ;;; only in code produced by the macro. That is, a binding for a
276 ;;; hidden (generated) identifier is created instead, and subsequent
277 ;;; references within the macro output are renamed accordingly. For
284 ;;; (define secret exp)
287 ;;; (set! secret (+ secret 17))
292 ;;; secret => Error: variable secret is not bound
294 ;;; The definition above would fail if the definition for secret
295 ;;; were placed after the definition for var, since the expander would
296 ;;; encounter the references to secret before the definition that
297 ;;; establishes the compile-time map from the identifier secret to
298 ;;; the generated identifier.
300 ;;; Identifiers and syntax objects are implemented as vectors for
301 ;;; portability. As a result, it is possible to "forge" syntax
304 ;;; The input to sc-expand may contain "annotations" describing, e.g., the
305 ;;; source file and character position from where each object was read if
306 ;;; it was read from a file. These annotations are handled properly by
307 ;;; sc-expand only if the annotation? hook (see hooks below) is implemented
308 ;;; properly and the operators make-annotation, annotation-expression,
309 ;;; annotation-source, annotation-stripped, and set-annotation-stripped!
310 ;;; are supplied. If annotations are supplied, the proper annotation
311 ;;; source is passed to the various output constructors, allowing
312 ;;; implementations to accurately correlate source and expanded code.
313 ;;; Contact one of the authors for details if you wish to make use of
316 ;;; Implementation of modules:
318 ;;; The implementation of modules requires that implicit top-level exports
319 ;;; be listed with the exported macro at some level where both are visible,
322 ;;; (module M (alpha (beta b))
323 ;;; (module ((alpha a) b)
324 ;;; (define-syntax alpha (identifier-syntax a))
327 ;;; (define-syntax beta (identifier-syntax b)))
329 ;;; Listing of implicit imports is not needed for macros that do not make
330 ;;; it out to top level, including all macros that are local to a "body".
331 ;;; (They may be listed in this case, however.) We need this information
332 ;;; for top-level modules since a top-level module expands into a letrec
333 ;;; for non-top-level variables and top-level definitions (assignments) for
334 ;;; top-level variables. Because of the general nature of macro
335 ;;; transformers, we cannot determine the set of implicit exports from the
336 ;;; transformer code, so without the user's help, we'd have to put all
337 ;;; variables at top level.
339 ;;; Each such top-level identifier is given a generated name (gensym).
340 ;;; When a top-level module is imported at top level, a compile-time
341 ;;; alias is established from the top-level name to the generated name.
342 ;;; The expander follows these aliases transparently. When any module is
343 ;;; imported anywhere other than at top level, the id-var-name of the
344 ;;; import identifier is set to the id-var-name of the export identifier.
345 ;;; Since we can't determine the actual labels for identifiers defined in
346 ;;; top-level modules until we determine which are placed in the letrec
347 ;;; and which make it to top level, we give each an "indirect" label---a
348 ;;; pair whose car will eventually contain the actual label. Import does
349 ;;; not follow the indirect, but id-var-name does.
351 ;;; All identifiers defined within a local module are folded into the
352 ;;; letrec created for the enclosing body. Visibility is controlled in
353 ;;; this case and for nested top-level modules by introducing a new wrap
359 ;;; When changing syntax-object representations, it is necessary to support
360 ;;; both old and new syntax-object representations in id-var-name. It
361 ;;; should be sufficient to recognize old representations and treat
362 ;;; them as not lexically bound.
369 ((_ test e1 e2 ...) (if test (begin e1 e2 ...)))))
370 (define-syntax unless
372 ((_ test e1 e2 ...) (when (not test) (begin e1 e2 ...)))))
373 (define-syntax define-structure
375 (define construct-name
376 (lambda (template-identifier . args)
377 (datum->syntax-object
384 (symbol->string (syntax-object->datum x))))
388 (andmap identifier? (syntax (name id1 ...)))
390 ((constructor (construct-name (syntax name) "make-" (syntax name)))
391 (predicate (construct-name (syntax name) (syntax name) "?"))
393 (map (lambda (x) (construct-name x (syntax name) "-" x))
397 (construct-name x "set-" (syntax name) "-" x "!"))
400 (+ (length (syntax (id1 ...))) 1))
402 (let f ((i 1) (ids (syntax (id1 ...))))
405 (cons i (f (+ i 1) (cdr ids)))))))
409 (vector 'name id1 ... )))
413 (= (vector-length x) structure-length)
414 (eq? (vector-ref x 0) 'name))))
417 (vector-ref x index)))
421 (vector-set! x index update)))
424 (define noexpand "noexpand")
426 ;;; hooks to nonportable run-time helpers
428 (define-syntax fx+ (identifier-syntax +))
429 (define-syntax fx- (identifier-syntax -))
430 (define-syntax fx= (identifier-syntax =))
431 (define-syntax fx< (identifier-syntax <))
433 (define annotation? (lambda (x) #f))
435 (define top-level-eval-hook
437 (eval `(,noexpand ,x))))
439 (define local-eval-hook
441 (eval `(,noexpand ,x))))
444 (lambda (who why what)
445 (error who "~a ~s" why what)))
447 (define-syntax gensym-hook
451 (define put-global-definition-hook
453 ($sc-put-cte symbol val)))
455 (define get-global-definition-hook
457 (getprop symbol '*sc-expander*)))
459 (define get-import-binding
460 (lambda (symbol token)
461 (getprop symbol token)))
464 (let ((b (- 127 32 2)))
465 ; session-key should generate a unique integer for each system run
466 ; to support separate compilation
467 (define session-key (lambda () 0))
468 (define make-digit (lambda (x) (integer->char (fx+ x 33))))
471 (let fmt ((n n) (a '()))
473 (list->string (cons (make-digit n) a))
474 (let ((r (modulo n b)) (rest (quotient n b)))
475 (fmt rest (cons (make-digit r) a)))))))
476 (let ((prefix (fmt (session-key))) (n -1))
479 (let ((newsym (string->symbol (string-append "#" prefix (fmt n)))))
484 ;;; output constructors
486 (define-syntax build-application
488 ((_ source fun-exp arg-exps)
489 `(,fun-exp . ,arg-exps))))
491 (define-syntax build-conditional
493 ((_ source test-exp then-exp else-exp)
494 `(if ,test-exp ,then-exp ,else-exp))))
496 (define-syntax build-lexical-reference
501 (define-syntax build-lexical-assignment
506 (define-syntax build-global-reference
511 (define-syntax build-global-assignment
516 (define-syntax build-global-definition
519 `(define ,var ,exp))))
521 (define-syntax build-module-definition
522 ; should have the effect of a global definition but may not appear at top level
523 (identifier-syntax build-global-assignment))
525 (define-syntax build-cte-install
526 ; should build a call that has the same effect as calling the
527 ; global definition hook
529 ((_ sym exp) `($sc-put-cte ',sym ,exp))))
531 (define-syntax build-lambda
534 `(lambda ,vars ,exp))))
536 (define-syntax build-primref
539 ((_ src level name) name)))
541 (define-syntax build-data
543 ((_ src exp) `',exp)))
545 (define build-sequence
547 (if (null? (cdr exps))
552 (lambda (src vars val-exps body-exp)
555 `(letrec ,(map list vars val-exps) ,body-exp))))
557 (define-syntax build-lexical-var
559 ((_ src id) (gensym))))
561 (define-syntax self-evaluating?
565 (or (boolean? x) (number? x) (string? x) (char? x) (null? x))))))
568 (define-structure (syntax-object expression wrap))
570 (define-syntax unannotate
575 (annotation-expression e)
578 (define-syntax no-source (identifier-syntax #f))
580 (define source-annotation
583 ((annotation? x) (annotation-source x))
584 ((syntax-object? x) (source-annotation (syntax-object-expression x)))
587 (define-syntax arg-check
591 (if (not (pred? x)) (error-hook who "invalid argument" x))))))
593 ;;; compile-time environments
595 ;;; wrap and environment comprise two level mapping.
596 ;;; wrap : id --> label
597 ;;; env : label --> <element>
599 ;;; environments are represented in two parts: a lexical part and a global
600 ;;; part. The lexical part is a simple list of associations from labels
601 ;;; to bindings. The global part is implemented by
602 ;;; {put,get}-global-definition-hook and associates symbols with
605 ;;; global (assumed global variable) and displaced-lexical (see below)
606 ;;; do not show up in any environment; instead, they are fabricated by
607 ;;; lookup when it finds no other bindings.
609 ;;; <environment> ::= ((<label> . <binding>)*)
611 ;;; identifier bindings include a type and a value
613 ;;; <binding> ::= (macro . <procedure>) macros
614 ;;; (deferred . <expanded code>) lazy-evaluation of transformers
615 ;;; (core . <procedure>) core forms
618 ;;; (define-syntax) define-syntax
619 ;;; (local-syntax . rec?) let-syntax/letrec-syntax
620 ;;; (eval-when) eval-when
621 ;;; (syntax . (<var> . <level>)) pattern variables
622 ;;; (global . <symbol>) assumed global variable
623 ;;; (lexical . <var>) lexical variables
624 ;;; (displaced-lexical . #f) id-var-name not found in store
625 ;;; <level> ::= <nonnegative integer>
626 ;;; <var> ::= variable returned by build-lexical-var
628 ;;; a macro is a user-defined syntactic-form. a core is a system-defined
629 ;;; syntactic form. begin, define, define-syntax, and eval-when are
630 ;;; treated specially since they are sensitive to whether the form is
631 ;;; at top-level and (except for eval-when) can denote valid internal
634 ;;; a pattern variable is a variable introduced by syntax-case and can
635 ;;; be referenced only within a syntax form.
637 ;;; any identifier for which no top-level syntax definition or local
638 ;;; binding of any kind has been seen is assumed to be a global
641 ;;; a lexical variable is a lambda- or letrec-bound variable.
643 ;;; a displaced-lexical identifier is a lexical identifier removed from
644 ;;; it's scope by the return of a syntax object containing the identifier.
645 ;;; a displaced lexical can also appear when a letrec-syntax-bound
646 ;;; keyword is referenced on the rhs of one of the letrec-syntax clauses.
647 ;;; a displaced lexical should never occur with properly written macros.
649 (define make-binding (lambda (x y) (cons x y)))
650 (define binding-type car)
651 (define binding-value cdr)
652 (define set-binding-type! set-car!)
653 (define set-binding-value! set-cdr!)
654 (define binding? (lambda (x) (and (pair? x) (symbol? (car x)))))
656 (define-syntax null-env (identifier-syntax '()))
659 (lambda (label binding r)
660 (cons (cons label binding) r)))
663 (lambda (labels bindings r)
666 (extend-env* (cdr labels) (cdr bindings)
667 (extend-env (car labels) (car bindings) r)))))
669 (define extend-var-env*
670 ; variant of extend-env* that forms "lexical" binding
671 (lambda (labels vars r)
674 (extend-var-env* (cdr labels) (cdr vars)
675 (extend-env (car labels) (make-binding 'lexical (car vars)) r)))))
677 ;;; we use a "macros only" environment in expansion of local macro
678 ;;; definitions so that their definitions can use local macros without
679 ;;; attempting to use other lexical identifiers.
681 ;;; - can make this null-env if we don't want to allow macros to use other
682 ;;; macros in defining their transformers
683 ;;; - can add a cache here if it pays off
684 (define transformer-env
689 (if (eq? (cadr a) 'lexical) ; only strip out lexical so that (transformer x) works
690 (transformer-env (cdr r))
691 (cons a (transformer-env (cdr r))))))))
693 (define displaced-lexical-error
696 (if (id-var-name id empty-wrap)
697 "identifier out of context"
698 "identifier not visible"))))
701 ; x may be a label or a symbol
702 ; although symbols are usually global, we check the environment first
703 ; anyway because a temporary binding may have been established by
709 (or (get-global-definition-hook x) (make-binding 'global x)))
710 (else (make-binding 'displaced-lexical #f)))))
712 (define sanitize-binding
715 ((procedure? b) (make-binding 'macro b))
717 (case (binding-type b)
718 ((core macro macro!) (and (procedure? (binding-value b)) b))
719 ((module) (and (interface? (binding-value b)) b))
725 (define whack-binding!
727 (set-binding-type! b (binding-type *b))
728 (set-binding-value! b (binding-value *b))))
729 (let ((b (lookup* x r)))
730 (case (binding-type b)
731 ; ((*alias) (lookup (id-var-name (binding-value b) empty-wrap) r))
734 (let ((*b (local-eval-hook (binding-value b))))
735 (or (sanitize-binding *b)
736 (syntax-error *b "invalid transformer"))))
737 (case (binding-type b)
738 ; ((*alias) (lookup (id-var-name (binding-value b) empty-wrap) r))
742 (define global-extend
743 (lambda (type sym val)
744 (put-global-definition-hook sym (make-binding type val))))
747 ;;; Conceptually, identifiers are always syntax objects. Internally,
748 ;;; however, the wrap is sometimes maintained separately (a source of
749 ;;; efficiency and confusion), so that symbols are also considered
750 ;;; identifiers by id?. Externally, they are always wrapped.
752 (define nonsymbol-id?
754 (and (syntax-object? x)
755 (symbol? (unannotate (syntax-object-expression x))))))
761 ((syntax-object? x) (symbol? (unannotate (syntax-object-expression x))))
762 ((annotation? x) (symbol? (annotation-expression x)))
765 (define-syntax id-sym-name
769 (unannotate (if (syntax-object? x) (syntax-object-expression x) x))))))
771 (define id-sym-name&marks
773 (if (syntax-object? x)
775 (unannotate (syntax-object-expression x))
776 (join-marks (wrap-marks w) (wrap-marks (syntax-object-wrap x))))
777 (values (unannotate x) (wrap-marks w)))))
779 ;;; syntax object wraps
781 ;;; <wrap> ::= ((<mark> ...) . (<subst> ...))
782 ;;; <subst> ::= <ribcage> | <shift>
783 ;;; <ribcage> ::= #((<ex-symname> ...) (<mark> ...) (<label> ...)) ; extensible, for chi-internal/external
784 ;;; | #(#(<symname> ...) #(<mark> ...) #(<label> ...)) ; nonextensible
785 ;;; <ex-symname> ::= <symname> | <import token> | <barrier>
786 ;;; <shift> ::= shift
787 ;;; <barrier> ::= #f ; inserted by import-only
788 ;;; <import token> ::= #<"import-token" <token>>
789 ;;; <token> ::= <generated id>
791 (define make-wrap cons)
792 (define wrap-marks car)
793 (define wrap-subst cdr)
795 (define-syntax subst-rename? (identifier-syntax vector?))
796 (define-syntax rename-old (syntax-rules () ((_ x) (vector-ref x 0))))
797 (define-syntax rename-new (syntax-rules () ((_ x) (vector-ref x 1))))
798 (define-syntax rename-marks (syntax-rules () ((_ x) (vector-ref x 2))))
799 (define-syntax make-rename
801 ((_ old new marks) (vector old new marks))))
805 ;;; simple labels must be comparable with "eq?" and distinct from symbols
808 ;;; indirect labels, which are implemented as pairs, are used to support
809 ;;; import aliasing for identifiers exported (explictly or implicitly) from
810 ;;; top-level modules. chi-external creates an indirect label for each
811 ;;; defined identifier, import causes the pair to be shared aliases it
812 ;;; establishes, and chi-top-module whacks the pair to hold the top-level
813 ;;; identifier name (symbol) if the id is to be placed at top level, before
814 ;;; expanding the right-hand sides of the definitions in the module.
817 (lambda () (string #\i)))
820 (or (string? x) ; normal lexical labels
821 (symbol? x) ; global labels (symbolic names)
822 (indirect-label? x))))
828 (cons (gen-label) (gen-labels (cdr ls))))))
830 (define gen-indirect-label
831 (lambda () (list (gen-label))))
833 (define indirect-label? pair?)
834 (define get-indirect-label car)
835 (define set-indirect-label! set-car!)
837 (define-structure (ribcage symnames marks labels))
838 (define-syntax empty-wrap (identifier-syntax '(())))
840 (define-syntax top-wrap (identifier-syntax '((top))))
842 (define-syntax top-marked?
844 ((_ w) (memq 'top (wrap-marks w)))))
846 (define-syntax only-top-marked?
848 ((_ id) (same-marks? (wrap-marks (syntax-object-wrap id)) (wrap-marks top-wrap)))))
850 ;;; Marks must be comparable with "eq?" and distinct from pairs and
851 ;;; the symbol top. We do not use integers so that marks will remain
852 ;;; unique even across file compiles.
854 (define-syntax the-anti-mark (identifier-syntax #f))
858 (make-wrap (cons the-anti-mark (wrap-marks w))
859 (cons 'shift (wrap-subst w)))))
861 (define-syntax new-mark
865 (define barrier-marker #f)
866 (module (make-import-token import-token? import-token-key)
867 (define tag 'import-token)
868 (define make-import-token (lambda (x) (cons tag x)))
869 (define import-token? (lambda (x) (and (pair? x) (eq? (car x) tag))))
870 (define import-token-key cdr))
872 ;;; make-empty-ribcage and extend-ribcage maintain list-based ribcages for
873 ;;; internal definitions, in which the ribcages are built incrementally
874 (define-syntax make-empty-ribcage
876 ((_) (make-ribcage '() '() '()))))
878 (define extend-ribcage!
879 ; must receive ids with complete wraps
880 ; ribcage guaranteed to be list-based
881 (lambda (ribcage id label)
882 (set-ribcage-symnames! ribcage
883 (cons (unannotate (syntax-object-expression id))
884 (ribcage-symnames ribcage)))
885 (set-ribcage-marks! ribcage
886 (cons (wrap-marks (syntax-object-wrap id))
887 (ribcage-marks ribcage)))
888 (set-ribcage-labels! ribcage
889 (cons label (ribcage-labels ribcage)))))
891 (define extend-ribcage-barrier!
892 ; must receive ids with complete wraps
893 ; ribcage guaranteed to be list-based
894 (lambda (ribcage killer-id)
895 (extend-ribcage-barrier-help! ribcage (syntax-object-wrap killer-id))))
897 (define extend-ribcage-barrier-help!
898 (lambda (ribcage wrap)
899 (set-ribcage-symnames! ribcage
900 (cons barrier-marker (ribcage-symnames ribcage)))
901 (set-ribcage-marks! ribcage
902 (cons (wrap-marks wrap) (ribcage-marks ribcage)))))
904 (define extend-ribcage-subst!
905 ; ribcage guaranteed to be list-based
906 (lambda (ribcage token)
907 (set-ribcage-symnames! ribcage
908 (cons (make-import-token token) (ribcage-symnames ribcage)))))
910 (define lookup-import-binding-name
911 (lambda (sym key marks)
912 (let ((new (get-import-binding sym key)))
916 ((pair? new) (or (f (car new)) (f (cdr new))))
917 ((same-marks? marks (wrap-marks (syntax-object-wrap new))) new)
920 ;;; make-binding-wrap creates vector-based ribcages
921 (define make-binding-wrap
922 (lambda (ids labels w)
928 (let ((labelvec (list->vector labels)))
929 (let ((n (vector-length labelvec)))
930 (let ((symnamevec (make-vector n)) (marksvec (make-vector n)))
931 (let f ((ids ids) (i 0))
932 (if (not (null? ids))
934 (lambda () (id-sym-name&marks (car ids) w))
935 (lambda (symname marks)
936 (vector-set! symnamevec i symname)
937 (vector-set! marksvec i marks)
938 (f (cdr ids) (fx+ i 1))))))
939 (make-ribcage symnamevec marksvec labelvec))))
942 ;;; make-trimmed-syntax-object is used by make-resolved-interface to support
943 ;;; creation of module export lists whose constituent ids do not contain
944 ;;; unnecessary substitutions or marks.
945 (define make-trimmed-syntax-object
948 (lambda () (id-var-name&marks id empty-wrap))
949 (lambda (tosym marks)
951 (syntax-error id "identifier not visible for export"))
952 (let ((fromsym (id-sym-name id)))
953 (make-syntax-object fromsym
955 (list (make-ribcage (vector fromsym) (vector marks) (vector tosym))))))))))
957 ;;; Scheme's append should not copy the first argument if the second is
958 ;;; nil, but it does, so we define a smart version here.
967 (let ((m1 (wrap-marks w1)) (s1 (wrap-subst w1)))
973 (smart-append s1 (wrap-subst w2))))
975 (smart-append m1 (wrap-marks w2))
976 (smart-append s1 (wrap-subst w2)))))))
980 (smart-append m1 m2)))
987 (eq? (car x) (car y))
988 (same-marks? (cdr x) (cdr y))))))
990 (define id-var-name-loc&marks
993 (lambda (sym subst marks)
996 (let ((fst (car subst)))
998 (search sym (cdr subst) (cdr marks))
999 (let ((symnames (ribcage-symnames fst)))
1000 (if (vector? symnames)
1001 (search-vector-rib sym subst marks symnames fst)
1002 (search-list-rib sym subst marks symnames fst))))))))
1003 (define search-list-rib
1004 (lambda (sym subst marks symnames ribcage)
1005 (let f ((symnames symnames) (i 0))
1007 ((null? symnames) (search sym (cdr subst) marks))
1008 ((and (eq? (car symnames) sym)
1009 (same-marks? marks (list-ref (ribcage-marks ribcage) i)))
1010 (values (list-ref (ribcage-labels ribcage) i) marks))
1011 ((import-token? (car symnames))
1013 ((lookup-import-binding-name sym (import-token-key (car symnames)) marks) =>
1017 (id-var-name&marks id empty-wrap)))) ; could be more efficient: new is a resolved id
1018 (else (f (cdr symnames) i))))
1019 ((and (eq? (car symnames) barrier-marker)
1020 (same-marks? marks (list-ref (ribcage-marks ribcage) i)))
1022 (else (f (cdr symnames) (fx+ i 1)))))))
1023 (define search-vector-rib
1024 (lambda (sym subst marks symnames ribcage)
1025 (let ((n (vector-length symnames)))
1028 ((fx= i n) (search sym (cdr subst) marks))
1029 ((and (eq? (vector-ref symnames i) sym)
1030 (same-marks? marks (vector-ref (ribcage-marks ribcage) i)))
1031 (values (vector-ref (ribcage-labels ribcage) i) marks))
1032 (else (f (fx+ i 1))))))))
1034 ((symbol? id) (search id (wrap-subst w) (wrap-marks w)))
1035 ((syntax-object? id)
1036 (let ((sym (unannotate (syntax-object-expression id)))
1037 (w1 (syntax-object-wrap id)))
1038 (let ((marks (join-marks (wrap-marks w) (wrap-marks w1))))
1039 (call-with-values (lambda () (search sym (wrap-subst w) marks))
1040 (lambda (new-id marks)
1041 (if (eq? new-id sym)
1042 (search sym (wrap-subst w1) marks)
1043 (values new-id marks)))))))
1044 ((annotation? id) (search (unannotate id) (wrap-subst w) (wrap-marks w)))
1045 (else (error-hook 'id-var-name "invalid id" id)))))
1047 (define id-var-name&marks
1048 ; this version follows indirect labels
1051 (lambda () (id-var-name-loc&marks id w))
1052 (lambda (label marks)
1053 (values (if (indirect-label? label) (get-indirect-label label) label) marks)))))
1055 (define id-var-name-loc
1056 ; this version doesn't follow indirect labels
1059 (lambda () (id-var-name-loc&marks id w))
1060 (lambda (label marks) label))))
1063 ; this version follows indirect labels
1066 (lambda () (id-var-name-loc&marks id w))
1067 (lambda (label marks)
1068 (if (indirect-label? label) (get-indirect-label label) label)))))
1070 ;;; free-id=? must be passed fully wrapped ids since (free-id=? x y)
1071 ;;; may be true even if (free-id=? (wrap x w) (wrap y w)) is not.
1075 (and (eq? (id-sym-name i) (id-sym-name j)) ; accelerator
1076 (eq? (id-var-name i empty-wrap) (id-var-name j empty-wrap)))))
1078 (define-syntax literal-id=? (identifier-syntax free-id=?))
1080 ;;; bound-id=? may be passed unwrapped (or partially wrapped) ids as
1081 ;;; long as the missing portion of the wrap is common to both of the ids
1082 ;;; since (bound-id=? x y) iff (bound-id=? (wrap x w) (wrap y w))
1086 (if (and (syntax-object? i) (syntax-object? j))
1087 (and (eq? (unannotate (syntax-object-expression i))
1088 (unannotate (syntax-object-expression j)))
1089 (same-marks? (wrap-marks (syntax-object-wrap i))
1090 (wrap-marks (syntax-object-wrap j))))
1091 (eq? (unannotate i) (unannotate j)))))
1093 ;;; "valid-bound-ids?" returns #t if it receives a list of distinct ids.
1094 ;;; valid-bound-ids? may be passed unwrapped (or partially wrapped) ids
1095 ;;; as long as the missing portion of the wrap is common to all of the
1098 (define valid-bound-ids?
1100 (and (let all-ids? ((ids ids))
1102 (and (id? (car ids))
1103 (all-ids? (cdr ids)))))
1104 (distinct-bound-ids? ids))))
1106 ;;; distinct-bound-ids? expects a list of ids and returns #t if there are
1107 ;;; no duplicates. It is quadratic on the length of the id list; long
1108 ;;; lists could be sorted to make it more efficient. distinct-bound-ids?
1109 ;;; may be passed unwrapped (or partially wrapped) ids as long as the
1110 ;;; missing portion of the wrap is common to all of the ids.
1112 (define distinct-bound-ids?
1114 (let distinct? ((ids ids))
1116 (and (not (bound-id-member? (car ids) (cdr ids)))
1117 (distinct? (cdr ids)))))))
1119 (define invalid-ids-error
1120 ; find first bad one and complain about it
1121 (lambda (ids exp class)
1122 (let find ((ids ids) (gooduns '()))
1124 (syntax-error exp) ; shouldn't happen
1126 (if (bound-id-member? (car ids) gooduns)
1127 (syntax-error (car ids) "duplicate " class)
1128 (find (cdr ids) (cons (car ids) gooduns)))
1129 (syntax-error (car ids) "invalid " class))))))
1131 (define bound-id-member?
1133 (and (not (null? list))
1134 (or (bound-id=? x (car list))
1135 (bound-id-member? x (cdr list))))))
1137 ;;; wrapping expressions and identifiers
1142 ((and (null? (wrap-marks w)) (null? (wrap-subst w))) x)
1145 (syntax-object-expression x)
1146 (join-wraps w (syntax-object-wrap x))))
1148 (else (make-syntax-object x w)))))
1152 (wrap (if s (make-annotation x s #f) x) w)))
1156 (define chi-sequence
1157 (lambda (body r w s)
1159 (let dobody ((body body) (r r) (w w))
1162 (let ((first (chi (car body) r w)))
1163 (cons first (dobody (cdr body) r w))))))))
1165 (define chi-top-sequence
1166 (lambda (body r w s m esew ribcage)
1168 (let dobody ((body body) (r r) (w w) (m m) (esew esew))
1171 (let ((first (chi-top (car body) r w m esew ribcage)))
1172 (cons first (dobody (cdr body) r w m esew))))))))
1174 (define chi-when-list
1175 (lambda (e when-list w)
1176 ; when-list is syntax'd version of list of situations
1177 (let f ((when-list when-list) (situations '()))
1178 (if (null? when-list)
1181 (cons (let ((x (car when-list)))
1183 ((literal-id=? x (syntax compile)) 'compile)
1184 ((literal-id=? x (syntax load)) 'load)
1185 ((literal-id=? x (syntax eval)) 'eval)
1186 (else (syntax-error (wrap x w)
1187 "invalid eval-when situation"))))
1190 ;;; syntax-type returns five values: type, value, e, w, and s. The first
1191 ;;; two are described in the table below.
1193 ;;; type value explanation
1194 ;;; -------------------------------------------------------------------
1195 ;;; begin none begin keyword
1196 ;;; begin-form none begin expression
1197 ;;; call none any other call
1198 ;;; constant none self-evaluating datum
1199 ;;; core procedure core form (including singleton)
1200 ;;; define none define keyword
1201 ;;; define-form none variable definition
1202 ;;; define-syntax none define-syntax keyword
1203 ;;; define-syntax-form none syntax definition
1204 ;;; displaced-lexical none displaced lexical identifier
1205 ;;; eval-when none eval-when keyword
1206 ;;; eval-when-form none eval-when form
1207 ;;; global name global variable reference
1208 ;;; import none import keyword
1209 ;;; import-form none import form
1210 ;;; lexical name lexical variable reference
1211 ;;; lexical-call name call to lexical variable
1212 ;;; local-syntax rec? letrec-syntax/let-syntax keyword
1213 ;;; local-syntax-form rec? syntax definition
1214 ;;; module none module keyword
1215 ;;; module-form none module definition
1216 ;;; other none anything else
1217 ;;; syntax level pattern variable
1219 ;;; For all forms, e is the form, w is the wrap for e. and s is the source.
1221 ;;; syntax-type expands macros and unwraps as necessary to get to
1222 ;;; one of the forms above.
1225 (lambda (e r w s rib)
1228 (let* ((n (id-var-name e w))
1230 (type (binding-type b)))
1232 ((lexical) (values type (binding-value b) e w s))
1233 ((global) (values type (binding-value b) e w s))
1234 ((macro macro!) (syntax-type (chi-macro (binding-value b) e r w s rib) r empty-wrap #f rib))
1235 (else (values type (binding-value b) e w s)))))
1237 (let ((first (car e)))
1239 (let* ((n (id-var-name first w))
1241 (type (binding-type b)))
1243 ((lexical) (values 'lexical-call (binding-value b) e w s))
1245 (syntax-type (chi-macro (binding-value b) e r w s rib)
1246 r empty-wrap #f rib))
1247 ((core) (values type (binding-value b) e w s))
1249 (values 'local-syntax-form (binding-value b) e w s))
1250 ((begin) (values 'begin-form #f e w s))
1251 ((eval-when) (values 'eval-when-form #f e w s))
1252 ((define) (values 'define-form #f e w s))
1253 ((define-syntax) (values 'define-syntax-form #f e w s))
1254 ((module-key) (values 'module-form #f e w s))
1255 ((import) (values 'import-form (and (binding-value b) (wrap first w)) e w s))
1256 ((set!) (chi-set! e r w s rib))
1257 (else (values 'call #f e w s))))
1258 (values 'call #f e w s))))
1260 ;; s can't be valid source if we've unwrapped
1261 (syntax-type (syntax-object-expression e)
1263 (join-wraps w (syntax-object-wrap e))
1266 (syntax-type (annotation-expression e) r w (annotation-source e) rib))
1267 ((self-evaluating? e) (values 'constant #f e w s))
1268 (else (values 'other #f e w s)))))
1270 (define chi-top-expr
1271 (lambda (e r w top-ribcage)
1273 (lambda () (syntax-type e r w no-source top-ribcage))
1274 (lambda (type value e w s)
1275 (chi-expr type value e r w s)))))
1278 (lambda (e r w m esew top-ribcage)
1279 (define-syntax eval-if-c&e
1283 (if (eq? m 'c&e) (top-level-eval-hook x))
1286 (lambda () (syntax-type e r w no-source top-ribcage))
1287 (lambda (type value e w s)
1293 (chi-top-sequence (syntax (e1 e2 ...)) r w s m esew top-ribcage))))
1294 ((local-syntax-form)
1295 (chi-local-syntax value e r w s
1296 (lambda (body r w s)
1297 (chi-top-sequence body r w s m esew top-ribcage))))
1300 ((_ (x ...) e1 e2 ...)
1301 (let ((when-list (chi-when-list e (syntax (x ...)) w))
1302 (body (syntax (e1 e2 ...))))
1305 (if (memq 'eval when-list)
1306 (chi-top-sequence body r w s 'e '(eval) top-ribcage)
1308 ((memq 'load when-list)
1309 (if (or (memq 'compile when-list)
1310 (and (eq? m 'c&e) (memq 'eval when-list)))
1311 (chi-top-sequence body r w s 'c&e '(compile load) top-ribcage)
1312 (if (memq m '(c c&e))
1313 (chi-top-sequence body r w s 'c '(load) top-ribcage)
1315 ((or (memq 'compile when-list)
1316 (and (eq? m 'c&e) (memq 'eval when-list)))
1317 (top-level-eval-hook
1318 (chi-top-sequence body r w s 'e '(eval) top-ribcage))
1320 (else (chi-void)))))))
1321 ((define-syntax-form)
1322 (parse-define-syntax e w s
1324 (let ((id (wrap id w)))
1325 (let ((n (id-var-name id empty-wrap)))
1326 (let ((b (lookup n r)))
1327 (case (binding-type b)
1328 ((displaced-lexical) (displaced-lexical-error id)))))
1329 (ct-eval/residualize m esew
1332 (let ((sym (id-sym-name id)))
1333 (if (only-top-marked? id)
1335 (let ((marks (wrap-marks (syntax-object-wrap id))))
1336 (make-syntax-object sym
1338 (list (make-ribcage (vector sym)
1339 (vector marks) (vector (generate-id sym)))))))))
1340 (chi rhs (transformer-env r) w))))))))
1344 (let ((id (wrap id w)))
1345 (let ((n (id-var-name id empty-wrap)))
1346 (let ((b (lookup n r)))
1347 (case (binding-type b)
1348 ((displaced-lexical) (displaced-lexical-error id)))))
1349 (let ((sym (id-sym-name id)))
1350 (let ((valsym (if (only-top-marked? id) sym (generate-id sym))))
1351 (build-sequence no-source
1353 (ct-eval/residualize m esew
1356 (if (eq? sym valsym)
1358 (let ((marks (wrap-marks (syntax-object-wrap id))))
1359 (make-syntax-object sym
1361 (list (make-ribcage (vector sym)
1362 (vector marks) (vector valsym)))))))
1363 (build-data no-source (make-binding 'global valsym)))))
1364 (eval-if-c&e m (build-global-definition s valsym (chi rhs r w))))))
1367 (let ((r (cons '("top-level module placeholder" . (placeholder)) r))
1368 (ribcage (make-empty-ribcage)))
1369 (parse-module e w s (make-wrap (wrap-marks w) (cons ribcage (wrap-subst w)))
1370 (lambda (id exports forms)
1373 (let ((n (id-var-name id empty-wrap)))
1374 (let ((b (lookup n r)))
1375 (case (binding-type b)
1376 ((displaced-lexical) (displaced-lexical-error (wrap id w))))))
1377 (chi-top-module e r ribcage w s m esew id exports forms))
1378 (chi-top-module e r ribcage w s m esew #f exports forms))))))
1382 (ct-eval/residualize m esew
1384 (when value (syntax-error (source-wrap e w s) "not valid at top-level"))
1385 (let ((binding (lookup (id-var-name mid empty-wrap) null-env)))
1386 (case (binding-type binding)
1387 ((module) (do-top-import mid (interface-token (binding-value binding))))
1388 ((displaced-lexical) (displaced-lexical-error mid))
1389 (else (syntax-error mid "import from unknown module")))))))))
1390 (else (eval-if-c&e m (chi-expr type value e r w s))))))))
1392 (define flatten-exports
1394 (let loop ((exports exports) (ls '()))
1398 (if (pair? (car exports))
1399 (loop (car exports) ls)
1400 (cons (car exports) ls)))))))
1403 (define-structure (interface exports token))
1405 (define make-trimmed-interface
1406 ; trim out implicit exports
1409 (list->vector (map (lambda (x) (if (pair? x) (car x) x)) exports))
1412 (define make-resolved-interface
1413 ; trim out implicit exports & resolve others to actual top-level symbol
1414 (lambda (exports import-token)
1416 (list->vector (map (lambda (x) (make-trimmed-syntax-object (if (pair? x) (car x) x))) exports))
1419 (define-structure (module-binding type id label imps val))
1421 (define chi-top-module
1422 (lambda (e r ribcage w s m esew id exports forms)
1423 (let ((fexports (flatten-exports exports)))
1424 (chi-external ribcage (source-wrap e w s)
1425 (map (lambda (d) (cons r d)) forms) r exports fexports m esew
1426 (lambda (bindings inits)
1427 ; dvs & des: "defined" (letrec-bound) vars & rhs expressions
1428 ; svs & ses: "set!" (top-level) vars & rhs expressions
1429 (let partition ((fexports fexports) (bs bindings) (svs '()) (ses '()) (ctdefs '()))
1430 (if (null? fexports)
1431 ; remaining bindings are either local vars or local macros/modules
1432 (let partition ((bs bs) (dvs '()) (des '()))
1434 (let ((ses (map (lambda (x) (chi (cdr x) (car x) empty-wrap)) ses))
1435 (des (map (lambda (x) (chi (cdr x) (car x) empty-wrap)) des))
1436 (inits (map (lambda (x) (chi (cdr x) (car x) empty-wrap)) inits)))
1437 ; we wait to do this here so that expansion of des & ses use
1438 ; local versions, which in particular, allows us to use macros
1439 ; locally even if esew tells us not to eval them
1440 (for-each (lambda (x)
1441 (apply (lambda (t label sym val)
1442 (when label (set-indirect-label! label sym)))
1445 (build-sequence no-source
1446 (list (ct-eval/residualize m esew
1450 (build-sequence no-source
1452 (apply (lambda (t label sym val)
1453 (build-cte-install sym
1454 (if (eq? t 'define-syntax-form)
1456 (build-data no-source
1457 (make-binding 'module
1458 (make-resolved-interface val sym))))))
1461 (ct-eval/residualize m esew
1463 (let ((n (if id (id-sym-name id) #f)))
1464 (let* ((token (generate-id n))
1465 (b (build-data no-source
1466 (make-binding 'module
1467 (make-resolved-interface exports token)))))
1470 (if (only-top-marked? id)
1472 (let ((marks (wrap-marks (syntax-object-wrap id))))
1473 (make-syntax-object n
1475 (list (make-ribcage (vector n)
1476 (vector marks) (vector (generate-id n))))))))
1478 (let ((n (generate-id 'tmp)))
1479 (build-sequence no-source
1480 (list (build-cte-install n b)
1481 (do-top-import n token)))))))))
1482 ; Some systems complain when undefined variables are assigned.
1483 (build-sequence no-source
1484 (map (lambda (v) (build-global-definition no-source v (chi-void))) svs))
1485 (build-letrec no-source
1488 (build-sequence no-source
1492 (build-sequence no-source
1494 (build-module-definition no-source v e))
1499 (build-sequence no-source inits)))))
1502 (case (module-binding-type b)
1504 (let ((var (gen-var (module-binding-id b))))
1506 (get-indirect-label (module-binding-label b))
1507 (make-binding 'lexical var))
1508 (partition (cdr bs) (cons var dvs)
1509 (cons (module-binding-val b) des))))
1510 ((define-syntax-form module-form) (partition (cdr bs) dvs des))
1511 (else (error 'sc-expand-internal "unexpected module binding type"))))))
1512 (let ((id (car fexports)) (fexports (cdr fexports)))
1513 (define pluck-binding
1514 (lambda (id bs succ fail)
1515 (let loop ((bs bs) (new-bs '()))
1518 (if (bound-id=? (module-binding-id (car bs)) id)
1519 (succ (car bs) (smart-append (reverse new-bs) (cdr bs)))
1520 (loop (cdr bs) (cons (car bs) new-bs)))))))
1521 (pluck-binding id bs
1523 (let ((t (module-binding-type b))
1524 (label (module-binding-label b))
1525 (imps (module-binding-imps b)))
1526 (let ((fexports (append imps fexports))
1527 (sym (generate-id (id-sym-name id))))
1530 (set-indirect-label! label sym)
1531 (partition fexports bs (cons sym svs)
1532 (cons (module-binding-val b) ses)
1534 ((define-syntax-form)
1535 (partition fexports bs svs ses
1536 (cons (list t label sym (module-binding-val b)) ctdefs)))
1538 (let ((exports (module-binding-val b)))
1539 (partition (append (flatten-exports exports) fexports) bs
1541 (cons (list t label sym exports) ctdefs))))
1542 (else (error 'sc-expand-internal "unexpected module binding type"))))))
1543 (lambda () (partition fexports bs svs ses ctdefs)))))))))))
1546 (lambda (exports defs)
1548 ((null? exports) '())
1549 ((bound-id-member? (car exports) defs) (id-set-diff (cdr exports) defs))
1550 (else (cons (car exports) (id-set-diff (cdr exports) defs))))))
1552 (define extend-store!
1553 (lambda (r label binding)
1554 (set-cdr! r (extend-env label binding (cdr r)))))
1556 (define check-module-exports
1557 ; After processing the definitions of a module this is called to verify that the
1558 ; module has defined or imported each exported identifier. Because ids in fexports are
1559 ; wrapped with the given ribcage, they will contain substitutions for anything defined
1560 ; or imported here. These subsitutions can be used by do-import! and do-import-top! to
1561 ; provide access to reexported bindings, for example.
1562 (lambda (source-exp fexports ids)
1567 (let ((token (interface-token x)))
1569 (lookup-import-binding-name (id-sym-name e) token (wrap-marks (syntax-object-wrap e)))
1570 (let ((v (interface-exports x)))
1571 (let lp ((i (fx- (vector-length v) 1)))
1573 (or (bound-id=? e (vector-ref v i))
1574 (lp (fx- i 1))))))))
1577 (let loop ((fexports fexports) (missing '()))
1578 (if (null? fexports)
1579 (unless (null? missing) (syntax-error missing "missing definition for export(s)"))
1580 (let ((e (car fexports)) (fexports (cdr fexports)))
1581 (if (defined? e ids)
1582 (loop fexports missing)
1583 (loop fexports (cons e missing))))))))
1585 (define check-defined-ids
1586 (lambda (source-exp ls)
1588 ; cope with fat-fingered top-level
1593 (and (eq? x (id-sym-name y))
1594 (same-marks? (wrap-marks (syntax-object-wrap y)) (wrap-marks top-wrap))))
1596 (and (eq? y (id-sym-name x))
1597 (same-marks? (wrap-marks (syntax-object-wrap x)) (wrap-marks top-wrap)))
1598 (bound-id=? x y)))))
1601 (let ((len (vector-length v)))
1602 (let lp ((i 0) (cls cls))
1605 (lp (fx+ i 1) (p (vector-ref v i) cls)))))))
1612 (let ((xe (interface-exports x)) (ye (interface-exports y)))
1613 (if (fx> (vector-length xe) (vector-length ye))
1616 (lambda (iface exports)
1617 (vfold exports (lambda (id cls) (id-iface-conflicts id iface cls)) cls)))
1618 (id-iface-conflicts y x cls))
1620 (id-iface-conflicts x y cls)
1621 (if (b-i=? x y) (cons x cls) cls)))))
1622 (define id-iface-conflicts
1623 (lambda (id iface cls)
1624 (let ((token (interface-token iface)))
1626 (if (lookup-import-binding-name (id-sym-name id) token
1628 (wrap-marks top-wrap)
1629 (wrap-marks (syntax-object-wrap id))))
1632 (vfold (interface-exports iface)
1633 (lambda (*id cls) (if (b-i=? *id id) (cons *id cls) cls))
1636 (let lp ((x (car ls)) (ls (cdr ls)) (cls '()))
1639 (let ((cls (syntax-object->datum cls)))
1640 (syntax-error source-exp "duplicate definition for "
1641 (symbol->string (car cls))
1643 (let lp2 ((ls2 ls) (cls cls))
1645 (lp (car ls) (cdr ls) cls)
1646 (lp2 (cdr ls2) (conflicts x (car ls2) cls)))))))))
1648 (define chi-external
1649 (lambda (ribcage source-exp body r exports fexports m esew k)
1651 (lambda (bindings ids inits)
1652 (check-defined-ids source-exp ids)
1653 (check-module-exports source-exp fexports ids)
1654 (k bindings inits)))
1655 (define get-implicit-exports
1657 (let f ((exports exports))
1660 (if (and (pair? (car exports)) (bound-id=? id (caar exports)))
1661 (flatten-exports (cdar exports))
1662 (f (cdr exports)))))))
1663 (define update-imp-exports
1664 (lambda (bindings exports)
1665 (let ((exports (map (lambda (x) (if (pair? x) (car x) x)) exports)))
1667 (let ((id (module-binding-id b)))
1668 (if (not (bound-id-member? id exports))
1670 (make-module-binding
1671 (module-binding-type b)
1673 (module-binding-label b)
1674 (append (get-implicit-exports id) (module-binding-imps b))
1675 (module-binding-val b)))))
1677 (let parse ((body body) (ids '()) (bindings '()) (inits '()))
1679 (return bindings ids inits)
1680 (let ((e (cdar body)) (er (caar body)))
1682 (lambda () (syntax-type e er empty-wrap no-source ribcage))
1683 (lambda (type value e w s)
1688 (let* ((id (wrap id w))
1689 (label (gen-indirect-label))
1690 (imps (get-implicit-exports id)))
1691 (extend-ribcage! ribcage id label)
1695 (cons (make-module-binding type id label
1696 imps (cons er (wrap rhs w)))
1699 ((define-syntax-form)
1700 (parse-define-syntax e w s
1702 (let* ((id (wrap id w))
1703 (label (gen-indirect-label))
1704 (imps (get-implicit-exports id))
1705 (exp (chi rhs (transformer-env er) w)))
1706 ; arrange to evaluate the transformer lazily
1707 (extend-store! r (get-indirect-label label) (cons 'deferred exp))
1708 (extend-ribcage! ribcage id label)
1712 (cons (make-module-binding type id label imps exp)
1716 (let* ((*ribcage (make-empty-ribcage))
1717 (*w (make-wrap (wrap-marks w) (cons *ribcage (wrap-subst w)))))
1718 (parse-module e w s *w
1719 (lambda (id *exports forms)
1720 (chi-external *ribcage (source-wrap e w s)
1721 (map (lambda (d) (cons er d)) forms)
1722 r *exports (flatten-exports *exports) m esew
1723 (lambda (*bindings *inits)
1724 (let* ((iface (make-trimmed-interface *exports))
1725 (bindings (append (if id *bindings (update-imp-exports *bindings *exports)) bindings))
1726 (inits (append inits *inits)))
1728 (let ((label (gen-indirect-label))
1729 (imps (get-implicit-exports id)))
1730 (extend-store! r (get-indirect-label label)
1731 (make-binding 'module iface))
1732 (extend-ribcage! ribcage id label)
1736 (cons (make-module-binding type id label imps *exports) bindings)
1739 (do-import! iface ribcage)
1740 (parse (cdr body) (cons iface ids) bindings inits))))))))))
1744 (let ((mlabel (id-var-name mid empty-wrap)))
1745 (let ((binding (lookup mlabel r)))
1746 (case (binding-type binding)
1748 (let ((iface (binding-value binding)))
1749 (when value (extend-ribcage-barrier! ribcage value))
1750 (do-import! iface ribcage)
1754 (update-imp-exports bindings (vector->list (interface-exports iface)))
1756 ((displaced-lexical) (displaced-lexical-error mid))
1757 (else (syntax-error mid "import from unknown module"))))))))
1761 (parse (let f ((forms (syntax (e1 ...))))
1764 (cons (cons er (wrap (car forms) w))
1766 ids bindings inits))))
1767 ((local-syntax-form)
1768 (chi-local-syntax value e er w s
1769 (lambda (forms er w s)
1770 (parse (let f ((forms forms))
1773 (cons (cons er (wrap (car forms) w))
1775 ids bindings inits))))
1776 (else ; found an init expression
1777 (return bindings ids
1778 (append inits (cons (cons er (source-wrap e w s)) (cdr body)))))))))))))
1782 (do ((i (fx- (vector-length v) 1) (fx- i 1))
1783 (ls '() (cons (fn (vector-ref v i)) ls)))
1788 (let ((len (vector-length v)))
1789 (do ((i 0 (fx+ i 1)))
1791 (fn (vector-ref v i))))))
1793 (define do-top-import
1795 (build-cte-install mid
1796 (build-data no-source
1797 (make-binding 'do-import token)))))
1799 (define ct-eval/residualize
1800 (lambda (m esew thunk)
1802 ((c) (if (memq 'compile esew)
1804 (top-level-eval-hook e)
1805 (if (memq 'load esew) e (chi-void)))
1806 (if (memq 'load esew) (thunk) (chi-void))))
1807 ((c&e) (let ((e (thunk))) (top-level-eval-hook e) e))
1808 (else (if (memq 'eval esew) (top-level-eval-hook (thunk))) (chi-void)))))
1813 (lambda () (syntax-type e r w no-source #f))
1814 (lambda (type value e w s)
1815 (chi-expr type value e r w s)))))
1818 (lambda (type value e r w s)
1821 (build-lexical-reference 'value s value))
1822 ((core) (value e r w s))
1825 (build-lexical-reference 'fun (source-annotation (car e)) value)
1827 ((constant) (build-data s (strip (source-wrap e w s) empty-wrap)))
1828 ((global) (build-global-reference s value))
1829 ((call) (chi-application (chi (car e) r w) e r w s))
1832 ((_ e1 e2 ...) (chi-sequence (syntax (e1 e2 ...)) r w s))))
1833 ((local-syntax-form)
1834 (chi-local-syntax value e r w s chi-sequence))
1837 ((_ (x ...) e1 e2 ...)
1838 (let ((when-list (chi-when-list e (syntax (x ...)) w)))
1839 (if (memq 'eval when-list)
1840 (chi-sequence (syntax (e1 e2 ...)) r w s)
1842 ((define-form define-syntax-form module-form import-form)
1843 (syntax-error (source-wrap e w s) "invalid context for definition"))
1845 (syntax-error (source-wrap e w s)
1846 "reference to pattern variable outside syntax form"))
1847 ((displaced-lexical) (displaced-lexical-error (source-wrap e w s)))
1848 (else (syntax-error (source-wrap e w s))))))
1850 (define chi-application
1854 (build-application s x
1855 (map (lambda (e) (chi e r w)) (syntax (e1 ...)))))
1856 (_ (syntax-error (source-wrap e w s))))))
1859 (lambda (e r w s rib)
1863 (let ((n (id-var-name (syntax id) w)))
1864 (let ((b (lookup n r)))
1865 (case (binding-type b)
1867 (let ((id (wrap (syntax id) w)) (val (wrap (syntax val) w)))
1868 (syntax-type (chi-macro (binding-value b)
1869 `(,(syntax set!) ,id ,val)
1870 r empty-wrap s rib) r empty-wrap s rib)))
1874 ; repeat lookup in case we were first expression (init) in
1875 ; module or lambda body. we repeat id-var-name as well,
1876 ; although this is only necessary if we allow inits to
1877 ; preced definitions
1878 (let ((val (chi (syntax val) r w))
1879 (n (id-var-name (syntax id) w)))
1880 (let ((b (lookup n r)))
1881 (case (binding-type b)
1882 ((lexical) (build-lexical-assignment s (binding-value b) val))
1883 ((global) (build-global-assignment s (binding-value b) val))
1884 ((displaced-lexical)
1885 (syntax-error (wrap (syntax id) w) "identifier out of context"))
1886 (else (syntax-error (source-wrap e w s)))))))
1888 (_ (syntax-error (source-wrap e w s))))))
1891 (lambda (p e r w s rib)
1892 (define rebuild-macro-output
1895 (cons (rebuild-macro-output (car x) m)
1896 (rebuild-macro-output (cdr x) m)))
1898 (let ((w (syntax-object-wrap x)))
1899 (let ((ms (wrap-marks w)) (s (wrap-subst w)))
1900 (make-syntax-object (syntax-object-expression x)
1901 (if (and (pair? ms) (eq? (car ms) the-anti-mark))
1903 (if rib (cons rib (cdr s)) (cdr s)))
1904 (make-wrap (cons m ms)
1906 (cons rib (cons 'shift s))
1907 (cons 'shift s))))))))
1909 (let* ((n (vector-length x)) (v (make-vector n)))
1910 (do ((i 0 (fx+ i 1)))
1913 (rebuild-macro-output (vector-ref x i) m)))))
1915 (syntax-error (source-wrap e w s)
1916 "encountered raw symbol "
1918 " in output of macro"))
1920 (rebuild-macro-output
1921 (let ((out (p (source-wrap e (anti-mark w) s))))
1922 (if (procedure? out)
1924 (unless (identifier? id)
1926 "environment argument is not an identifier"))
1927 (lookup (id-var-name id empty-wrap) r)))
1932 ;; Here we create the empty wrap and new environment with placeholder
1933 ;; as required by chi-internal. On return we extend the environment
1934 ;; to recognize the var-labels as lexical variables and build a letrec
1935 ;; binding them to the var-vals which we expand here.
1936 (lambda (body outer-form r w)
1937 (let* ((r (cons '("placeholder" . (placeholder)) r))
1938 (ribcage (make-empty-ribcage))
1939 (w (make-wrap (wrap-marks w) (cons ribcage (wrap-subst w))))
1940 (body (map (lambda (x) (cons r (wrap x w))) body)))
1941 (chi-internal ribcage outer-form body r
1942 (lambda (exprs ids vars vals inits)
1943 (when (null? exprs) (syntax-error outer-form "no expressions in body"))
1944 (build-letrec no-source
1946 (map (lambda (x) (chi (cdr x) (car x) empty-wrap)) vals)
1947 (build-sequence no-source
1948 (map (lambda (x) (chi (cdr x) (car x) empty-wrap)) (append inits exprs)))))))))
1950 (define chi-internal
1951 ;; In processing the forms of the body, we create a new, empty wrap.
1952 ;; This wrap is augmented (destructively) each time we discover that
1953 ;; the next form is a definition. This is done:
1955 ;; (1) to allow the first nondefinition form to be a call to
1956 ;; one of the defined ids even if the id previously denoted a
1957 ;; definition keyword or keyword for a macro expanding into a
1959 ;; (2) to prevent subsequent definition forms (but unfortunately
1960 ;; not earlier ones) and the first nondefinition form from
1961 ;; confusing one of the bound identifiers for an auxiliary
1963 ;; (3) so that we do not need to restart the expansion of the
1964 ;; first nondefinition form, which is problematic anyway
1965 ;; since it might be the first element of a begin that we
1966 ;; have just spliced into the body (meaning if we restarted,
1967 ;; we'd really need to restart with the begin or the macro
1968 ;; call that expanded into the begin, and we'd have to give
1969 ;; up allowing (begin <defn>+ <expr>+), which is itself
1970 ;; problematic since we don't know if a begin contains only
1971 ;; definitions until we've expanded it).
1973 ;; Before processing the body, we also create a new environment
1974 ;; containing a placeholder for the bindings we will add later and
1975 ;; associate this environment with each form. In processing a
1976 ;; let-syntax or letrec-syntax, the associated environment may be
1977 ;; augmented with local keyword bindings, so the environment may
1978 ;; be different for different forms in the body. Once we have
1979 ;; gathered up all of the definitions, we evaluate the transformer
1980 ;; expressions and splice into r at the placeholder the new variable
1981 ;; and keyword bindings. This allows let-syntax or letrec-syntax
1982 ;; forms local to a portion or all of the body to shadow the
1983 ;; definition bindings.
1985 ;; Subforms of a begin, let-syntax, or letrec-syntax are spliced
1988 ;; outer-form is fully wrapped w/source
1989 (lambda (ribcage source-exp body r k)
1991 (lambda (exprs ids vars vals inits)
1992 (check-defined-ids source-exp ids)
1993 (k exprs ids vars vals inits)))
1994 (let parse ((body body) (ids '()) (vars '()) (vals '()) (inits '()))
1996 (return body ids vars vals inits)
1997 (let ((e (cdar body)) (er (caar body)))
1999 (lambda () (syntax-type e er empty-wrap no-source ribcage))
2000 (lambda (type value e w s)
2005 (let ((id (wrap id w)) (label (gen-label)))
2006 (let ((var (gen-var id)))
2007 (extend-ribcage! ribcage id label)
2008 (extend-store! r label (make-binding 'lexical var))
2013 (cons (cons er (wrap rhs w)) vals)
2015 ((define-syntax-form)
2016 (parse-define-syntax e w s
2018 (let ((id (wrap id w))
2020 (exp (chi rhs (transformer-env er) w)))
2021 (extend-ribcage! ribcage id label)
2022 (extend-store! r label (make-binding 'deferred exp))
2023 (parse (cdr body) (cons id ids) vars vals inits)))))
2025 (let* ((*ribcage (make-empty-ribcage))
2026 (*w (make-wrap (wrap-marks w) (cons *ribcage (wrap-subst w)))))
2027 (parse-module e w s *w
2028 (lambda (id exports forms)
2029 (chi-internal *ribcage (source-wrap e w s)
2030 (map (lambda (d) (cons er d)) forms) r
2031 (lambda (*body *ids *vars *vals *inits)
2032 ; valid bound ids checked already by chi-internal
2033 (check-module-exports source-exp (flatten-exports exports) *ids)
2034 (let ((iface (make-trimmed-interface exports))
2035 (vars (append *vars vars))
2036 (vals (append *vals vals))
2037 (inits (append inits *inits *body)))
2039 (let ((label (gen-label)))
2040 (extend-ribcage! ribcage id label)
2041 (extend-store! r label (make-binding 'module iface))
2042 (parse (cdr body) (cons id ids) vars vals inits))
2044 (do-import! iface ribcage)
2045 (parse (cdr body) (cons iface ids) vars vals inits))))))))))
2049 (let ((mlabel (id-var-name mid empty-wrap)))
2050 (let ((binding (lookup mlabel r)))
2053 (let ((iface (cdr binding)))
2054 (when value (extend-ribcage-barrier! ribcage value))
2055 (do-import! iface ribcage)
2056 (parse (cdr body) (cons iface ids) vars vals inits)))
2057 ((displaced-lexical) (displaced-lexical-error mid))
2058 (else (syntax-error mid "import from unknown module"))))))))
2062 (parse (let f ((forms (syntax (e1 ...))))
2065 (cons (cons er (wrap (car forms) w))
2067 ids vars vals inits))))
2068 ((local-syntax-form)
2069 (chi-local-syntax value e er w s
2070 (lambda (forms er w s)
2071 (parse (let f ((forms forms))
2074 (cons (cons er (wrap (car forms) w))
2076 ids vars vals inits))))
2077 (else ; found a non-definition
2078 (return (cons (cons er (source-wrap e w s)) (cdr body))
2079 ids vars vals inits))))))))))
2082 (lambda (interface ribcage)
2083 (let ((token (interface-token interface)))
2085 (extend-ribcage-subst! ribcage token)
2088 (let ((label1 (id-var-name-loc id empty-wrap)))
2090 (syntax-error id "exported identifier not visible"))
2091 (extend-ribcage! ribcage id label1)))
2092 (interface-exports interface))))))
2094 (define parse-module
2095 (lambda (e w s *w k)
2100 (cons (syntax-case (car exports) ()
2101 ((ex ...) (listify (syntax (ex ...))))
2102 (x (if (id? (syntax x))
2103 (wrap (syntax x) *w)
2104 (syntax-error (source-wrap e w s)
2105 "invalid exports list in"))))
2106 (listify (cdr exports))))))
2108 (lambda (id exports forms)
2109 (k id (listify exports) (map (lambda (x) (wrap x *w)) forms))))
2111 ((_ (ex ...) form ...)
2112 (return #f (syntax (ex ...)) (syntax (form ...))))
2113 ((_ mid (ex ...) form ...)
2115 ; id receives old wrap so it won't be confused with id of same name
2116 ; defined within the module
2117 (return (wrap (syntax mid) w) (syntax (ex ...)) (syntax (form ...))))
2118 (_ (syntax-error (source-wrap e w s))))))
2120 (define parse-import
2125 (k (wrap (syntax mid) w)))
2126 (_ (syntax-error (source-wrap e w s))))))
2128 (define parse-define
2133 (k (syntax name) (syntax val) w))
2134 ((_ (name . args) e1 e2 ...)
2135 (and (id? (syntax name))
2136 (valid-bound-ids? (lambda-var-list (syntax args))))
2137 (k (wrap (syntax name) w)
2138 (cons (syntax lambda) (wrap (syntax (args e1 e2 ...)) w))
2142 (k (wrap (syntax name) w) (syntax (void)) empty-wrap))
2143 (_ (syntax-error (source-wrap e w s))))))
2145 (define parse-define-syntax
2150 (k (syntax name) (syntax val) w))
2151 (_ (syntax-error (source-wrap e w s))))))
2153 (define chi-lambda-clause
2156 (((id ...) e1 e2 ...)
2157 (let ((ids (syntax (id ...))))
2158 (if (not (valid-bound-ids? ids))
2159 (syntax-error e "invalid parameter list in")
2160 (let ((labels (gen-labels ids))
2161 (new-vars (map gen-var ids)))
2163 (chi-body (syntax (e1 e2 ...))
2165 (extend-var-env* labels new-vars r)
2166 (make-binding-wrap ids labels w)))))))
2168 (let ((old-ids (lambda-var-list (syntax ids))))
2169 (if (not (valid-bound-ids? old-ids))
2170 (syntax-error e "invalid parameter list in")
2171 (let ((labels (gen-labels old-ids))
2172 (new-vars (map gen-var old-ids)))
2173 (k (let f ((ls1 (cdr new-vars)) (ls2 (car new-vars)))
2176 (f (cdr ls1) (cons (car ls1) ls2))))
2177 (chi-body (syntax (e1 e2 ...))
2179 (extend-var-env* labels new-vars r)
2180 (make-binding-wrap old-ids labels w)))))))
2181 (_ (syntax-error e)))))
2183 (define chi-local-syntax
2184 (lambda (rec? e r w s k)
2186 ((_ ((id val) ...) e1 e2 ...)
2187 (let ((ids (syntax (id ...))))
2188 (if (not (valid-bound-ids? ids))
2189 (invalid-ids-error (map (lambda (x) (wrap x w)) ids)
2192 (let ((labels (gen-labels ids)))
2193 (let ((new-w (make-binding-wrap ids labels w)))
2194 (k (syntax (e1 e2 ...))
2197 (let ((w (if rec? new-w w))
2198 (trans-r (transformer-env r)))
2199 (map (lambda (x) (make-binding 'deferred (chi x trans-r w))) (syntax (val ...))))
2203 (_ (syntax-error (source-wrap e w s))))))
2207 (build-application no-source (build-primref no-source 'void) '())))
2211 (and (nonsymbol-id? x)
2212 (literal-id=? x (syntax (... ...))))))
2216 ;;; strips all annotations from potentially circular reader output
2218 (define strip-annotation
2222 (let ((new (cons #f #f)))
2223 (when parent (set-annotation-stripped! parent new))
2224 (set-car! new (strip-annotation (car x) #f))
2225 (set-cdr! new (strip-annotation (cdr x) #f))
2228 (or (annotation-stripped x)
2229 (strip-annotation (annotation-expression x) x)))
2231 (let ((new (make-vector (vector-length x))))
2232 (when parent (set-annotation-stripped! parent new))
2233 (let loop ((i (- (vector-length x) 1)))
2235 (vector-set! new i (strip-annotation (vector-ref x i) #f))
2240 ;;; strips syntax-objects down to top-wrap; if top-wrap is layered directly
2241 ;;; on an annotation, strips the annotation as well.
2242 ;;; since only the head of a list is annotated by the reader, not each pair
2243 ;;; in the spine, we also check for pairs whose cars are annotated in case
2244 ;;; we've been passed the cdr of an annotated list
2253 (strip* (syntax-object-expression x) (syntax-object-wrap x) fn))
2255 (let ((a (f (car x))) (d (f (cdr x))))
2256 (if (and (eq? a (car x)) (eq? d (cdr x)))
2260 (let ((old (vector->list x)))
2261 (let ((new (map f old)))
2262 (if (andmap eq? old new) x (list->vector new)))))
2269 (if (or (annotation? x) (and (pair? x) (annotation? (car x))))
2270 (strip-annotation x #f)
2273 ;;; lexical variables
2277 (let ((id (if (syntax-object? id) (syntax-object-expression id) id)))
2278 (if (annotation? id)
2279 (build-lexical-var (annotation-source id) (annotation-expression id))
2280 (build-lexical-var no-source id)))))
2282 (define lambda-var-list
2284 (let lvl ((vars vars) (ls '()) (w empty-wrap))
2286 ((pair? vars) (lvl (cdr vars) (cons (wrap (car vars) w) ls) w))
2287 ((id? vars) (cons (wrap vars w) ls))
2289 ((syntax-object? vars)
2290 (lvl (syntax-object-expression vars)
2292 (join-wraps w (syntax-object-wrap vars))))
2294 (lvl (annotation-expression vars) ls w))
2295 ; include anything else to be caught by subsequent error
2297 (else (cons vars ls))))))
2300 ; must precede global-extends
2308 (if (not x) id (cons id x))))
2312 (if (bound-id=? (car x) id) ; could just check same-marks
2314 (cons-id (car x) (weed id (cdr x))))
2315 (if (or (not x) (bound-id=? x id))
2318 (let ((sym (id-sym-name id)))
2319 (let ((x (weed id (getprop sym token))))
2320 (if (and (not x) (symbol? id))
2321 ; don't pollute property list when all we have is a plain
2322 ; top-level binding, since that's what's assumed anyway
2324 (putprop sym token (cons-id id x)))))))
2325 (define sc-put-module
2326 (lambda (exports token)
2328 (lambda (id) (put-token id token))
2330 (define (put-cte id binding)
2331 ;; making assumption here that all macros should be visible to the user and that system
2332 ;; globals don't come through here (primvars.ss sets up their properties)
2333 (let ((sym (if (symbol? id) id (id-var-name id empty-wrap))))
2334 (putprop sym '*sc-expander* binding)))
2335 (let ((binding (or (sanitize-binding b) (error 'define-syntax "invalid transformer ~s" b))))
2336 (case (binding-type binding)
2338 (let ((iface (binding-value binding)))
2339 (sc-put-module (interface-exports iface) (interface-token iface)))
2340 (put-cte id binding))
2341 ((do-import) ; fake binding: id is module id, binding-value is import token
2342 (let ((token (binding-value b)))
2343 (let ((b (lookup (id-var-name id empty-wrap) null-env)))
2344 (case (binding-type b)
2346 (let ((iface (binding-value b)))
2347 (unless (eq? (interface-token iface) token)
2348 (syntax-error id "import mismatch for module"))
2349 (sc-put-module (interface-exports iface) '*top*)))
2350 (else (syntax-error id "import from unknown module"))))))
2351 (else (put-cte id binding))))))
2354 ;;; core transformers
2356 (global-extend 'local-syntax 'letrec-syntax #t)
2357 (global-extend 'local-syntax 'let-syntax #f)
2360 (global-extend 'core 'fluid-let-syntax
2363 ((_ ((var val) ...) e1 e2 ...)
2364 (valid-bound-ids? (syntax (var ...)))
2365 (let ((names (map (lambda (x) (id-var-name x w)) (syntax (var ...)))))
2368 (case (binding-type (lookup n r))
2369 ((displaced-lexical) (displaced-lexical-error (wrap id w)))))
2373 (syntax (e1 e2 ...))
2377 (let ((trans-r (transformer-env r)))
2378 (map (lambda (x) (make-binding 'deferred (chi x trans-r w))) (syntax (val ...))))
2381 (_ (syntax-error (source-wrap e w s))))))
2383 (global-extend 'core 'quote
2386 ((_ e) (build-data s (strip (syntax e) w)))
2387 (_ (syntax-error (source-wrap e w s))))))
2389 (global-extend 'core 'syntax
2392 (lambda (src e r maps ellipsis?)
2394 (let ((label (id-var-name e empty-wrap)))
2395 (let ((b (lookup label r)))
2396 (if (eq? (binding-type b) 'syntax)
2399 (let ((var.lev (binding-value b)))
2400 (gen-ref src (car var.lev) (cdr var.lev) maps)))
2401 (lambda (var maps) (values `(ref ,var) maps)))
2403 (syntax-error src "misplaced ellipsis in syntax form")
2404 (values `(quote ,e) maps)))))
2407 (ellipsis? (syntax dots))
2408 (gen-syntax src (syntax e) r maps (lambda (x) #f)))
2410 ; this could be about a dozen lines of code, except that we
2411 ; choose to handle (syntax (x ... ...)) forms
2412 (ellipsis? (syntax dots))
2413 (let f ((y (syntax y))
2417 (gen-syntax src (syntax x) r
2418 (cons '() maps) ellipsis?))
2420 (if (null? (car maps))
2422 "extra ellipsis in syntax form")
2423 (values (gen-map x (car maps))
2427 (ellipsis? (syntax dots))
2431 (lambda () (k (cons '() maps)))
2433 (if (null? (car maps))
2435 "extra ellipsis in syntax form")
2436 (values (gen-mappend x (car maps))
2438 (_ (call-with-values
2439 (lambda () (gen-syntax src y r maps ellipsis?))
2442 (lambda () (k maps))
2444 (values (gen-append x y) maps)))))))))
2447 (lambda () (gen-syntax src (syntax x) r maps ellipsis?))
2450 (lambda () (gen-syntax src (syntax y) r maps ellipsis?))
2451 (lambda (y maps) (values (gen-cons x y) maps))))))
2455 (gen-syntax src (syntax (e1 e2 ...)) r maps ellipsis?))
2456 (lambda (e maps) (values (gen-vector e) maps))))
2457 (_ (values `(quote ,e) maps))))))
2460 (lambda (src var level maps)
2464 (syntax-error src "missing ellipsis in syntax form")
2466 (lambda () (gen-ref src var (fx- level 1) (cdr maps)))
2467 (lambda (outer-var outer-maps)
2468 (let ((b (assq outer-var (car maps))))
2470 (values (cdr b) maps)
2471 (let ((inner-var (gen-var 'tmp)))
2473 (cons (cons (cons outer-var inner-var)
2475 outer-maps)))))))))))
2479 `(apply (primitive append) ,(gen-map e map-env))))
2483 (let ((formals (map cdr map-env))
2484 (actuals (map (lambda (x) `(ref ,(car x))) map-env)))
2487 ; identity map equivalence:
2488 ; (map (lambda (x) x) y) == y
2491 (lambda (x) (and (eq? (car x) 'ref) (memq (cadr x) formals)))
2493 ; eta map equivalence:
2494 ; (map (lambda (x ...) (f x ...)) y ...) == (map f y ...)
2495 `(map (primitive ,(car e))
2496 ,@(map (let ((r (map cons formals actuals)))
2497 (lambda (x) (cdr (assq (cadr x) r))))
2499 (else `(map (lambda ,formals ,e) ,@actuals))))))
2505 (if (eq? (car x) 'quote)
2506 `(quote (,(cadr x) . ,(cadr y)))
2507 (if (eq? (cadr y) '())
2510 ((list) `(list ,x ,@(cdr y)))
2511 (else `(cons ,x ,y)))))
2515 (if (equal? y '(quote ()))
2522 ((eq? (car x) 'list) `(vector ,@(cdr x)))
2523 ((eq? (car x) 'quote) `(quote #(,@(cadr x))))
2524 (else `(list->vector ,x)))))
2530 ((ref) (build-lexical-reference 'value no-source (cadr x)))
2531 ((primitive) (build-primref no-source (cadr x)))
2532 ((quote) (build-data no-source (cadr x)))
2533 ((lambda) (build-lambda no-source (cadr x) (regen (caddr x))))
2534 ((map) (let ((ls (map regen (cdr x))))
2535 (build-application no-source
2536 (if (fx= (length ls) 2)
2537 (build-primref no-source 'map)
2538 ; really need to do our own checking here
2539 (build-primref no-source 2 'map)) ; require error check
2541 (else (build-application no-source
2542 (build-primref no-source (car x))
2543 (map regen (cdr x)))))))
2546 (let ((e (source-wrap e w s)))
2550 (lambda () (gen-syntax e (syntax x) r '() ellipsis?))
2551 (lambda (e maps) (regen e))))
2552 (_ (syntax-error e)))))))
2555 (global-extend 'core 'lambda
2559 (chi-lambda-clause (source-wrap e w s) (syntax c) r w
2560 (lambda (vars body) (build-lambda s vars body)))))))
2563 (global-extend 'core 'letrec
2566 ((_ ((id val) ...) e1 e2 ...)
2567 (let ((ids (syntax (id ...))))
2568 (if (not (valid-bound-ids? ids))
2569 (invalid-ids-error (map (lambda (x) (wrap x w)) ids)
2570 (source-wrap e w s) "bound variable")
2571 (let ((labels (gen-labels ids))
2572 (new-vars (map gen-var ids)))
2573 (let ((w (make-binding-wrap ids labels w))
2574 (r (extend-var-env* labels new-vars r)))
2577 (map (lambda (x) (chi x r w)) (syntax (val ...)))
2578 (chi-body (syntax (e1 e2 ...)) (source-wrap e w s) r w)))))))
2579 (_ (syntax-error (source-wrap e w s))))))
2581 (global-extend 'core 'if
2585 (build-conditional s
2586 (chi (syntax test) r w)
2587 (chi (syntax then) r w)
2590 (build-conditional s
2591 (chi (syntax test) r w)
2592 (chi (syntax then) r w)
2593 (chi (syntax else) r w)))
2594 (_ (syntax-error (source-wrap e w s))))))
2598 (global-extend 'set! 'set! '())
2600 (global-extend 'begin 'begin '())
2602 (global-extend 'module-key 'module '())
2603 (global-extend 'import 'import #f)
2604 (global-extend 'import 'import-only #t)
2606 (global-extend 'define 'define '())
2608 (global-extend 'define-syntax 'define-syntax '())
2610 (global-extend 'eval-when 'eval-when '())
2612 (global-extend 'core 'syntax-case
2614 (define convert-pattern
2615 ; accepts pattern & keys
2616 ; returns syntax-dispatch pattern & ids
2617 (lambda (pattern keys)
2618 (let cvt ((p pattern) (n 0) (ids '()))
2620 (if (bound-id-member? p keys)
2621 (values (vector 'free-id p) ids)
2622 (values 'any (cons (cons p n) ids)))
2625 (ellipsis? (syntax dots))
2627 (lambda () (cvt (syntax x) (fx+ n 1) ids))
2629 (values (if (eq? p 'any) 'each-any (vector 'each p))
2633 (lambda () (cvt (syntax y) n ids))
2636 (lambda () (cvt (syntax x) n ids))
2638 (values (cons x y) ids))))))
2639 (() (values '() ids))
2642 (lambda () (cvt (syntax (x ...)) n ids))
2643 (lambda (p ids) (values (vector 'vector p) ids))))
2644 (x (values (vector 'atom (strip p empty-wrap)) ids)))))))
2646 (define build-dispatch-call
2647 (lambda (pvars exp y r)
2648 (let ((ids (map car pvars)) (levels (map cdr pvars)))
2649 (let ((labels (gen-labels ids)) (new-vars (map gen-var ids)))
2650 (build-application no-source
2651 (build-primref no-source 'apply)
2652 (list (build-lambda no-source new-vars
2656 (map (lambda (var level)
2657 (make-binding 'syntax `(,var . ,level)))
2661 (make-binding-wrap ids labels empty-wrap)))
2665 (lambda (x keys clauses r pat fender exp)
2667 (lambda () (convert-pattern pat keys))
2670 ((not (distinct-bound-ids? (map car pvars)))
2671 (invalid-ids-error (map car pvars) pat "pattern variable"))
2672 ((not (andmap (lambda (x) (not (ellipsis? (car x)))) pvars))
2674 "misplaced ellipsis in syntax-case pattern"))
2676 (let ((y (gen-var 'tmp)))
2677 ; fat finger binding and references to temp variable y
2678 (build-application no-source
2679 (build-lambda no-source (list y)
2680 (let-syntax ((y (identifier-syntax
2681 (build-lexical-reference 'value no-source y))))
2682 (build-conditional no-source
2683 (syntax-case fender ()
2685 (_ (build-conditional no-source
2687 (build-dispatch-call pvars fender y r)
2688 (build-data no-source #f))))
2689 (build-dispatch-call pvars exp y r)
2690 (gen-syntax-case x keys clauses r))))
2691 (list (if (eq? p 'any)
2692 (build-application no-source
2693 (build-primref no-source 'list)
2694 (list (build-lexical-reference no-source 'value x)))
2695 (build-application no-source
2696 (build-primref no-source '$syntax-dispatch)
2697 (list (build-lexical-reference no-source 'value x)
2698 (build-data no-source p)))))))))))))
2700 (define gen-syntax-case
2701 (lambda (x keys clauses r)
2703 (build-application no-source
2704 (build-primref no-source 'syntax-error)
2705 (list (build-lexical-reference 'value no-source x)))
2706 (syntax-case (car clauses) ()
2708 (if (and (id? (syntax pat))
2709 (not (bound-id-member? (syntax pat) keys))
2710 (not (ellipsis? (syntax pat))))
2711 (let ((label (gen-label))
2712 (var (gen-var (syntax pat))))
2713 (build-application no-source
2714 (build-lambda no-source (list var)
2716 (extend-env label (make-binding 'syntax `(,var . 0)) r)
2717 (make-binding-wrap (syntax (pat))
2718 (list label) empty-wrap)))
2719 (list (build-lexical-reference 'value no-source x))))
2720 (gen-clause x keys (cdr clauses) r
2721 (syntax pat) #t (syntax exp))))
2723 (gen-clause x keys (cdr clauses) r
2724 (syntax pat) (syntax fender) (syntax exp)))
2725 (_ (syntax-error (car clauses) "invalid syntax-case clause"))))))
2728 (let ((e (source-wrap e w s)))
2730 ((_ val (key ...) m ...)
2731 (if (andmap (lambda (x) (and (id? x) (not (ellipsis? x))))
2733 (let ((x (gen-var 'tmp)))
2734 ; fat finger binding and references to temp variable x
2735 (build-application s
2736 (build-lambda no-source (list x)
2738 (syntax (key ...)) (syntax (m ...))
2740 (list (chi (syntax val) r empty-wrap))))
2741 (syntax-error e "invalid literals list in"))))))))
2743 ;;; The portable sc-expand seeds chi-top's mode m with 'e (for
2744 ;;; evaluating) and esew (which stands for "eval syntax expanders
2745 ;;; when") with '(eval). In Chez Scheme, m is set to 'c instead of e
2746 ;;; if we are compiling a file, and esew is set to
2747 ;;; (eval-syntactic-expanders-when), which defaults to the list
2748 ;;; '(compile load eval). This means that, by default, top-level
2749 ;;; syntactic definitions are evaluated immediately after they are
2750 ;;; expanded, and the expanded definitions are also residualized into
2751 ;;; the object file if we are compiling a file.
2753 (let ((m 'e) (esew '(eval))
2755 (let ((ribcage (make-empty-ribcage)))
2756 (extend-ribcage-subst! ribcage '*top*)
2758 (let ((user-top-wrap
2759 (make-wrap (wrap-marks top-wrap)
2760 (cons user-ribcage (wrap-subst top-wrap)))))
2762 (if (and (pair? x) (equal? (car x) noexpand))
2764 (chi-top x null-env user-top-wrap m esew user-ribcage))))))
2770 (set! datum->syntax-object
2772 (arg-check nonsymbol-id? id 'datum->syntax-object)
2773 (make-syntax-object datum (syntax-object-wrap id))))
2775 (set! syntax-object->datum
2776 ; accepts any object, since syntax objects may consist partially
2777 ; or entirely of unwrapped, nonsymbolic data
2779 (strip x empty-wrap)))
2781 (set! generate-temporaries
2783 (arg-check list? ls 'generate-temporaries)
2784 (map (lambda (x) (wrap (gensym-hook) top-wrap)) ls)))
2786 (set! free-identifier=?
2788 (arg-check nonsymbol-id? x 'free-identifier=?)
2789 (arg-check nonsymbol-id? y 'free-identifier=?)
2792 (set! bound-identifier=?
2794 (arg-check nonsymbol-id? x 'bound-identifier=?)
2795 (arg-check nonsymbol-id? y 'bound-identifier=?)
2800 (lambda (object . messages)
2801 (for-each (lambda (x) (arg-check string? x 'syntax-error)) messages)
2802 (let ((message (if (null? messages)
2804 (apply string-append messages))))
2805 (error-hook #f message (strip object empty-wrap)))))
2807 ;;; syntax-dispatch expects an expression and a pattern. If the expression
2808 ;;; matches the pattern a list of the matching expressions for each
2809 ;;; "any" is returned. Otherwise, #f is returned. (This use of #f will
2810 ;;; not work on r4rs implementations that violate the ieee requirement
2811 ;;; that #f and () be distinct.)
2813 ;;; The expression is matched with the pattern as follows:
2815 ;;; pattern: matches:
2818 ;;; (<pattern>1 . <pattern>2) (<pattern>1 . <pattern>2)
2820 ;;; #(free-id <key>) <key> with free-identifier=?
2821 ;;; #(each <pattern>) (<pattern>*)
2822 ;;; #(vector <pattern>) (list->vector <pattern>)
2823 ;;; #(atom <object>) <object> with "equal?"
2825 ;;; Vector cops out to pair under assumption that vectors are rare. If
2826 ;;; not, should convert to:
2827 ;;; #(vector <pattern>*) #(<pattern>*)
2835 (match-each (annotation-expression e) p w))
2837 (let ((first (match (car e) p w '())))
2839 (let ((rest (match-each (cdr e) p w)))
2840 (and rest (cons first rest))))))
2843 (match-each (syntax-object-expression e)
2845 (join-wraps w (syntax-object-wrap e))))
2848 (define match-each-any
2852 (match-each-any (annotation-expression e) w))
2854 (let ((l (match-each-any (cdr e) w)))
2855 (and l (cons (wrap (car e) w) l))))
2858 (match-each-any (syntax-object-expression e)
2859 (join-wraps w (syntax-object-wrap e))))
2866 ((eq? p 'any) (cons '() r))
2867 ((pair? p) (match-empty (car p) (match-empty (cdr p) r)))
2868 ((eq? p 'each-any) (cons '() r))
2870 (case (vector-ref p 0)
2871 ((each) (match-empty (vector-ref p 1) r))
2873 ((vector) (match-empty (vector-ref p 1) r)))))))
2878 ((null? p) (and (null? e) r))
2880 (and (pair? e) (match (car e) (car p) w
2881 (match (cdr e) (cdr p) w r))))
2883 (let ((l (match-each-any e w))) (and l (cons l r))))
2885 (case (vector-ref p 0)
2888 (match-empty (vector-ref p 1) r)
2889 (let ((l (match-each e (vector-ref p 1) w)))
2891 (let collect ((l l))
2894 (cons (map car l) (collect (map cdr l)))))))))
2895 ((free-id) (and (id? e) (literal-id=? (wrap e w) (vector-ref p 1)) r))
2896 ((atom) (and (equal? (vector-ref p 1) (strip e w)) r))
2899 (match (vector->list e) (vector-ref p 1) w r))))))))
2905 ((eq? p 'any) (cons (wrap e w) r))
2908 (unannotate (syntax-object-expression e))
2910 (join-wraps w (syntax-object-wrap e))
2912 (else (match* (unannotate e) p w r)))))
2914 (set! $syntax-dispatch
2917 ((eq? p 'any) (list e))
2919 (match* (unannotate (syntax-object-expression e))
2920 p (syntax-object-wrap e) '()))
2921 (else (match* (unannotate e) p empty-wrap '())))))
2925 (define-syntax with-syntax
2929 (syntax (begin e1 e2 ...)))
2930 ((_ ((out in)) e1 e2 ...)
2931 (syntax (syntax-case in () (out (begin e1 e2 ...)))))
2932 ((_ ((out in) ...) e1 e2 ...)
2933 (syntax (syntax-case (list in ...) ()
2934 ((out ...) (begin e1 e2 ...))))))))
2936 (define-syntax syntax-rules
2939 ((_ (k ...) ((keyword . pattern) template) ...)
2941 (syntax-case x (k ...)
2942 ((dummy . pattern) (syntax template))
2951 (syntax (let ((t e1)) (if t t (or e2 e3 ...))))))))
2956 ((_ e1 e2 e3 ...) (syntax (if e1 (and e2 e3 ...) #f)))
2958 ((_) (syntax #t)))))
2963 ((_ ((x v) ...) e1 e2 ...)
2964 (andmap identifier? (syntax (x ...)))
2965 (syntax ((lambda (x ...) e1 e2 ...) v ...)))
2966 ((_ f ((x v) ...) e1 e2 ...)
2967 (andmap identifier? (syntax (f x ...)))
2968 (syntax ((letrec ((f (lambda (x ...) e1 e2 ...))) f)
2974 ((let* ((x v) ...) e1 e2 ...)
2975 (andmap identifier? (syntax (x ...)))
2976 (let f ((bindings (syntax ((x v) ...))))
2977 (if (null? bindings)
2978 (syntax (let () e1 e2 ...))
2979 (with-syntax ((body (f (cdr bindings)))
2980 (binding (car bindings)))
2981 (syntax (let (binding) body)))))))))
2987 (let f ((clause (syntax m1)) (clauses (syntax (m2 ...))))
2989 (syntax-case clause (else =>)
2990 ((else e1 e2 ...) (syntax (begin e1 e2 ...)))
2991 ((e0) (syntax (let ((t e0)) (if t t))))
2992 ((e0 => e1) (syntax (let ((t e0)) (if t (e1 t)))))
2993 ((e0 e1 e2 ...) (syntax (if e0 (begin e1 e2 ...))))
2994 (_ (syntax-error x)))
2995 (with-syntax ((rest (f (car clauses) (cdr clauses))))
2996 (syntax-case clause (else =>)
2997 ((e0) (syntax (let ((t e0)) (if t t rest))))
2998 ((e0 => e1) (syntax (let ((t e0)) (if t (e1 t) rest))))
2999 ((e0 e1 e2 ...) (syntax (if e0 (begin e1 e2 ...) rest)))
3000 (_ (syntax-error x))))))))))
3004 (syntax-case orig-x ()
3005 ((_ ((var init . step) ...) (e0 e1 ...) c ...)
3006 (with-syntax (((step ...)
3011 (_ (syntax-error orig-x))))
3013 (syntax (step ...)))))
3014 (syntax-case (syntax (e1 ...)) ()
3015 (() (syntax (let doloop ((var init) ...)
3017 (begin c ... (doloop step ...))))))
3019 (syntax (let doloop ((var init) ...)
3022 (begin c ... (doloop step ...))))))))))))
3024 (define-syntax quasiquote
3026 ; these are here because syntax-case uses literal-identifier=?,
3027 ; and we want the more precise free-identifier=?
3028 ((isquote? (lambda (x)
3029 (and (identifier? x)
3030 (free-identifier=? x (syntax quote)))))
3031 (islist? (lambda (x)
3032 (and (identifier? x)
3033 (free-identifier=? x (syntax list)))))
3034 (iscons? (lambda (x)
3035 (and (identifier? x)
3036 (free-identifier=? x (syntax cons)))))
3037 (quote-nil? (lambda (x)
3039 ((quote? ()) (isquote? (syntax quote?)))
3046 (quasicons (car x) (f (cdr x)))))))
3049 (with-syntax ((x x) (y y))
3050 (syntax-case (syntax y) ()
3052 (isquote? (syntax quote?))
3053 (syntax-case (syntax x) ()
3055 (isquote? (syntax quote?))
3056 (syntax (quote (dx . dy))))
3057 (_ (if (null? (syntax dy))
3059 (syntax (cons x y))))))
3061 (islist? (syntax listp))
3062 (syntax (list x . stuff)))
3063 (else (syntax (cons x y)))))))
3066 (let ((ls (let f ((x x))
3071 (if (quote-nil? (car x))
3073 (cons (car x) (f (cdr x))))))))
3075 ((null? ls) (syntax (quote ())))
3076 ((null? (cdr ls)) (car ls))
3077 (else (with-syntax (((p ...) ls))
3078 (syntax (append p ...))))))))
3081 (with-syntax ((pat-x x))
3082 (syntax-case (syntax pat-x) ()
3084 (isquote? (syntax quote?))
3085 (syntax (quote #(x ...))))
3086 (_ (let f ((x x) (k (lambda (ls) `(,(syntax vector) ,@ls))))
3089 (isquote? (syntax quote?))
3090 (k (syntax ((quote x) ...))))
3092 (islist? (syntax listp))
3093 (k (syntax (x ...))))
3095 (iscons? (syntax cons?))
3096 (f (syntax y) (lambda (ls) (k (cons (syntax x) ls)))))
3098 (syntax (list->vector pat-x))))))))))
3101 (syntax-case p (unquote unquote-splicing quasiquote)
3105 (quasicons (syntax (quote unquote))
3106 (quasi (syntax (p)) (- lev 1)))))
3107 (((unquote p ...) . q)
3109 (quasilist* (syntax (p ...)) (quasi (syntax q) lev))
3110 (quasicons (quasicons (syntax (quote unquote))
3111 (quasi (syntax (p ...)) (- lev 1)))
3112 (quasi (syntax q) lev))))
3113 (((unquote-splicing p ...) . q)
3115 (quasiappend (syntax (p ...)) (quasi (syntax q) lev))
3116 (quasicons (quasicons (syntax (quote unquote-splicing))
3117 (quasi (syntax (p ...)) (- lev 1)))
3118 (quasi (syntax q) lev))))
3120 (quasicons (syntax (quote quasiquote))
3121 (quasi (syntax (p)) (+ lev 1))))
3123 (quasicons (quasi (syntax p) lev) (quasi (syntax q) lev)))
3124 (#(x ...) (quasivector (quasi (syntax (x ...)) lev)))
3125 (p (syntax (quote p)))))))
3128 ((_ e) (quasi (syntax e) 0))))))
3130 (define-syntax include
3134 (let ((p (open-input-file fn)))
3138 (begin (close-input-port p) '())
3139 (cons (datum->syntax-object k x) (f))))))))
3142 (let ((fn (syntax-object->datum (syntax filename))))
3143 (with-syntax (((exp ...) (read-file fn (syntax k))))
3144 (syntax (begin exp ...))))))))
3146 (define-syntax unquote
3151 "expression not valid outside of quasiquote")))))
3153 (define-syntax unquote-splicing
3158 "expression not valid outside of quasiquote")))))
3165 ((body (let f ((clause (syntax m1)) (clauses (syntax (m2 ...))))
3167 (syntax-case clause (else)
3168 ((else e1 e2 ...) (syntax (begin e1 e2 ...)))
3169 (((k ...) e1 e2 ...)
3170 (syntax (if (memv t '(k ...)) (begin e1 e2 ...))))
3171 (_ (syntax-error x)))
3172 (with-syntax ((rest (f (car clauses) (cdr clauses))))
3173 (syntax-case clause (else)
3174 (((k ...) e1 e2 ...)
3175 (syntax (if (memv t '(k ...))
3178 (_ (syntax-error x))))))))
3179 (syntax (let ((t e)) body)))))))
3181 (define-syntax identifier-syntax
3183 (syntax-case x (set!)
3189 (identifier? (syntax id))
3192 (syntax (e x (... ...))))))))
3193 ((_ (id exp1) ((set! var val) exp2))
3194 (and (identifier? (syntax id)) (identifier? (syntax var)))
3198 (syntax-case x (set!)
3199 ((set! var val) (syntax exp2))
3200 ((id x (... ...)) (syntax (exp1 x (... ...))))
3201 (id (identifier? (syntax id)) (syntax exp1))))))))))