actually pass original ids on to tree-il data types
[bpt/guile.git] / module / ice-9 / psyntax.scm
index 0969342..fd7ad59 100644 (file)
@@ -22,6 +22,9 @@
 ;;; Extracted from Chez Scheme Version 5.9f
 ;;; Authors: R. Kent Dybvig, Oscar Waddell, Bob Hieb, Carl Bruggeman
 
+;;; Modified by Andy Wingo <wingo@pobox.com> according to the Git
+;;; revision control logs corresponding to this file: 2009.
+
 ;;; Modified by Mikael Djurfeldt <djurfeldt@nada.kth.se> according
 ;;; to the ChangeLog distributed in the same directory as this file:
 ;;; 1997-08-19, 1997-09-03, 1997-09-10, 2000-08-13, 2000-08-24,
@@ -49,7 +52,7 @@
 ;;; also documented in the R4RS and draft R5RS.
 ;;;
 ;;;   bound-identifier=?
-;;;   datum->syntax-object
+;;;   datum->syntax
 ;;;   define-syntax
 ;;;   fluid-let-syntax
 ;;;   free-identifier=?
@@ -60,7 +63,7 @@
 ;;;   letrec-syntax
 ;;;   syntax
 ;;;   syntax-case
-;;;   syntax-object->datum
+;;;   syntax->datum
 ;;;   syntax-rules
 ;;;   with-syntax
 ;;;
 ;;;      conditionally evaluates expr ... at compile-time or run-time
 ;;;      depending upon situations (see the Chez Scheme System Manual,
 ;;;      Revision 3, for a complete description)
-;;;   (syntax-error object message)
+;;;   (syntax-violation who message form [subform])
 ;;;      used to report errors found during expansion
-;;;   (install-global-transformer symbol value)
-;;;      used by expanded code to install top-level syntactic abstractions
-;;;   (syntax-dispatch e p)
+;;;   ($sc-dispatch e p)
 ;;;      used by expanded code to handle syntax-case matching
 
 ;;; The following nonstandard procedures must be provided by the
-;;; implementation for this code to run.
-;;;
-;;; (void)
-;;; returns the implementation's cannonical "unspecified value".  This
-;;; usually works: (define void (lambda () (if #f #f))).
-;;;
-;;; (andmap proc list1 list2 ...)
-;;; returns true if proc returns true when applied to each element of list1
-;;; along with the corresponding elements of list2 ....
-;;; The following definition works but does no error checking:
-;;;
-;;; (define andmap
-;;;   (lambda (f first . rest)
-;;;     (or (null? first)
-;;;         (if (null? rest)
-;;;             (let andmap ((first first))
-;;;               (let ((x (car first)) (first (cdr first)))
-;;;                 (if (null? first)
-;;;                     (f x)
-;;;                     (and (f x) (andmap first)))))
-;;;             (let andmap ((first first) (rest rest))
-;;;               (let ((x (car first))
-;;;                     (xr (map car rest))
-;;;                     (first (cdr first))
-;;;                     (rest (map cdr rest)))
-;;;                 (if (null? first)
-;;;                     (apply f (cons x xr))
-;;;                     (and (apply f (cons x xr)) (andmap first rest)))))))))
-;;;
-;;; The following nonstandard procedures must also be provided by the
 ;;; implementation for this code to run using the standard portable
-;;; hooks and output constructors.  They are not used by expanded code,
+;;; hooks and output constructors. They are not used by expanded code,
 ;;; and so need be present only at expansion time.
 ;;;
 ;;; (eval x)
 ;;; by eval, and eval accepts one argument, nothing special must be done
 ;;; to support the "noexpand" flag, since it is handled by sc-expand.
 ;;;
-;;; (error who format-string why what)
-;;; where who is either a symbol or #f, format-string is always "~a ~s",
-;;; why is always a string, and what may be any object.  error should
-;;; signal an error with a message something like
-;;;
-;;;    "error in <who>: <why> <what>"
-;;;
 ;;; (gensym)
 ;;; returns a unique symbol each time it's called
-;;;
-;;; (putprop symbol key value)
-;;; (getprop symbol key)
-;;; key is always the symbol *sc-expander*; value may be any object.
-;;; putprop should associate the given value with the given symbol in
-;;; some way that it can be retrieved later with getprop.
 
 ;;; When porting to a new Scheme implementation, you should define the
 ;;; procedures listed above, load the expanded version of psyntax.ss
 
 ;;; Objects with no standard print syntax, including objects containing
 ;;; cycles and syntax object, are allowed in quoted data as long as they
-;;; are contained within a syntax form or produced by datum->syntax-object.
+;;; are contained within a syntax form or produced by datum->syntax.
 ;;; Such objects are never copied.
 
 ;;; All identifiers that don't have macro definitions and are not bound
 
 
 
+(eval-when (compile)
+  (set-current-module (resolve-module '(guile))))
+
 (let ()
+;;; Private version of and-map that handles multiple lists.
+(define and-map*
+  (lambda (f first . rest)
+    (or (null? first)
+        (if (null? rest)
+            (let andmap ((first first))
+              (let ((x (car first)) (first (cdr first)))
+                (if (null? first)
+                    (f x)
+                    (and (f x) (andmap first)))))
+            (let andmap ((first first) (rest rest))
+              (let ((x (car first))
+                    (xr (map car rest))
+                    (first (cdr first))
+                    (rest (map cdr rest)))
+                (if (null? first)
+                    (apply f (cons x xr))
+                    (and (apply f (cons x xr)) (andmap first rest)))))))))
+
 (define-syntax define-structure
   (lambda (x)
     (define construct-name
       (lambda (template-identifier . args)
-        (datum->syntax-object
+        (datum->syntax
           template-identifier
           (string->symbol
             (apply string-append
                    (map (lambda (x)
                           (if (string? x)
                               x
-                              (symbol->string (syntax-object->datum x))))
+                              (symbol->string (syntax->datum x))))
                         args))))))
     (syntax-case x ()
       ((_ (name id1 ...))
-       (andmap identifier? (syntax (name id1 ...)))
+       (and-map identifier? (syntax (name id1 ...)))
        (with-syntax
          ((constructor (construct-name (syntax name) "make-" (syntax name)))
           (predicate (construct-name (syntax name) (syntax name) "?"))
 
 (let ()
 (define noexpand "noexpand")
+(define *mode* (make-fluid))
 
 ;;; hooks to nonportable run-time helpers
 (begin
 
 (define top-level-eval-hook
   (lambda (x mod)
-    (eval `(,noexpand ,x) (or mod (interaction-environment)))))
+    (primitive-eval
+     `(,noexpand
+       ,(case (fluid-ref *mode*)
+          ((c) ((@ (language tree-il) tree-il->scheme) x))
+          (else x))))))
 
 (define local-eval-hook
   (lambda (x mod)
-    (eval `(,noexpand ,x) (or mod (interaction-environment)))))
-
-(define error-hook
-  (lambda (who why what)
-    (error who "~a ~s" why what)))
+    (primitive-eval
+     `(,noexpand
+       ,(case (fluid-ref *mode*)
+          ((c) ((@ (language tree-il) tree-il->scheme) x))
+          (else x))))))
 
 (define-syntax gensym-hook
   (syntax-rules ()
     ((_) (gensym))))
 
-;; wingo: FIXME: use modules natively?
 (define put-global-definition-hook
-  (lambda (symbol binding)
-     (putprop symbol '*sc-expander* binding)))
+  (lambda (symbol type val)
+    (let ((existing (let ((v (module-variable (current-module) symbol)))
+                      (and v (variable-bound? v)
+                           (let ((val (variable-ref v)))
+                             (and (macro? val)
+                                  (not (syncase-macro-type val))
+                                  val))))))
+      (module-define! (current-module)
+                      symbol
+                      (if existing
+                          (make-extended-syncase-macro existing type val)
+                          (make-syncase-macro type val))))))
 
 (define get-global-definition-hook
-  (lambda (symbol)
-     (getprop symbol '*sc-expander*)))
+  (lambda (symbol module)
+    (if (and (not module) (current-module))
+        (warn "module system is booted, we should have a module" symbol))
+    (let ((v (module-variable (if module
+                                  (resolve-module (cdr module))
+                                  (current-module))
+                              symbol)))
+      (and v (variable-bound? v)
+           (let ((val (variable-ref v)))
+             (and (macro? val) (syncase-macro-type val)
+                  (cons (syncase-macro-type val)
+                        (syncase-macro-binding val))))))))
+
 )
 
 
 ;;; output constructors
-(define (build-annotated src exp)
-  (if (and src (not (annotation? exp)))
-      (make-annotation exp src #t)
-      exp))
-
-(define-syntax build-application
-  (syntax-rules ()
-    ((_ source fun-exp arg-exps)
-     (build-annotated source `(,fun-exp . ,arg-exps)))))
-
-(define-syntax build-conditional
-  (syntax-rules ()
-    ((_ source test-exp then-exp else-exp)
-     (build-annotated source `(if ,test-exp ,then-exp ,else-exp)))))
-
-(define-syntax build-lexical-reference
-  (syntax-rules ()
-    ((_ type source var)
-     (build-annotated source var))))
-
-(define-syntax build-lexical-assignment
-  (syntax-rules ()
-    ((_ source var exp)
-     (build-annotated source `(set! ,var ,exp)))))
-
-(define-syntax build-global-reference
-  (syntax-rules ()
-    ((_ source var mod)
-     (build-annotated source (make-module-ref #f var mod)))))
-
-(define-syntax build-global-assignment
-  (syntax-rules ()
-    ((_ source var exp mod)
-     (build-annotated source `(set! ,(make-module-ref #f var mod) ,exp)))))
-
-(define-syntax build-global-definition
-  (syntax-rules ()
-    ((_ source var exp mod)
-     (build-annotated source `(define ,var ,exp)))))
-
-(define-syntax build-lambda
-  (syntax-rules ()
-    ((_ src vars exp)
-     (build-annotated src `(lambda ,vars ,exp)))))
-
-;; FIXME: wingo: add modules here somehow?
-(define-syntax build-primref
-  (syntax-rules ()
-    ((_ src name) (build-annotated src name))
-    ((_ src level name) (build-annotated src name))))
+(define build-application
+  (lambda (source fun-exp arg-exps)
+    (case (fluid-ref *mode*)
+      ((c) ((@ (language tree-il) make-application) source fun-exp arg-exps))
+      (else `(,fun-exp . ,arg-exps)))))
+
+(define build-conditional
+  (lambda (source test-exp then-exp else-exp)
+    (case (fluid-ref *mode*)
+      ((c) ((@ (language tree-il) make-conditional)
+            source test-exp then-exp else-exp))
+      (else `(if ,test-exp ,then-exp ,else-exp)))))
+
+(define build-lexical-reference
+  (lambda (type source name var)
+    (case (fluid-ref *mode*)
+      ((c) ((@ (language tree-il) make-lexical-ref) source name var))
+      (else var))))
+
+(define build-lexical-assignment
+  (lambda (source name var exp)
+    (case (fluid-ref *mode*)
+      ((c) ((@ (language tree-il) make-lexical-set) source name var exp))
+      (else `(set! ,var ,exp)))))
+
+;; Before modules are booted, we can't expand into data structures from
+;; (language tree-il) -- we need to give the evaluator the
+;; s-expressions that it understands natively. Actually the real truth
+;; of the matter is that the evaluator doesn't understand tree-il
+;; structures at all. So until we fix the evaluator, if ever, the
+;; conflation that we should use tree-il iff we are compiling
+;; holds true.
+;;
+(define (analyze-variable mod var modref-cont bare-cont)
+  (if (not mod)
+      (bare-cont var)
+      (let ((kind (car mod))
+            (mod (cdr mod)))
+        (case kind
+          ((public) (modref-cont mod var #t))
+          ((private) (if (not (equal? mod (module-name (current-module))))
+                         (modref-cont mod var #f)
+                         (bare-cont var)))
+          ((bare) (bare-cont var))
+          ((hygiene) (if (and (not (equal? mod (module-name (current-module))))
+                              (module-variable (resolve-module mod) var))
+                         (modref-cont mod var #f)
+                         (bare-cont var)))
+          (else (syntax-violation #f "bad module kind" var mod))))))
+
+(define build-global-reference
+  (lambda (source var mod)
+    (analyze-variable
+     mod var
+     (lambda (mod var public?) 
+       (case (fluid-ref *mode*)
+         ((c) ((@ (language tree-il) make-module-ref) source mod var public?))
+         (else (list (if public? '@ '@@) mod var))))
+     (lambda (var)
+       (case (fluid-ref *mode*)
+         ((c) ((@ (language tree-il) make-toplevel-ref) source var))
+         (else var))))))
+
+(define build-global-assignment
+  (lambda (source var exp mod)
+    (analyze-variable
+     mod var
+     (lambda (mod var public?) 
+       (case (fluid-ref *mode*)
+         ((c) ((@ (language tree-il) make-module-set) source mod var public? exp))
+         (else `(set! ,(list (if public? '@ '@@) mod var) ,exp))))
+     (lambda (var)
+       (case (fluid-ref *mode*)
+         ((c) ((@ (language tree-il) make-toplevel-set) source var exp))
+         (else `(set! ,var ,exp)))))))
+
+(define build-global-definition
+  (lambda (source var exp)
+    (case (fluid-ref *mode*)
+      ((c) ((@ (language tree-il) make-toplevel-define) source var exp))
+      (else `(define ,var ,exp)))))
+
+(define build-lambda
+  (lambda (src ids vars docstring exp)
+    (case (fluid-ref *mode*)
+      ((c) ((@ (language tree-il) make-lambda) src ids vars
+            (if docstring `((documentation . ,docstring)) '())
+            exp))
+      (else `(lambda ,vars ,@(if docstring (list docstring) '())
+                     ,exp)))))
+
+(define build-primref
+  (lambda (src name)
+    (case (fluid-ref *mode*)
+      ((c) ((@ (language tree-il) make-primitive-ref) src name))
+      ;; hygiene guile is a hack
+      (else (build-global-reference src name '(hygiene guile))))))
 
 (define (build-data src exp)
-  (if (and (self-evaluating? exp)
-          (not (vector? exp)))
-      (build-annotated src exp)
-      (build-annotated src (list 'quote exp))))
+  (case (fluid-ref *mode*)
+    ((c) ((@ (language tree-il) make-const) src exp))
+    (else (if (and (self-evaluating? exp) (not (vector? exp)))
+              exp
+              (list 'quote exp)))))
 
 (define build-sequence
   (lambda (src exps)
     (if (null? (cdr exps))
-        (build-annotated src (car exps))
-        (build-annotated src `(begin ,@exps)))))
+        (car exps)
+        (case (fluid-ref *mode*)
+          ((c) ((@ (language tree-il) make-sequence) src exps))
+          (else `(begin ,@exps))))))
 
 (define build-let
-  (lambda (src vars val-exps body-exp)
+  (lambda (src ids vars val-exps body-exp)
     (if (null? vars)
-       (build-annotated src body-exp)
-       (build-annotated src `(let ,(map list vars val-exps) ,body-exp)))))
+       body-exp
+        (case (fluid-ref *mode*)
+          ((c) ((@ (language tree-il) make-let) src ids vars val-exps body-exp))
+          (else `(let ,(map list vars val-exps) ,body-exp))))))
 
 (define build-named-let
-  (lambda (src vars val-exps body-exp)
-    (if (null? vars)
-       (build-annotated src body-exp)
-       (build-annotated src
-                         `(let ,(car vars)
-                            ,(map list (cdr vars) val-exps) ,body-exp)))))
+  (lambda (src ids vars val-exps body-exp)
+    (let ((f (car vars))
+          (f-name (car ids))
+          (vars (cdr vars))
+          (ids (cdr ids)))
+      (case (fluid-ref *mode*)
+        ((c) ((@ (language tree-il) make-letrec) src
+              (list f-name)
+              (list f)
+              (list (build-lambda src ids vars #f body-exp))
+              (build-application src (build-lexical-reference 'fun src f-name f)
+                                 val-exps)))
+        (else `(let ,f ,(map list vars val-exps) ,body-exp))))))
 
 (define build-letrec
-  (lambda (src vars val-exps body-exp)
+  (lambda (src ids vars val-exps body-exp)
     (if (null? vars)
-        (build-annotated src body-exp)
-        (build-annotated src
-                         `(letrec ,(map list vars val-exps) ,body-exp)))))
+        body-exp
+        (case (fluid-ref *mode*)
+          ((c) ((@ (language tree-il) make-letrec) src ids vars val-exps body-exp))
+          (else `(letrec ,(map list vars val-exps) ,body-exp))))))
 
-;; FIXME: wingo: use make-lexical
+;; FIXME: wingo: use make-lexical ?
 (define-syntax build-lexical-var
   (syntax-rules ()
-    ((_ src id) (build-annotated src (gensym (symbol->string id))))))
+    ((_ src id) (gensym (symbol->string id)))))
 
 (define-structure (syntax-object expression wrap module))
 
   (syntax-rules ()
     ((_ pred? e who)
      (let ((x e))
-       (if (not (pred? x)) (error-hook who "invalid argument" x))))))
+       (if (not (pred? x)) (syntax-violation who "invalid argument" x))))))
 
 ;;; compile-time environments
 
 ;;; <binding> ::= (macro . <procedure>)           macros
 ;;;               (core . <procedure>)            core forms
 ;;;               (external-macro . <procedure>)  external-macro
+;;;               (module-ref . <procedure>)      @ or @@
 ;;;               (begin)                         begin
 ;;;               (define)                        define
 ;;;               (define-syntax)                 define-syntax
   ; although symbols are usually global, we check the environment first
   ; anyway because a temporary binding may have been established by
   ; fluid-let-syntax
-  (lambda (x r)
+  (lambda (x r mod)
     (cond
       ((assq x r) => cdr)
       ((symbol? x)
-       (or (get-global-definition-hook x) (make-binding 'global)))
+       (or (get-global-definition-hook x mod) (make-binding 'global)))
       (else (make-binding 'displaced-lexical)))))
 
 (define global-extend
   (lambda (type sym val)
-    (put-global-definition-hook sym (make-binding type val))))
+    (put-global-definition-hook sym type val)))
 
 
 ;;; Conceptually, identifiers are always syntax objects.  Internally,
       ((annotation? id)
        (let ((id (unannotate id)))
          (or (first (search id (wrap-subst w) (wrap-marks w))) id)))
-      (else (error-hook 'id-var-name "invalid id" id)))))
+      (else (syntax-violation 'id-var-name "invalid id" id)))))
 
 ;;; free-id=? must be passed fully wrapped ids since (free-id=? x y)
 ;;; may be true even if (free-id=? (wrap x w) (wrap y w)) is not.
             (let ((first (chi-top (car body) r w m esew mod)))
               (cons first (dobody (cdr body) r w m esew mod))))))))
 
-;; FIXME: module?
 (define chi-install-global
   (lambda (name e)
-    (build-application no-source
-      (build-primref no-source 'install-global-transformer)
-      (list (build-data no-source name) e))))
+    (build-global-definition
+     no-source
+     name
+     ;; FIXME: seems nasty to call current-module here
+     (if (let ((v (module-variable (current-module) name)))
+           ;; FIXME use primitive-macro?
+           (and v (variable-bound? v) (macro? (variable-ref v))
+                (not (eq? (macro-type (variable-ref v)) 'syncase-macro))))
+         (build-application
+          no-source
+          (build-primref no-source 'make-extended-syncase-macro)
+          (list (build-application
+                 no-source
+                 (build-primref no-source 'module-ref)
+                 (list (build-application no-source 'current-module '())
+                       (build-data no-source name)))
+                (build-data no-source 'macro)
+                e))
+         (build-application
+          no-source
+          (build-primref no-source 'make-syncase-macro)
+          (list (build-data no-source 'macro) e))))))
 
 (define chi-when-list
   (lambda (e when-list w)
                        ((free-id=? x (syntax compile)) 'compile)
                        ((free-id=? x (syntax load)) 'load)
                        ((free-id=? x (syntax eval)) 'eval)
-                       (else (syntax-error (wrap x w #f)
-                               "invalid eval-when situation"))))
+                       (else (syntax-violation 'eval-when
+                                               "invalid situation"
+                                               e (wrap x w #f)))))
                    situations))))))
 
 ;;; syntax-type returns six values: type, value, e, w, s, and mod. The
 ;;;    -------------------------------------------------------------------
 ;;;    core                   procedure     core form (including singleton)
 ;;;    external-macro         procedure     external macro
+;;;    module-ref             procedure     @ or @@ form
 ;;;    lexical                name          lexical variable reference
 ;;;    global                 name          global variable reference
 ;;;    begin                  none          begin keyword
     (cond
       ((symbol? e)
        (let* ((n (id-var-name e w))
-              (b (lookup n r))
+              (b (lookup n r mod))
               (type (binding-type b)))
          (case type
-           ((lexical) (values type (binding-value b) e w s #f))
+           ((lexical) (values type (binding-value b) e w s mod))
            ((global) (values type n e w s mod))
            ((macro)
             (syntax-type (chi-macro (binding-value b) e r w rib mod)
        (let ((first (car e)))
          (if (id? first)
              (let* ((n (id-var-name first w))
-                    (b (lookup n r))
+                    (b (lookup n r (or (and (syntax-object? first)
+                                            (syntax-object-module first))
+                                       mod)))
                     (type (binding-type b)))
                (case type
                  ((lexical)
                  ((macro)
                   (syntax-type (chi-macro (binding-value b) e r w rib mod)
                     r empty-wrap s rib mod))
-                 ((core external-macro)
+                 ((core external-macro module-ref)
                   (values type (binding-value b) e w s mod))
                  ((local-syntax)
                   (values 'local-syntax-form (binding-value b) e w s mod))
                      (and (id? (syntax name))
                           (valid-bound-ids? (lambda-var-list (syntax args))))
                      ; need lambda here...
-                     (values 'define-form (wrap (syntax name) w #f)
+                     (values 'define-form (wrap (syntax name) w mod)
                        (cons (syntax lambda) (wrap (syntax (args e1 e2 ...)) w mod))
                        empty-wrap s mod))
                     ((_ name)
                      (id? (syntax name))
-                     (values 'define-form (wrap (syntax name) w #f)
-                       (syntax (void))
+                     (values 'define-form (wrap (syntax name) w mod)
+                       (syntax (if #f #f))
                        empty-wrap s mod))))
                  ((define-syntax)
                   (syntax-case e ()
        (syntax-type (syntax-object-expression e)
                     r
                     (join-wraps w (syntax-object-wrap e))
-                    no-source rib (syntax-object-module e)))
+                    no-source rib (or (syntax-object-module e) mod)))
       ((annotation? e)
        (syntax-type (annotation-expression e) r w (annotation-source e) rib mod))
       ((self-evaluating? e) (values 'constant #f e w s mod))
                 (chi-void)))))
           ((define-form)
            (let* ((n (id-var-name value w))
-                 (type (binding-type (lookup n r))))
+                 (type (binding-type (lookup n r mod))))
              (case type
-               ((global)
+               ((global core macro module-ref)
                 (eval-if-c&e m
-                  (build-global-definition s n (chi e r w mod) mod)
+                  (build-global-definition s n (chi e r w mod))
                   mod))
                ((displaced-lexical)
-                (syntax-error (wrap value w #f) "identifier out of context"))
+                (syntax-violation #f "identifier out of context"
+                                  e (wrap value w mod)))
                (else
-               (if (eq? type 'external-macro)
-                   (eval-if-c&e m
-                      (build-global-definition s n (chi e r w mod) mod)
-                      mod)
-                   (syntax-error (wrap value w #f)
-                                 "cannot define keyword at top level"))))))
+                (syntax-violation #f "cannot define keyword at top level"
+                                  e (wrap value w mod))))))
           (else (eval-if-c&e m (chi-expr type value e r w s mod) mod)))))))
 
 (define chi
   (lambda (type value e r w s mod)
     (case type
       ((lexical)
-       (build-lexical-reference 'value s value))
+       (build-lexical-reference 'value s value))
       ((core external-macro)
        ;; apply transformer
        (value e r w s mod))
+      ((module-ref)
+       (call-with-values (lambda () (value e))
+         ;; we could add a public? arg here
+         (lambda (id mod) (build-global-reference s id mod))))
       ((lexical-call)
        (chi-application
-         (build-lexical-reference 'fun (source-annotation (car e)) value)
+         (build-lexical-reference 'fun (source-annotation (car e))
+                                  (car e) value)
          e r w s mod))
       ((global-call)
        (chi-application
-         (build-global-reference (source-annotation (car e)) value mod)
+         (build-global-reference (source-annotation (car e)) value
+                                 (if (syntax-object? (car e))
+                                     (syntax-object-module (car e))
+                                     mod))
          e r w s mod))
       ((constant) (build-data s (strip (source-wrap e w s mod) empty-wrap)))
       ((global) (build-global-reference s value mod))
                 (chi-sequence (syntax (e1 e2 ...)) r w s mod)
                 (chi-void))))))
       ((define-form define-syntax-form)
-       (syntax-error (wrap value w #f) "invalid context for definition of"))
+       (syntax-violation #f "definition in expression context"
+                         e (wrap value w mod)))
       ((syntax)
-       (syntax-error (source-wrap e w s mod)
-         "reference to pattern variable outside syntax form"))
+       (syntax-violation #f "reference to pattern variable outside syntax form"
+                         (source-wrap e w s mod)))
       ((displaced-lexical)
-       (syntax-error (source-wrap e w s mod)
-         "reference to identifier outside its scope"))
-      (else (syntax-error (source-wrap e w s mod))))))
+       (syntax-violation #f "reference to identifier outside its scope"
+                          (source-wrap e w s mod)))
+      (else (syntax-violation #f "unexpected syntax"
+                              (source-wrap e w s mod))))))
 
 (define chi-application
   (lambda (x e r w s mod)
                                    (if rib
                                        (cons rib (cons 'shift s))
                                        (cons 'shift s)))
-                        (procedure-module p)))))) ;; hither the hygiene
+                        (let ((pmod (procedure-module p)))
+                          (if pmod
+                              ;; hither the hygiene
+                              (cons 'hygiene (module-name pmod))
+                              ;; but it's possible for the proc to have
+                              ;; no mod, if it was made before modules
+                              ;; were booted
+                              '(hygiene guile))))))))
               ((vector? x)
                (let* ((n (vector-length x)) (v (make-vector n)))
                  (do ((i 0 (fx+ i 1)))
                      (vector-set! v i
                        (rebuild-macro-output (vector-ref x i) m)))))
               ((symbol? x)
-               (syntax-error x "encountered raw symbol in macro output"))
+               (syntax-violation #f "encountered raw symbol in macro output"
+                                 (source-wrap e w s mod) x))
               (else x))))
     (rebuild-macro-output (p (wrap e (anti-mark w) mod)) (new-mark))))
 
       (let parse ((body (map (lambda (x) (cons r (wrap x w mod))) body))
                   (ids '()) (labels '()) (vars '()) (vals '()) (bindings '()))
         (if (null? body)
-            (syntax-error outer-form "no expressions in body")
+            (syntax-violation #f "no expressions in body" outer-form)
             (let ((e (cdar body)) (er (caar body)))
               (call-with-values
                 (lambda () (syntax-type e er empty-wrap no-source ribcage mod))
                                       (cdr body))))
                          (begin
                            (if (not (valid-bound-ids? ids))
-                               (syntax-error outer-form
-                                 "invalid or duplicate identifier in definition"))
+                               (syntax-violation
+                                #f "invalid or duplicate identifier in definition"
+                                outer-form))
                            (let loop ((bs bindings) (er-cache #f) (r-cache #f))
                              (if (not (null? bs))
                                  (let* ((b (car bs)))
                                        (loop (cdr bs) er-cache r-cache)))))
                            (set-cdr! r (extend-env labels bindings (cdr r)))
                            (build-letrec no-source
+                             (map syntax->datum ids)
                              vars
                              (map (lambda (x)
                                     (chi (cdr x) (car x) empty-wrap mod))
                                           (cdr body)))))))))))))))))
 
 (define chi-lambda-clause
-  (lambda (e c r w mod k)
+  (lambda (e docstring c r w mod k)
     (syntax-case c ()
+      ((args doc e1 e2 ...)
+       (and (string? (syntax->datum (syntax doc))) (not docstring))
+       (chi-lambda-clause e (syntax doc) (syntax (args e1 e2 ...)) r w mod k))
       (((id ...) e1 e2 ...)
        (let ((ids (syntax (id ...))))
          (if (not (valid-bound-ids? ids))
-             (syntax-error e "invalid parameter list in")
+             (syntax-violation 'lambda "invalid parameter list" e)
              (let ((labels (gen-labels ids))
                    (new-vars (map gen-var ids)))
-               (k new-vars
+               (k (map syntax->datum ids)
+                  new-vars
+                  docstring
                   (chi-body (syntax (e1 e2 ...))
                             e
                             (extend-var-env labels new-vars r)
       ((ids e1 e2 ...)
        (let ((old-ids (lambda-var-list (syntax ids))))
          (if (not (valid-bound-ids? old-ids))
-             (syntax-error e "invalid parameter list in")
+             (syntax-violation 'lambda "invalid parameter list" e)
              (let ((labels (gen-labels old-ids))
                    (new-vars (map gen-var old-ids)))
-               (k (let f ((ls1 (cdr new-vars)) (ls2 (car new-vars)))
+               (k (let f ((ls1 (cdr old-ids)) (ls2 (car old-ids)))
+                    (if (null? ls1)
+                        (syntax->datum ls2)
+                        (f (cdr ls1) (cons (syntax->datum (car ls1)) ls2))))
+                  (let f ((ls1 (cdr new-vars)) (ls2 (car new-vars)))
                     (if (null? ls1)
                         ls2
                         (f (cdr ls1) (cons (car ls1) ls2))))
+                  docstring
                   (chi-body (syntax (e1 e2 ...))
                             e
                             (extend-var-env labels new-vars r)
                             (make-binding-wrap old-ids labels w)
                             mod))))))
-      (_ (syntax-error e)))))
+      (_ (syntax-violation 'lambda "bad lambda" e)))))
 
 (define chi-local-syntax
   (lambda (rec? e r w s mod k)
       ((_ ((id val) ...) e1 e2 ...)
        (let ((ids (syntax (id ...))))
          (if (not (valid-bound-ids? ids))
-             (syntax-error e "duplicate bound keyword in")
+             (syntax-violation #f "duplicate bound keyword" e)
              (let ((labels (gen-labels ids)))
                (let ((new-w (make-binding-wrap ids labels w)))
                  (k (syntax (e1 e2 ...))
                     new-w
                     s
                     mod))))))
-      (_ (syntax-error (source-wrap e w s mod))))))
+      (_ (syntax-violation #f "bad local syntax definition"
+                           (source-wrap e w s mod))))))
 
 (define eval-local-transformer
   (lambda (expanded mod)
     (let ((p (local-eval-hook expanded mod)))
       (if (procedure? p)
           p
-          (syntax-error p "nonprocedure transformer")))))
+          (syntax-violation #f "nonprocedure transformer" p)))))
 
 (define chi-void
   (lambda ()
-    (build-application no-source (build-primref no-source 'void) '())))
+    (build-application no-source (build-primref no-source 'if) '(#f #f))))
 
 (define ellipsis?
   (lambda (x)
             ((vector? x)
              (let ((old (vector->list x)))
                 (let ((new (map f old)))
-                   (if (andmap eq? old new) x (list->vector new)))))
+                   (if (and-map* eq? old new) x (list->vector new)))))
             (else x))))))
 
 ;;; lexical variables
        (let ((names (map (lambda (x) (id-var-name x w)) (syntax (var ...)))))
          (for-each
            (lambda (id n)
-             (case (binding-type (lookup n r))
+             (case (binding-type (lookup n r mod))
                ((displaced-lexical)
-                (syntax-error (source-wrap id w s mod)
-                  "identifier out of context"))))
+                (syntax-violation 'fluid-let-syntax
+                                  "identifier out of context"
+                                  e
+                                  (source-wrap id w s mod)))))
            (syntax (var ...))
            names)
          (chi-body
              r)
            w
            mod)))
-      (_ (syntax-error (source-wrap e w s mod))))))
+      (_ (syntax-violation 'fluid-let-syntax "bad syntax"
+                           (source-wrap e w s mod))))))
 
 (global-extend 'core 'quote
    (lambda (e r w s mod)
       (syntax-case e ()
          ((_ e) (build-data s (strip (syntax e) w)))
-         (_ (syntax-error (source-wrap e w s mod))))))
+         (_ (syntax-violation 'quote "bad syntax"
+                              (source-wrap e w s mod))))))
 
 (global-extend 'core 'syntax
   (let ()
     (define gen-syntax
-      (lambda (src e r maps ellipsis?)
+      (lambda (src e r maps ellipsis? mod)
         (if (id? e)
             (let ((label (id-var-name e empty-wrap)))
-              (let ((b (lookup label r)))
+              (let ((b (lookup label r mod)))
                 (if (eq? (binding-type b) 'syntax)
                     (call-with-values
                       (lambda ()
                           (gen-ref src (car var.lev) (cdr var.lev) maps)))
                       (lambda (var maps) (values `(ref ,var) maps)))
                     (if (ellipsis? e)
-                        (syntax-error src "misplaced ellipsis in syntax form")
+                        (syntax-violation 'syntax "misplaced ellipsis" src)
                         (values `(quote ,e) maps)))))
             (syntax-case e ()
               ((dots e)
                (ellipsis? (syntax dots))
-               (gen-syntax src (syntax e) r maps (lambda (x) #f)))
+               (gen-syntax src (syntax e) r maps (lambda (x) #f) mod))
               ((x dots . y)
                ; this could be about a dozen lines of code, except that we
                ; choose to handle (syntax (x ... ...)) forms
                             (call-with-values
                               (lambda ()
                                 (gen-syntax src (syntax x) r
-                                  (cons '() maps) ellipsis?))
+                                  (cons '() maps) ellipsis? mod))
                               (lambda (x maps)
                                 (if (null? (car maps))
-                                    (syntax-error src
-                                      "extra ellipsis in syntax form")
+                                    (syntax-violation 'syntax "extra ellipsis"
+                                                      src)
                                     (values (gen-map x (car maps))
                                             (cdr maps))))))))
                  (syntax-case y ()
                            (lambda () (k (cons '() maps)))
                            (lambda (x maps)
                              (if (null? (car maps))
-                                 (syntax-error src
-                                   "extra ellipsis in syntax form")
+                                 (syntax-violation 'syntax "extra ellipsis" src)
                                  (values (gen-mappend x (car maps))
                                          (cdr maps))))))))
                    (_ (call-with-values
-                        (lambda () (gen-syntax src y r maps ellipsis?))
+                        (lambda () (gen-syntax src y r maps ellipsis? mod))
                         (lambda (y maps)
                           (call-with-values
                             (lambda () (k maps))
                               (values (gen-append x y) maps)))))))))
               ((x . y)
                (call-with-values
-                 (lambda () (gen-syntax src (syntax x) r maps ellipsis?))
+                 (lambda () (gen-syntax src (syntax x) r maps ellipsis? mod))
                  (lambda (x maps)
                    (call-with-values
-                     (lambda () (gen-syntax src (syntax y) r maps ellipsis?))
+                     (lambda () (gen-syntax src (syntax y) r maps ellipsis? mod))
                      (lambda (y maps) (values (gen-cons x y) maps))))))
               (#(e1 e2 ...)
                (call-with-values
                  (lambda ()
-                   (gen-syntax src (syntax (e1 e2 ...)) r maps ellipsis?))
+                   (gen-syntax src (syntax (e1 e2 ...)) r maps ellipsis? mod))
                  (lambda (e maps) (values (gen-vector e) maps))))
               (_ (values `(quote ,e) maps))))))
 
         (if (fx= level 0)
             (values var maps)
             (if (null? maps)
-                (syntax-error src "missing ellipsis in syntax form")
+                (syntax-violation 'syntax "missing ellipsis" src)
                 (call-with-values
                   (lambda () (gen-ref src var (fx- level 1) (cdr maps)))
                   (lambda (outer-var outer-maps)
              ; identity map equivalence:
              ; (map (lambda (x) x) y) == y
              (car actuals))
-            ((andmap
+            ((and-map
                 (lambda (x) (and (eq? (car x) 'ref) (memq (cadr x) formals)))
                 (cdr e))
              ; eta map equivalence:
     (define regen
       (lambda (x)
         (case (car x)
-          ((ref) (build-lexical-reference 'value no-source (cadr x)))
+          ((ref) (build-lexical-reference 'value no-source (cadr x) (cadr x)))
           ((primitive) (build-primref no-source (cadr x)))
           ((quote) (build-data no-source (cadr x)))
-          ((lambda) (build-lambda no-source (cadr x) (regen (caddr x))))
+          ((lambda) (build-lambda no-source (cadr x) (cadr x) #f (regen (caddr x))))
           ((map) (let ((ls (map regen (cdr x))))
                    (build-application no-source
-                     (if (fx= (length ls) 2)
-                         (build-primref no-source 'map)
-                        ; really need to do our own checking here
-                         (build-primref no-source 2 'map)) ; require error check
+                     ;; this check used to be here, not sure what for:
+                     ;; (if (fx= (length ls) 2)
+                     (build-primref no-source 'map)
                      ls)))
           (else (build-application no-source
                   (build-primref no-source (car x))
         (syntax-case e ()
           ((_ x)
            (call-with-values
-             (lambda () (gen-syntax e (syntax x) r '() ellipsis?))
-             ;; It doesn't seem we need `mod' here as `syntax' only
-             ;; references lexical vars and primitives.
+             (lambda () (gen-syntax e (syntax x) r '() ellipsis? mod))
              (lambda (e maps) (regen e))))
-          (_ (syntax-error e)))))))
+          (_ (syntax-violation 'syntax "bad `syntax' form" e)))))))
 
 
 (global-extend 'core 'lambda
    (lambda (e r w s mod)
       (syntax-case e ()
          ((_ . c)
-          (chi-lambda-clause (source-wrap e w s mod) (syntax c) r w mod
-            (lambda (vars body) (build-lambda s vars body)))))))
+          (chi-lambda-clause (source-wrap e w s mod) #f (syntax c) r w mod
+            (lambda (names vars docstring body)
+              (build-lambda s names vars docstring body)))))))
 
 
 (global-extend 'core 'let
   (let ()
     (define (chi-let e r w s mod constructor ids vals exps)
       (if (not (valid-bound-ids? ids))
-         (syntax-error e "duplicate bound variable in")
+         (syntax-violation 'let "duplicate bound variable" e)
          (let ((labels (gen-labels ids))
                (new-vars (map gen-var ids)))
            (let ((nw (make-binding-wrap ids labels w))
                  (nr (extend-var-env labels new-vars r)))
              (constructor s
+                           (map syntax->datum ids)
                           new-vars
                           (map (lambda (x) (chi x r w mod)) vals)
                           (chi-body exps (source-wrap e nw s mod)
                  (syntax (f id ...))
                  (syntax (val ...))
                  (syntax (e1 e2 ...))))
-       (_ (syntax-error (source-wrap e w s mod)))))))
+       (_ (syntax-violation 'let "bad let" (source-wrap e w s mod)))))))
 
 
 (global-extend 'core 'letrec
       ((_ ((id val) ...) e1 e2 ...)
        (let ((ids (syntax (id ...))))
          (if (not (valid-bound-ids? ids))
-             (syntax-error e "duplicate bound variable in")
+             (syntax-violation 'letrec "duplicate bound variable" e)
              (let ((labels (gen-labels ids))
                    (new-vars (map gen-var ids)))
                (let ((w (make-binding-wrap ids labels w))
                     (r (extend-var-env labels new-vars r)))
                  (build-letrec s
+                   (map syntax->datum ids)
                    new-vars
                    (map (lambda (x) (chi x r w mod)) (syntax (val ...)))
                    (chi-body (syntax (e1 e2 ...)) 
                              (source-wrap e w s mod) r w mod)))))))
-      (_ (syntax-error (source-wrap e w s mod))))))
+      (_ (syntax-violation 'letrec "bad letrec" (source-wrap e w s mod))))))
 
 
 (global-extend 'core 'set!
        (id? (syntax id))
        (let ((val (chi (syntax val) r w mod))
              (n (id-var-name (syntax id) w)))
-         (let ((b (lookup n r)))
+         (let ((b (lookup n r mod)))
            (case (binding-type b)
              ((lexical)
-              (build-lexical-assignment s (binding-value b) val))
+              (build-lexical-assignment s
+                                        (syntax->datum (syntax id))
+                                        (binding-value b)
+                                        val))
              ((global) (build-global-assignment s n val mod))
              ((displaced-lexical)
-              (syntax-error (wrap (syntax id) w #f)
-                "identifier out of context"))
-             (else (syntax-error (source-wrap e w s mod)))))))
-      ((_ (getter arg ...) val)
-       (build-application s
-                         (chi (syntax (setter getter)) r w mod)
-                         (map (lambda (e) (chi e r w mod))
-                              (syntax (arg ... val)))))
-      (_ (syntax-error (source-wrap e w s mod))))))
+              (syntax-violation 'set! "identifier out of context"
+                                (wrap (syntax id) w mod)))
+             (else (syntax-violation 'set! "bad set!"
+                                     (source-wrap e w s mod)))))))
+      ((_ (head tail ...) val)
+       (call-with-values
+           (lambda () (syntax-type (syntax head) r empty-wrap no-source #f mod))
+         (lambda (type value ee ww ss modmod)
+           (case type
+             ((module-ref)
+              (let ((val (chi (syntax val) r w mod)))
+                (call-with-values (lambda () (value (syntax (head tail ...))))
+                  (lambda (id mod)
+                    (build-global-assignment s id val mod)))))
+             (else
+              (build-application s
+                                 (chi (syntax (setter head)) r w mod)
+                                 (map (lambda (e) (chi e r w mod))
+                                      (syntax (tail ... val)))))))))
+      (_ (syntax-violation 'set! "bad set!" (source-wrap e w s mod))))))
+
+(global-extend 'module-ref '@
+   (lambda (e)
+     (syntax-case e ()
+        ((_ (mod ...) id)
+         (and (and-map id? (syntax (mod ...))) (id? (syntax id)))
+         (values (syntax->datum (syntax id))
+                 (syntax->datum
+                  (syntax (public mod ...))))))))
+
+(global-extend 'module-ref '@@
+   (lambda (e)
+     (syntax-case e ()
+        ((_ (mod ...) id)
+         (and (and-map id? (syntax (mod ...))) (id? (syntax id)))
+         (values (syntax->datum (syntax id))
+                 (syntax->datum
+                  (syntax (private mod ...))))))))
 
 (global-extend 'begin 'begin '())
 
   (let ()
     (define convert-pattern
       ; accepts pattern & keys
-      ; returns syntax-dispatch pattern & ids
+      ; returns $sc-dispatch pattern & ids
       (lambda (pattern keys)
         (let cvt ((p pattern) (n 0) (ids '()))
           (if (id? p)
           (let ((labels (gen-labels ids)) (new-vars (map gen-var ids)))
             (build-application no-source
               (build-primref no-source 'apply)
-              (list (build-lambda no-source new-vars
+              (list (build-lambda no-source (map syntax->datum ids) new-vars #f
                       (chi exp
                            (extend-env
                             labels
           (lambda (p pvars)
             (cond
               ((not (distinct-bound-ids? (map car pvars)))
-               (syntax-error pat
-                 "duplicate pattern variable in syntax-case pattern"))
-              ((not (andmap (lambda (x) (not (ellipsis? (car x)))) pvars))
-               (syntax-error pat
-                 "misplaced ellipsis in syntax-case pattern"))
+               (syntax-violation 'syntax-case "duplicate pattern variable" pat))
+              ((not (and-map (lambda (x) (not (ellipsis? (car x)))) pvars))
+               (syntax-violation 'syntax-case "misplaced ellipsis" pat))
               (else
                (let ((y (gen-var 'tmp)))
                  ; fat finger binding and references to temp variable y
                  (build-application no-source
-                   (build-lambda no-source (list y)
-                     (let ((y (build-lexical-reference 'value no-source y)))
+                   (build-lambda no-source (list 'tmp) (list y) #f
+                     (let ((y (build-lexical-reference 'value no-source
+                                                       'tmp y)))
                        (build-conditional no-source
                          (syntax-case fender ()
                            (#t y)
                                (build-primref no-source 'list)
                                (list x))
                              (build-application no-source
-                               (build-primref no-source 'syntax-dispatch)
+                               (build-primref no-source '$sc-dispatch)
                                (list x (build-data no-source p)))))))))))))
 
     (define gen-syntax-case
       (lambda (x keys clauses r mod)
         (if (null? clauses)
             (build-application no-source
-              (build-primref no-source 'syntax-error)
-              (list x))
+              (build-primref no-source 'syntax-violation)
+              (list #f "source expression failed to match any pattern" x))
             (syntax-case (car clauses) ()
               ((pat exp)
                (if (and (id? (syntax pat))
-                        (andmap (lambda (x) (not (free-id=? (syntax pat) x)))
-                          (cons (syntax (... ...)) keys)))
+                        (and-map (lambda (x) (not (free-id=? (syntax pat) x)))
+                                 (cons (syntax (... ...)) keys)))
                    (let ((labels (list (gen-label)))
                          (var (gen-var (syntax pat))))
                      (build-application no-source
-                       (build-lambda no-source (list var)
+                       (build-lambda no-source
+                                     (list (syntax->datum (syntax pat))) (list var)
+                                     #f
                          (chi (syntax exp)
                               (extend-env labels
                                 (list (make-binding 'syntax `(,var . 0)))
               ((pat fender exp)
                (gen-clause x keys (cdr clauses) r
                  (syntax pat) (syntax fender) (syntax exp) mod))
-              (_ (syntax-error (car clauses) "invalid syntax-case clause"))))))
+              (_ (syntax-violation 'syntax-case "invalid clause"
+                                   (car clauses)))))))
 
     (lambda (e r w s mod)
       (let ((e (source-wrap e w s mod)))
         (syntax-case e ()
           ((_ val (key ...) m ...)
-           (if (andmap (lambda (x) (and (id? x) (not (ellipsis? x))))
-                       (syntax (key ...)))
+           (if (and-map (lambda (x) (and (id? x) (not (ellipsis? x))))
+                        (syntax (key ...)))
                (let ((x (gen-var 'tmp)))
                  ; fat finger binding and references to temp variable x
                  (build-application s
-                   (build-lambda no-source (list x)
-                     (gen-syntax-case (build-lexical-reference 'value no-source x)
+                   (build-lambda no-source (list 'tmp) (list x) #f
+                     (gen-syntax-case (build-lexical-reference 'value no-source
+                                                               'tmp x)
                        (syntax (key ...)) (syntax (m ...))
                        r
                        mod))
                    (list (chi (syntax val) r empty-wrap mod))))
-               (syntax-error e "invalid literals list in"))))))))
+               (syntax-violation 'syntax-case "invalid literals list" e))))))))
 
 ;;; The portable sc-expand seeds chi-top's mode m with 'e (for
 ;;; evaluating) and esew (which stands for "eval syntax expanders
 ;;; expanded, and the expanded definitions are also residualized into
 ;;; the object file if we are compiling a file.
 (set! sc-expand
-  (let ((m 'e) (esew '(eval)))
-    (lambda (x)
-      (if (and (pair? x) (equal? (car x) noexpand))
-          (cadr x)
-          (chi-top x null-env top-wrap m esew (current-module))))))
-
-(set! sc-expand3
-  (let ((m 'e) (esew '(eval)))
-    (lambda (x . rest)
-      (if (and (pair? x) (equal? (car x) noexpand))
-          (cadr x)
-          (chi-top x
-                  null-env
-                  top-wrap
-                  (if (null? rest) m (car rest))
-                  (if (or (null? rest) (null? (cdr rest)))
-                      esew
-                      (cadr rest))
-                   (current-module))))))
+      (lambda (x . rest)
+        (if (and (pair? x) (equal? (car x) noexpand))
+            (cadr x)
+            (let ((m (if (null? rest) 'e (car rest)))
+                  (esew (if (or (null? rest) (null? (cdr rest)))
+                            '(eval)
+                            (cadr rest))))
+              (with-fluid* *mode* m
+                (lambda ()
+                  (chi-top x null-env top-wrap m esew
+                           (cons 'hygiene (module-name (current-module))))))))))
 
 (set! identifier?
   (lambda (x)
     (nonsymbol-id? x)))
 
-(set! datum->syntax-object
+(set! datum->syntax
   (lambda (id datum)
     (make-syntax-object datum (syntax-object-wrap id) #f)))
 
-(set! syntax-object->datum
+(set! syntax->datum
   ; accepts any object, since syntax objects may consist partially
   ; or entirely of unwrapped, nonsymbolic data
   (lambda (x)
       (arg-check nonsymbol-id? y 'bound-identifier=?)
       (bound-id=? x y)))
 
-(set! syntax-error
-  (lambda (object . messages)
-    (for-each (lambda (x) (arg-check string? x 'syntax-error)) messages)
-    (let ((message (if (null? messages)
-                       "invalid syntax"
-                       (apply string-append messages))))
-      (error-hook #f message (strip object empty-wrap)))))
-
-(set! install-global-transformer
-  (lambda (sym v)
-    (arg-check symbol? sym 'define-syntax)
-    (arg-check procedure? v 'define-syntax)
-    (global-extend 'macro sym v)))
-
-;;; syntax-dispatch expects an expression and a pattern.  If the expression
+(set! syntax-violation
+  (lambda (who message form . subform)
+    (arg-check (lambda (x) (or (not x) (string? x) (symbol? x)))
+               who 'syntax-violation)
+    (arg-check string? message 'syntax-violation)
+    (scm-error 'syntax-error 'sc-expand
+               (string-append
+                (if who "~a: " "")
+                "~a "
+                (if (null? subform) "in ~a" "in subform `~s' of `~s'"))
+               (let ((tail (cons message
+                                 (map (lambda (x) (strip x empty-wrap))
+                                      (append subform (list form))))))
+                 (if who (cons who tail) tail))
+               #f)))
+
+;;; $sc-dispatch expects an expression and a pattern.  If the expression
 ;;; matches the pattern a list of the matching expressions for each
 ;;; "any" is returned.  Otherwise, #f is returned.  (This use of #f will
 ;;; not work on r4rs implementations that violate the ieee requirement
 (let ()
 
 (define match-each
-  (lambda (e p w)
+  (lambda (e p w mod)
     (cond
       ((annotation? e)
-       (match-each (annotation-expression e) p w))
+       (match-each (annotation-expression e) p w mod))
       ((pair? e)
-       (let ((first (match (car e) p w '())))
+       (let ((first (match (car e) p w '() mod)))
          (and first
-              (let ((rest (match-each (cdr e) p w)))
+              (let ((rest (match-each (cdr e) p w mod)))
                  (and rest (cons first rest))))))
       ((null? e) '())
       ((syntax-object? e)
        (match-each (syntax-object-expression e)
                    p
-                   (join-wraps w (syntax-object-wrap e))))
+                   (join-wraps w (syntax-object-wrap e))
+                   (syntax-object-module e)))
       (else #f))))
 
 (define match-each-any
-  (lambda (e w)
+  (lambda (e w mod)
     (cond
       ((annotation? e)
-       (match-each-any (annotation-expression e) w))
+       (match-each-any (annotation-expression e) w mod))
       ((pair? e)
-       (let ((l (match-each-any (cdr e) w)))
-         (and l (cons (wrap (car e) w #f) l))))
+       (let ((l (match-each-any (cdr e) w mod)))
+         (and l (cons (wrap (car e) w mod) l))))
       ((null? e) '())
       ((syntax-object? e)
        (match-each-any (syntax-object-expression e)
-                       (join-wraps w (syntax-object-wrap e))))
+                       (join-wraps w (syntax-object-wrap e))
+                       mod))
       (else #f))))
 
 (define match-empty
          ((vector) (match-empty (vector-ref p 1) r)))))))
 
 (define match*
-  (lambda (e p w r)
+  (lambda (e p w r mod)
     (cond
       ((null? p) (and (null? e) r))
       ((pair? p)
        (and (pair? e) (match (car e) (car p) w
-                        (match (cdr e) (cdr p) w r))))
+                        (match (cdr e) (cdr p) w r mod)
+                        mod)))
       ((eq? p 'each-any)
-       (let ((l (match-each-any e w))) (and l (cons l r))))
+       (let ((l (match-each-any e w mod))) (and l (cons l r))))
       (else
        (case (vector-ref p 0)
          ((each)
           (if (null? e)
               (match-empty (vector-ref p 1) r)
-              (let ((l (match-each e (vector-ref p 1) w)))
+              (let ((l (match-each e (vector-ref p 1) w mod)))
                 (and l
                      (let collect ((l l))
                        (if (null? (car l))
                            r
                            (cons (map car l) (collect (map cdr l)))))))))
-         ((free-id) (and (id? e) (free-id=? (wrap e w #f) (vector-ref p 1)) r))
+         ((free-id) (and (id? e) (free-id=? (wrap e w mod) (vector-ref p 1)) r))
          ((atom) (and (equal? (vector-ref p 1) (strip e w)) r))
          ((vector)
           (and (vector? e)
-               (match (vector->list e) (vector-ref p 1) w r))))))))
+               (match (vector->list e) (vector-ref p 1) w r mod))))))))
 
 (define match
-  (lambda (e p w r)
+  (lambda (e p w r mod)
     (cond
       ((not r) #f)
-      ((eq? p 'any) (cons (wrap e w #f) r))
+      ((eq? p 'any) (cons (wrap e w mod) r))
       ((syntax-object? e)
        (match*
          (unannotate (syntax-object-expression e))
          p
          (join-wraps w (syntax-object-wrap e))
-         r))
-      (else (match* (unannotate e) p w r)))))
+         r
+         (syntax-object-module e)))
+      (else (match* (unannotate e) p w r mod)))))
 
-(set! syntax-dispatch
+(set! $sc-dispatch
   (lambda (e p)
     (cond
       ((eq? p 'any) (list e))
       ((syntax-object? e)
        (match* (unannotate (syntax-object-expression e))
-         p (syntax-object-wrap e) '()))
-      (else (match* (unannotate e) p empty-wrap '())))))
+         p (syntax-object-wrap e) '() (syntax-object-module e)))
+      (else (match* (unannotate e) p empty-wrap '() #f)))))
 
-(set! sc-chi chi)
 ))
 )
 
   (lambda (x)
     (syntax-case x ()
       ((let* ((x v) ...) e1 e2 ...)
-       (andmap identifier? (syntax (x ...)))
+       (and-map identifier? (syntax (x ...)))
        (let f ((bindings (syntax ((x v)  ...))))
          (if (null? bindings)
              (syntax (let () e1 e2 ...))
                                  (syntax-case s ()
                                     (() v)
                                     ((e) (syntax e))
-                                    (_ (syntax-error orig-x))))
+                                    (_ (syntax-violation
+                                        'do "bad step expression" 
+                                        orig-x s))))
                               (syntax (var ...))
                               (syntax (step ...)))))
              (syntax-case (syntax (e1 ...)) ()
           (let f ((x (read p)))
             (if (eof-object? x)
                 (begin (close-input-port p) '())
-                (cons (datum->syntax-object k x)
+                (cons (datum->syntax k x)
                       (f (read p))))))))
     (syntax-case x ()
       ((k filename)
-       (let ((fn (syntax-object->datum (syntax filename))))
+       (let ((fn (syntax->datum (syntax filename))))
          (with-syntax (((exp ...) (read-file fn (syntax k))))
            (syntax (begin exp ...))))))))
 
 (define-syntax unquote
-   (lambda (x)
-      (syntax-case x ()
-         ((_ e)
-          (error 'unquote
-                "expression ,~s not valid outside of quasiquote"
-                (syntax-object->datum (syntax e)))))))
+  (lambda (x)
+    (syntax-case x ()
+      ((_ e)
+       (syntax-violation 'unquote
+                         "expression not valid outside of quasiquote"
+                         x)))))
 
 (define-syntax unquote-splicing
-   (lambda (x)
-      (syntax-case x ()
-         ((_ e)
-          (error 'unquote-splicing
-                "expression ,@~s not valid outside of quasiquote"
-                (syntax-object->datum (syntax e)))))))
+  (lambda (x)
+    (syntax-case x ()
+      ((_ e)
+       (syntax-violation 'unquote-splicing
+                         "expression not valid outside of quasiquote"
+                         x)))))
 
 (define-syntax case
   (lambda (x)
                         ((else e1 e2 ...) (syntax (begin e1 e2 ...)))
                         (((k ...) e1 e2 ...)
                          (syntax (if (memv t '(k ...)) (begin e1 e2 ...))))
-                        (_ (syntax-error x)))
+                        (_ (syntax-violation 'case "bad clause" x clause)))
                       (with-syntax ((rest (f (car clauses) (cdr clauses))))
                         (syntax-case clause (else)
                           (((k ...) e1 e2 ...)
                            (syntax (if (memv t '(k ...))
                                        (begin e1 e2 ...)
                                        rest)))
-                          (_ (syntax-error x))))))))
+                          (_ (syntax-violation 'case "bad clause" x
+                                               clause))))))))
          (syntax (let ((t e)) body)))))))
 
 (define-syntax identifier-syntax
               (syntax e))
              ((_ x (... ...))
               (syntax (e x (... ...)))))))))))
-