slot-ref, slot-set! et al bypass "using-class" variants
[bpt/guile.git] / module / ice-9 / psyntax-pp.scm
index e330423..7ad8a70 100644 (file)
          gensyms
          vals
          body)))
-   (make-dynlet
-     (lambda (src fluids vals body)
-       (make-struct
-         (vector-ref %expanded-vtables 18)
-         0
-         src
-         fluids
-         vals
-         body)))
    (lambda?
      (lambda (x)
        (and (struct? x)
      (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)
-                     (macro-type val)
-                     (cons (macro-type val) (macro-binding val))))))))
+       (and (not (equal? module '(primitive)))
+            (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)
+                          (macro-type val)
+                          (cons (macro-type val) (macro-binding val)))))))))
    (decorate-source
      (lambda (e s)
        (if (and s (supports-source-properties? e))
    (build-conditional
      (lambda (source test-exp then-exp else-exp)
        (make-conditional source test-exp then-exp else-exp)))
-   (build-dynlet
-     (lambda (source fluids vals body)
-       (make-dynlet source fluids vals body)))
    (build-lexical-reference
      (lambda (type source name var) (make-lexical-ref source name var)))
    (build-lexical-assignment
                              (module-variable (resolve-module mod) var))
                       (modref-cont mod var #f)
                       (bare-cont var)))
+                   ((memv key '(primitive))
+                    (syntax-violation #f "primitive not in operator position" var))
                    (else (syntax-violation #f "bad module kind" var mod))))))))
    (build-global-reference
      (lambda (source var mod)
        (if (null? r)
          '()
          (let ((a (car r)))
-           (if (memq (cadr a) '(macro syntax-parameter))
+           (if (memq (cadr a) '(macro syntax-parameter ellipsis))
              (cons a (macros-only-env (cdr r)))
              (macros-only-env (cdr r)))))))
    (global-extend
                                        (let ((x (build-global-definition s var (expand e r w mod))))
                                          (top-level-eval-hook x mod)
                                          (lambda () x))
-                                       (lambda () (build-global-definition s var (expand e r w mod)))))))
+                                       (call-with-values
+                                         (lambda () (resolve-identifier id '(()) r mod #t))
+                                         (lambda (type* value* mod*)
+                                           (if (eq? type* 'macro)
+                                             (top-level-eval-hook
+                                               (build-global-definition s var (build-void s))
+                                               mod))
+                                           (lambda () (build-global-definition s var (expand e r w mod)))))))))
                             ((memv key '(define-syntax-form define-syntax-parameter-form))
                              (let* ((id (wrap value w mod))
                                     (label (gen-label))
                     (let ((key ftype))
                       (cond ((memv key '(lexical)) (values 'lexical-call fval e e w s mod))
                             ((memv key '(global))
-                             (values 'global-call (make-syntax-object fval w fmod) e e w s mod))
+                             (if (equal? fmod '(primitive))
+                               (values 'primitive-call fval e e w s mod)
+                               (values 'global-call (make-syntax-object fval w fmod) e e w s mod)))
                             ((memv key '(macro))
                              (syntax-type
                                (expand-macro fval e r w s rib mod)
                                for-car?))
                             ((memv key '(module-ref))
                              (call-with-values
-                               (lambda () (fval e r w))
+                               (lambda () (fval e r w mod))
                                (lambda (e r w s mod) (syntax-type e r w s rib mod for-car?))))
                             ((memv key '(core)) (values 'core-form fval e e w s mod))
                             ((memv key '(local-syntax))
                ((memv key '(core core-form)) (value e r w s mod))
                ((memv key '(module-ref))
                 (call-with-values
-                  (lambda () (value e r w))
+                  (lambda () (value e r w mod))
                   (lambda (e r w s mod) (expand e r w mod))))
                ((memv key '(lexical-call))
                 (expand-call
                   w
                   s
                   mod))
+               ((memv key '(primitive-call))
+                (let* ((tmp-1 e) (tmp ($sc-dispatch tmp-1 '(_ . each-any))))
+                  (if tmp
+                    (apply (lambda (e)
+                             (build-primcall s value (map (lambda (e) (expand e r w mod)) e)))
+                           tmp)
+                    (syntax-violation
+                      #f
+                      "source expression failed to match any pattern"
+                      tmp-1))))
                ((memv key '(constant))
                 (build-data s (strip (source-wrap e w s mod) '(()))))
                ((memv key '(global)) (build-global-reference s value mod))
                        (source-wrap e w (cdr w) mod)
                        x))
                     (else (decorate-source x s))))))
-         (with-fluids
-           ((transformer-environment (lambda (k) (k e r w s rib mod))))
-           (rebuild-macro-output
-             (p (source-wrap e (anti-mark w) s mod))
-             (gensym (string-append "m-" (session-id) "-")))))))
+         (let* ((t-1 transformer-environment) (t (lambda (k) (k e r w s rib mod))))
+           (with-fluid*
+             t-1
+             t
+             (lambda ()
+               (rebuild-macro-output
+                 (p (source-wrap e (anti-mark w) s mod))
+                 (gensym (string-append "m-" (session-id) "-")))))))))
    (expand-body
      (lambda (body outer-form r w mod)
        (let* ((r (cons '("placeholder" placeholder) r))
            (syntax-violation #f "nonprocedure transformer" p)))))
    (expand-void (lambda () (build-void #f)))
    (ellipsis?
-     (lambda (x)
-       (and (nonsymbol-id? x)
-            (free-id=? x '#(syntax-object ... ((top)) (hygiene guile))))))
+     (lambda (e r mod)
+       (and (nonsymbol-id? e)
+            (call-with-values
+              (lambda ()
+                (resolve-identifier
+                  (make-syntax-object
+                    '#{ $sc-ellipsis }#
+                    (syntax-object-wrap e)
+                    (syntax-object-module e))
+                  '(())
+                  r
+                  mod
+                  #f))
+              (lambda (type value mod)
+                (if (eq? type 'ellipsis)
+                  (bound-id=? e value)
+                  (free-id=? e '#(syntax-object ... ((top)) (hygiene guile)))))))))
    (lambda-formals
      (lambda (orig-args)
        (letrec*
                           (call-with-values
                             (lambda () (gen-ref src (car value) (cdr value) maps))
                             (lambda (var maps) (values (list 'ref var) maps))))
-                         ((ellipsis? e) (syntax-violation 'syntax "misplaced ellipsis" src))
+                         ((ellipsis? e r mod)
+                          (syntax-violation 'syntax "misplaced ellipsis" src))
                          (else (values (list 'quote e) maps))))))
              (let* ((tmp e) (tmp-1 ($sc-dispatch tmp '(any any))))
-               (if (and tmp-1 (apply (lambda (dots e) (ellipsis? dots)) tmp-1))
-                 (apply (lambda (dots e) (gen-syntax src e r maps (lambda (x) #f) mod))
+               (if (and tmp-1 (apply (lambda (dots e) (ellipsis? dots r mod)) tmp-1))
+                 (apply (lambda (dots e) (gen-syntax src e r maps (lambda (e r mod) #f) mod))
                         tmp-1)
                  (let ((tmp-1 ($sc-dispatch tmp '(any any . any))))
-                   (if (and tmp-1 (apply (lambda (x dots y) (ellipsis? dots)) tmp-1))
+                   (if (and tmp-1 (apply (lambda (x dots y) (ellipsis? dots r mod)) tmp-1))
                      (apply (lambda (x dots y)
                               (let f ((y y)
                                       (k (lambda (maps)
                                                  (syntax-violation 'syntax "extra ellipsis" src)
                                                  (values (gen-map x (car maps)) (cdr maps))))))))
                                 (let* ((tmp y) (tmp ($sc-dispatch tmp '(any . any))))
-                                  (if (and tmp (apply (lambda (dots y) (ellipsis? dots)) tmp))
+                                  (if (and tmp (apply (lambda (dots y) (ellipsis? dots r mod)) tmp))
                                     (apply (lambda (dots y)
                                              (f y
                                                 (lambda (maps)
     'core
     'case-lambda
     (lambda (e r w s mod)
-      (let* ((tmp e)
-             (tmp ($sc-dispatch
-                    tmp
-                    '(_ (any any . each-any) . #(each (any any . each-any))))))
-        (if tmp
-          (apply (lambda (args e1 e2 args* e1* e2*)
-                   (call-with-values
-                     (lambda ()
-                       (expand-lambda-case
-                         e
-                         r
-                         w
-                         s
-                         mod
-                         lambda-formals
-                         (cons (cons args (cons e1 e2))
-                               (map (lambda (tmp-2 tmp-1 tmp) (cons tmp (cons tmp-1 tmp-2)))
-                                    e2*
-                                    e1*
-                                    args*))))
-                     (lambda (meta lcase) (build-case-lambda s meta lcase))))
-                 tmp)
-          (syntax-violation 'case-lambda "bad case-lambda" e)))))
+      (letrec*
+        ((build-it
+           (lambda (meta clauses)
+             (call-with-values
+               (lambda () (expand-lambda-case e r w s mod lambda-formals clauses))
+               (lambda (meta* lcase)
+                 (build-case-lambda s (append meta meta*) lcase))))))
+        (let* ((tmp-1 e)
+               (tmp ($sc-dispatch tmp-1 '(_ . #(each (any any . each-any))))))
+          (if tmp
+            (apply (lambda (args e1 e2)
+                     (build-it
+                       '()
+                       (map (lambda (tmp-2 tmp-1 tmp) (cons tmp (cons tmp-1 tmp-2)))
+                            e2
+                            e1
+                            args)))
+                   tmp)
+            (let ((tmp ($sc-dispatch tmp-1 '(_ any . #(each (any any . each-any))))))
+              (if (and tmp
+                       (apply (lambda (docstring args e1 e2) (string? (syntax->datum docstring)))
+                              tmp))
+                (apply (lambda (docstring args e1 e2)
+                         (build-it
+                           (list (cons 'documentation (syntax->datum docstring)))
+                           (map (lambda (tmp-2 tmp-1 tmp) (cons tmp (cons tmp-1 tmp-2)))
+                                e2
+                                e1
+                                args)))
+                       tmp)
+                (syntax-violation 'case-lambda "bad case-lambda" e))))))))
   (global-extend
     'core
     'case-lambda*
     (lambda (e r w s mod)
-      (let* ((tmp e)
-             (tmp ($sc-dispatch
-                    tmp
-                    '(_ (any any . each-any) . #(each (any any . each-any))))))
-        (if tmp
-          (apply (lambda (args e1 e2 args* e1* e2*)
-                   (call-with-values
-                     (lambda ()
-                       (expand-lambda-case
-                         e
-                         r
-                         w
-                         s
-                         mod
-                         lambda*-formals
-                         (cons (cons args (cons e1 e2))
-                               (map (lambda (tmp-2 tmp-1 tmp) (cons tmp (cons tmp-1 tmp-2)))
-                                    e2*
-                                    e1*
-                                    args*))))
-                     (lambda (meta lcase) (build-case-lambda s meta lcase))))
+      (letrec*
+        ((build-it
+           (lambda (meta clauses)
+             (call-with-values
+               (lambda () (expand-lambda-case e r w s mod lambda*-formals clauses))
+               (lambda (meta* lcase)
+                 (build-case-lambda s (append meta meta*) lcase))))))
+        (let* ((tmp-1 e)
+               (tmp ($sc-dispatch tmp-1 '(_ . #(each (any any . each-any))))))
+          (if tmp
+            (apply (lambda (args e1 e2)
+                     (build-it
+                       '()
+                       (map (lambda (tmp-2 tmp-1 tmp) (cons tmp (cons tmp-1 tmp-2)))
+                            e2
+                            e1
+                            args)))
+                   tmp)
+            (let ((tmp ($sc-dispatch tmp-1 '(_ any . #(each (any any . each-any))))))
+              (if (and tmp
+                       (apply (lambda (docstring args e1 e2) (string? (syntax->datum docstring)))
+                              tmp))
+                (apply (lambda (docstring args e1 e2)
+                         (build-it
+                           (list (cons 'documentation (syntax->datum docstring)))
+                           (map (lambda (tmp-2 tmp-1 tmp) (cons tmp (cons tmp-1 tmp-2)))
+                                e2
+                                e1
+                                args)))
+                       tmp)
+                (syntax-violation 'case-lambda "bad case-lambda*" e))))))))
+  (global-extend
+    'core
+    'with-ellipsis
+    (lambda (e r w s mod)
+      (let* ((tmp e) (tmp ($sc-dispatch tmp '(_ any any . each-any))))
+        (if (and tmp (apply (lambda (dots e1 e2) (id? dots)) tmp))
+          (apply (lambda (dots e1 e2)
+                   (let ((id (if (symbol? dots)
+                               '#{ $sc-ellipsis }#
+                               (make-syntax-object
+                                 '#{ $sc-ellipsis }#
+                                 (syntax-object-wrap dots)
+                                 (syntax-object-module dots)))))
+                     (let ((ids (list id))
+                           (labels (list (gen-label)))
+                           (bindings (list (cons 'ellipsis (source-wrap dots w s mod)))))
+                       (let ((nw (make-binding-wrap ids labels w))
+                             (nr (extend-env labels bindings r)))
+                         (expand-body (cons e1 e2) (source-wrap e nw s mod) nr nw mod)))))
                  tmp)
-          (syntax-violation 'case-lambda "bad case-lambda*" e)))))
+          (syntax-violation
+            'with-ellipsis
+            "bad syntax"
+            (source-wrap e w s mod))))))
   (global-extend
     'core
     'let
                              (if (memv key '(module-ref))
                                (let ((val (expand val r w mod)))
                                  (call-with-values
-                                   (lambda () (value (cons head tail) r w))
+                                   (lambda () (value (cons head tail) r w mod))
                                    (lambda (e r w s* mod)
                                      (let* ((tmp-1 e) (tmp (list tmp-1)))
                                        (if (and tmp (apply (lambda (e) (id? e)) tmp))
   (global-extend
     'module-ref
     '@
-    (lambda (e r w)
+    (lambda (e r w mod)
       (let* ((tmp-1 e) (tmp ($sc-dispatch tmp-1 '(_ each-any any))))
         (if (and tmp
                  (apply (lambda (mod id) (and (and-map id? mod) (id? id))) tmp))
   (global-extend
     'module-ref
     '@@
-    (lambda (e r w)
+    (lambda (e r w mod)
       (letrec*
         ((remodulate
            (lambda (x mod)
                             (vector-set! v i (remodulate (vector-ref x i) mod))
                             (loop (+ i 1)))))))
                    (else x)))))
-        (let* ((tmp-1 e) (tmp ($sc-dispatch tmp-1 '(_ each-any any))))
-          (if (and tmp
-                   (apply (lambda (mod id) (and (and-map id? mod) (id? id))) tmp))
-            (apply (lambda (mod id)
-                     (values
-                       (syntax->datum id)
-                       r
-                       '((top))
-                       #f
-                       (syntax->datum
-                         (cons '#(syntax-object private ((top)) (hygiene guile)) mod))))
-                   tmp)
-            (let ((tmp ($sc-dispatch
-                         tmp-1
-                         '(_ #(free-id #(syntax-object @@ ((top)) (hygiene guile)))
-                             each-any
-                             any))))
-              (if (and tmp (apply (lambda (mod exp) (and-map id? mod)) tmp))
-                (apply (lambda (mod exp)
-                         (let ((mod (syntax->datum
-                                      (cons '#(syntax-object private ((top)) (hygiene guile)) mod))))
-                           (values (remodulate exp mod) r w (source-annotation exp) mod)))
-                       tmp)
-                (syntax-violation
-                  #f
-                  "source expression failed to match any pattern"
-                  tmp-1))))))))
+        (let* ((tmp e)
+               (tmp-1 ($sc-dispatch
+                        tmp
+                        '(_ #(free-id #(syntax-object primitive ((top)) (hygiene guile))) any))))
+          (if (and tmp-1
+                   (apply (lambda (id)
+                            (and (id? id)
+                                 (equal?
+                                   (cdr (if (syntax-object? id) (syntax-object-module id) mod))
+                                   '(guile))))
+                          tmp-1))
+            (apply (lambda (id) (values (syntax->datum id) r '((top)) #f '(primitive)))
+                   tmp-1)
+            (let ((tmp-1 ($sc-dispatch tmp '(_ each-any any))))
+              (if (and tmp-1
+                       (apply (lambda (mod id) (and (and-map id? mod) (id? id))) tmp-1))
+                (apply (lambda (mod id)
+                         (values
+                           (syntax->datum id)
+                           r
+                           '((top))
+                           #f
+                           (syntax->datum
+                             (cons '#(syntax-object private ((top)) (hygiene guile)) mod))))
+                       tmp-1)
+                (let ((tmp-1 ($sc-dispatch
+                               tmp
+                               '(_ #(free-id #(syntax-object @@ ((top)) (hygiene guile)))
+                                   each-any
+                                   any))))
+                  (if (and tmp-1 (apply (lambda (mod exp) (and-map id? mod)) tmp-1))
+                    (apply (lambda (mod exp)
+                             (let ((mod (syntax->datum
+                                          (cons '#(syntax-object private ((top)) (hygiene guile)) mod))))
+                               (values (remodulate exp mod) r w (source-annotation exp) mod)))
+                           tmp-1)
+                    (syntax-violation
+                      #f
+                      "source expression failed to match any pattern"
+                      tmp))))))))))
   (global-extend
     'core
     'if
                 #f
                 "source expression failed to match any pattern"
                 tmp)))))))
-  (global-extend
-    'core
-    'with-fluids
-    (lambda (e r w s mod)
-      (let* ((tmp-1 e)
-             (tmp ($sc-dispatch tmp-1 '(_ #(each (any any)) any . each-any))))
-        (if tmp
-          (apply (lambda (fluid val b b*)
-                   (build-dynlet
-                     s
-                     (map (lambda (x) (expand x r w mod)) fluid)
-                     (map (lambda (x) (expand x r w mod)) val)
-                     (expand-body (cons b b*) (source-wrap e w s mod) r w mod)))
-                 tmp)
-          (syntax-violation
-            #f
-            "source expression failed to match any pattern"
-            tmp-1)))))
   (global-extend 'begin 'begin '())
   (global-extend 'define 'define '())
   (global-extend 'define-syntax 'define-syntax '())
     'syntax-case
     (letrec*
       ((convert-pattern
-         (lambda (pattern keys)
+         (lambda (pattern keys ellipsis?)
            (letrec*
              ((cvt* (lambda (p* n ids)
-                      (if (not (pair? p*))
-                        (cvt p* n ids)
-                        (call-with-values
-                          (lambda () (cvt* (cdr p*) n ids))
-                          (lambda (y ids)
-                            (call-with-values
-                              (lambda () (cvt (car p*) n ids))
-                              (lambda (x ids) (values (cons x y) ids))))))))
+                      (let* ((tmp p*) (tmp ($sc-dispatch tmp '(any . any))))
+                        (if tmp
+                          (apply (lambda (x y)
+                                   (call-with-values
+                                     (lambda () (cvt* y n ids))
+                                     (lambda (y ids)
+                                       (call-with-values
+                                         (lambda () (cvt x n ids))
+                                         (lambda (x ids) (values (cons x y) ids))))))
+                                 tmp)
+                          (cvt p* n ids)))))
               (v-reverse
                 (lambda (x)
                   (let loop ((r '()) (x x))
        (gen-clause
          (lambda (x keys clauses r pat fender exp mod)
            (call-with-values
-             (lambda () (convert-pattern pat keys))
+             (lambda ()
+               (convert-pattern pat keys (lambda (e) (ellipsis? e r mod))))
              (lambda (p pvars)
-               (cond ((not (distinct-bound-ids? (map car pvars)))
-                      (syntax-violation 'syntax-case "duplicate pattern variable" pat))
-                     ((not (and-map (lambda (x) (not (ellipsis? (car x)))) pvars))
+               (cond ((not (and-map (lambda (x) (not (ellipsis? (car x) r mod))) pvars))
                       (syntax-violation 'syntax-case "misplaced ellipsis" pat))
+                     ((not (distinct-bound-ids? (map car pvars)))
+                      (syntax-violation 'syntax-case "duplicate pattern variable" pat))
                      (else
                       (let ((y (gen-var 'tmp)))
                         (build-call
                (tmp ($sc-dispatch tmp-1 '(_ any each-any . each-any))))
           (if tmp
             (apply (lambda (val key m)
-                     (if (and-map (lambda (x) (and (id? x) (not (ellipsis? x)))) key)
+                     (if (and-map (lambda (x) (and (id? x) (not (ellipsis? x r mod)))) key)
                        (let ((x (gen-var 'tmp)))
                          (build-call
                            s
          (let ((x id))
            (if (not (nonsymbol-id? x))
              (syntax-violation 'syntax-module "invalid argument" x)))
-         (cdr (syntax-object-module id))))
+         (let ((mod (syntax-object-module id)))
+           (and (not (equal? mod '(primitive))) (cdr mod)))))
      (syntax-local-binding
-       (lambda (id)
+       (lambda* (id
+                 #:key
+                 (resolve-syntax-parameters? #t #:resolve-syntax-parameters?))
          (let ((x id))
            (if (not (nonsymbol-id? x))
              (syntax-violation 'syntax-local-binding "invalid argument" x)))
                      (strip-anti-mark (syntax-object-wrap id))
                      r
                      (syntax-object-module id)
-                     #t))
+                     resolve-syntax-parameters?))
                  (lambda (type value mod)
                    (let ((key type))
                      (cond ((memv key '(lexical)) (values 'lexical value))
                            ((memv key '(macro)) (values 'macro value))
+                           ((memv key '(syntax-parameter))
+                            (values 'syntax-parameter (car value)))
                            ((memv key '(syntax)) (values 'pattern-variable value))
                            ((memv key '(displaced-lexical)) (values 'displaced-lexical #f))
-                           ((memv key '(global)) (values 'global (cons value (cdr mod))))
+                           ((memv key '(global))
+                            (if (equal? mod '(primitive))
+                              (values 'primitive value)
+                              (values 'global (cons value (cdr mod)))))
+                           ((memv key '(ellipsis))
+                            (values
+                              'ellipsis
+                              (make-syntax-object
+                                (syntax-object-expression value)
+                                (anti-mark (syntax-object-wrap value))
+                                (syntax-object-module value))))
                            (else (values 'other #f)))))))))))
      (syntax-locally-bound-identifiers
        (lambda (id)
                       "source expression failed to match any pattern"
                       tmp)))))))))))
 
-(define syntax-rules
+(define syntax-error
   (make-syntax-transformer
-    'syntax-rules
+    'syntax-error
     'macro
-    (lambda (xx)
-      (let ((tmp-1 xx))
-        (let ((tmp ($sc-dispatch tmp-1 '(_ each-any . #(each ((any . any) any))))))
-          (if tmp
-            (apply (lambda (k keyword pattern template)
-                     (list '#(syntax-object lambda ((top)) (hygiene guile))
-                           '(#(syntax-object x ((top)) (hygiene guile)))
-                           (vector
-                             '(#(syntax-object macro-type ((top)) (hygiene guile))
-                               .
-                               #(syntax-object
-                                 syntax-rules
-                                 ((top)
-                                  #(ribcage
-                                    #(syntax-rules)
-                                    #((top))
-                                    #(((hygiene guile)
-                                       .
-                                       #(syntax-object syntax-rules ((top)) (hygiene guile))))))
-                                 (hygiene guile)))
-                             (cons '#(syntax-object patterns ((top)) (hygiene guile)) pattern))
-                           (cons '#(syntax-object syntax-case ((top)) (hygiene guile))
-                                 (cons '#(syntax-object x ((top)) (hygiene guile))
-                                       (cons k
-                                             (map (lambda (tmp-1 tmp)
-                                                    (list (cons '#(syntax-object _ ((top)) (hygiene guile)) tmp)
-                                                          (list '#(syntax-object syntax ((top)) (hygiene guile))
-                                                                tmp-1)))
-                                                  template
-                                                  pattern))))))
+    (lambda (x)
+      (let ((tmp-1 x))
+        (let ((tmp ($sc-dispatch tmp-1 '(_ (any . any) any . each-any))))
+          (if (if tmp
+                (apply (lambda (keyword operands message arg)
+                         (string? (syntax->datum message)))
+                       tmp)
+                #f)
+            (apply (lambda (keyword operands message arg)
+                     (syntax-violation
+                       (syntax->datum keyword)
+                       (string-join
+                         (cons (syntax->datum message)
+                               (map (lambda (x) (object->string (syntax->datum x))) arg)))
+                       (if (syntax->datum keyword) (cons keyword operands) #f)))
                    tmp)
-            (let ((tmp ($sc-dispatch tmp-1 '(_ each-any any . #(each ((any . any) any))))))
+            (let ((tmp ($sc-dispatch tmp-1 '(_ any . each-any))))
               (if (if tmp
-                    (apply (lambda (k docstring keyword pattern template)
-                             (string? (syntax->datum docstring)))
-                           tmp)
+                    (apply (lambda (message arg) (string? (syntax->datum message))) tmp)
                     #f)
-                (apply (lambda (k docstring keyword pattern template)
-                         (list '#(syntax-object lambda ((top)) (hygiene guile))
-                               '(#(syntax-object x ((top)) (hygiene guile)))
-                               docstring
-                               (vector
-                                 '(#(syntax-object macro-type ((top)) (hygiene guile))
-                                   .
-                                   #(syntax-object
-                                     syntax-rules
-                                     ((top)
-                                      #(ribcage
-                                        #(syntax-rules)
-                                        #((top))
-                                        #(((hygiene guile)
-                                           .
-                                           #(syntax-object syntax-rules ((top)) (hygiene guile))))))
-                                     (hygiene guile)))
-                                 (cons '#(syntax-object patterns ((top)) (hygiene guile)) pattern))
-                               (cons '#(syntax-object syntax-case ((top)) (hygiene guile))
-                                     (cons '#(syntax-object x ((top)) (hygiene guile))
-                                           (cons k
-                                                 (map (lambda (tmp-1 tmp)
-                                                        (list (cons '#(syntax-object _ ((top)) (hygiene guile)) tmp)
-                                                              (list '#(syntax-object syntax ((top)) (hygiene guile))
-                                                                    tmp-1)))
-                                                      template
-                                                      pattern))))))
+                (apply (lambda (message arg)
+                         (cons '#(syntax-object
+                                  syntax-error
+                                  ((top)
+                                   #(ribcage
+                                     #(syntax-error)
+                                     #((top))
+                                     #(((hygiene guile)
+                                        .
+                                        #(syntax-object syntax-error ((top)) (hygiene guile))))))
+                                  (hygiene guile))
+                               (cons '(#f) (cons message arg))))
                        tmp)
                 (syntax-violation
                   #f
                   "source expression failed to match any pattern"
                   tmp-1)))))))))
 
+(define syntax-rules
+  (make-syntax-transformer
+    'syntax-rules
+    'macro
+    (lambda (xx)
+      (letrec*
+        ((expand-clause
+           (lambda (clause)
+             (let ((tmp-1 clause))
+               (let ((tmp ($sc-dispatch
+                            tmp-1
+                            '((any . any)
+                              (#(free-id #(syntax-object syntax-error ((top)) (hygiene guile)))
+                               any
+                               .
+                               each-any)))))
+                 (if (if tmp
+                       (apply (lambda (keyword pattern message arg)
+                                (string? (syntax->datum message)))
+                              tmp)
+                       #f)
+                   (apply (lambda (keyword pattern message arg)
+                            (list (cons '#(syntax-object dummy ((top)) (hygiene guile)) pattern)
+                                  (list '#(syntax-object syntax ((top)) (hygiene guile))
+                                        (cons '#(syntax-object syntax-error ((top)) (hygiene guile))
+                                              (cons (cons '#(syntax-object dummy ((top)) (hygiene guile)) pattern)
+                                                    (cons message arg))))))
+                          tmp)
+                   (let ((tmp ($sc-dispatch tmp-1 '((any . any) any))))
+                     (if tmp
+                       (apply (lambda (keyword pattern template)
+                                (list (cons '#(syntax-object dummy ((top)) (hygiene guile)) pattern)
+                                      (list '#(syntax-object syntax ((top)) (hygiene guile)) template)))
+                              tmp)
+                       (syntax-violation
+                         #f
+                         "source expression failed to match any pattern"
+                         tmp-1))))))))
+         (expand-syntax-rules
+           (lambda (dots keys docstrings clauses)
+             (let ((tmp-1 (list keys docstrings clauses (map expand-clause clauses))))
+               (let ((tmp ($sc-dispatch
+                            tmp-1
+                            '(each-any each-any #(each ((any . any) any)) each-any))))
+                 (if tmp
+                   (apply (lambda (k docstring keyword pattern template clause)
+                            (let ((tmp (cons '#(syntax-object lambda ((top)) (hygiene guile))
+                                             (cons '(#(syntax-object x ((top)) (hygiene guile)))
+                                                   (append
+                                                     docstring
+                                                     (list (vector
+                                                             '(#(syntax-object macro-type ((top)) (hygiene guile))
+                                                               .
+                                                               #(syntax-object
+                                                                 syntax-rules
+                                                                 ((top)
+                                                                  #(ribcage
+                                                                    #(syntax-rules)
+                                                                    #((top))
+                                                                    #(((hygiene guile)
+                                                                       .
+                                                                       #(syntax-object
+                                                                         syntax-rules
+                                                                         ((top))
+                                                                         (hygiene guile))))))
+                                                                 (hygiene guile)))
+                                                             (cons '#(syntax-object patterns ((top)) (hygiene guile))
+                                                                   pattern))
+                                                           (cons '#(syntax-object syntax-case ((top)) (hygiene guile))
+                                                                 (cons '#(syntax-object x ((top)) (hygiene guile))
+                                                                       (cons k clause)))))))))
+                              (let ((form tmp))
+                                (if dots
+                                  (let ((tmp dots))
+                                    (let ((dots tmp))
+                                      (list '#(syntax-object with-ellipsis ((top)) (hygiene guile))
+                                            dots
+                                            form)))
+                                  form))))
+                          tmp)
+                   (syntax-violation
+                     #f
+                     "source expression failed to match any pattern"
+                     tmp-1)))))))
+        (let ((tmp xx))
+          (let ((tmp-1 ($sc-dispatch tmp '(_ each-any . #(each ((any . any) any))))))
+            (if tmp-1
+              (apply (lambda (k keyword pattern template)
+                       (expand-syntax-rules
+                         #f
+                         k
+                         '()
+                         (map (lambda (tmp-2 tmp-1 tmp) (list (cons tmp tmp-1) tmp-2))
+                              template
+                              pattern
+                              keyword)))
+                     tmp-1)
+              (let ((tmp-1 ($sc-dispatch tmp '(_ each-any any . #(each ((any . any) any))))))
+                (if (if tmp-1
+                      (apply (lambda (k docstring keyword pattern template)
+                               (string? (syntax->datum docstring)))
+                             tmp-1)
+                      #f)
+                  (apply (lambda (k docstring keyword pattern template)
+                           (expand-syntax-rules
+                             #f
+                             k
+                             (list docstring)
+                             (map (lambda (tmp-2 tmp-1 tmp) (list (cons tmp tmp-1) tmp-2))
+                                  template
+                                  pattern
+                                  keyword)))
+                         tmp-1)
+                  (let ((tmp-1 ($sc-dispatch tmp '(_ any each-any . #(each ((any . any) any))))))
+                    (if (if tmp-1
+                          (apply (lambda (dots k keyword pattern template) (identifier? dots))
+                                 tmp-1)
+                          #f)
+                      (apply (lambda (dots k keyword pattern template)
+                               (expand-syntax-rules
+                                 dots
+                                 k
+                                 '()
+                                 (map (lambda (tmp-2 tmp-1 tmp) (list (cons tmp tmp-1) tmp-2))
+                                      template
+                                      pattern
+                                      keyword)))
+                             tmp-1)
+                      (let ((tmp-1 ($sc-dispatch tmp '(_ any each-any any . #(each ((any . any) any))))))
+                        (if (if tmp-1
+                              (apply (lambda (dots k docstring keyword pattern template)
+                                       (if (identifier? dots) (string? (syntax->datum docstring)) #f))
+                                     tmp-1)
+                              #f)
+                          (apply (lambda (dots k docstring keyword pattern template)
+                                   (expand-syntax-rules
+                                     dots
+                                     k
+                                     (list docstring)
+                                     (map (lambda (tmp-2 tmp-1 tmp) (list (cons tmp tmp-1) tmp-2))
+                                          template
+                                          pattern
+                                          keyword)))
+                                 tmp-1)
+                          (syntax-violation
+                            #f
+                            "source expression failed to match any pattern"
+                            tmp))))))))))))))
+
 (define define-syntax-rule
   (make-syntax-transformer
     'define-syntax-rule
     'macro
     (lambda (x)
       (letrec*
-        ((absolute-path? (lambda (path) (string-prefix? "/" path)))
-         (read-file
+        ((read-file
            (lambda (fn dir k)
-             (let ((p (open-input-file (if (absolute-path? fn) fn (in-vicinity dir fn)))))
-               (let f ((x (read p)) (result '()))
-                 (if (eof-object? x)
-                   (begin (close-input-port p) (reverse result))
-                   (f (read p) (cons (datum->syntax k x) result))))))))
+             (let ((p (open-input-file
+                        (if (absolute-file-name? fn)
+                          fn
+                          (if dir
+                            (in-vicinity dir fn)
+                            (syntax-violation
+                              'include
+                              "relative file name only allowed when the include form is in a file"
+                              x))))))
+               (let ((enc (file-encoding p)))
+                 (set-port-encoding! p (let ((t enc)) (if t t "UTF-8")))
+                 (let f ((x (read p)) (result '()))
+                   (if (eof-object? x)
+                     (begin (close-input-port p) (reverse result))
+                     (f (read p) (cons (datum->syntax k x) result)))))))))
         (let ((src (syntax-source x)))
           (let ((file (if src (assq-ref src 'filename) #f)))
             (let ((dir (if (string? file) (dirname file) #f)))