0.7.9.65:
[sbcl.git] / src / code / macros.lisp
index adceea0..2574cac 100644 (file)
 \f
 ;;;; DEFINE-COMPILER-MACRO
 
-;;; FIXME: The logic here for handling compiler macros named (SETF
-;;; FOO) was added after the fork from SBCL, is not well tested, and
-;;; may conflict with subtleties of the ANSI standard. E.g. section
-;;; "3.2.2.1 Compiler Macros" says that creating a lexical binding for
-;;; a function name shadows a compiler macro, and it's not clear that
-;;; that works with this version. It should be tested.
 (defmacro-mundanely define-compiler-macro (name lambda-list &body body)
   #!+sb-doc
   "Define a compiler-macro for NAME."
+  (legal-fun-name-or-type-error name)
+  (when (consp name)
+    ;; It's fairly clear that the user intends the compiler macro to
+    ;; expand when he does (SETF (FOO ...) X). And that's even a
+    ;; useful and reasonable thing to want. Unfortunately,
+    ;; (SETF (FOO ...) X) macroexpands into (FUNCALL (SETF FOO) X ...),
+    ;; and it's not at all clear that it's valid to expand a FUNCALL form,
+    ;; and the ANSI standard doesn't seem to say anything else which
+    ;; would justify us expanding the compiler macro the way the user
+    ;; wants. So instead we rely on 3.2.2.1.3 "When Compiler Macros Are
+    ;; Used" which says they never have to be used, so by ignoring such
+    ;; macros we're erring on the safe side. But any user who does
+    ;; (DEFINE-COMPILER-MACRO (SETF FOO) ...) could easily be surprised
+    ;; by this way of complying with a rather screwy aspect of the ANSI
+    ;; spec, so at least we can warn him...
+    (sb!c::compiler-style-warn
+     "defining compiler macro of (SETF ...), which will not be expanded"))
   (let ((whole (gensym "WHOLE-"))
        (environment (gensym "ENV-")))
     (multiple-value-bind (body local-decs doc)
       (destructuring-bind (keyoid &rest forms) case
        (cond ((memq keyoid '(t otherwise))
               (if errorp
-                  (error 'simple-program-error
-                         :format-control
-                         "No default clause is allowed in ~S: ~S"
-                         :format-arguments (list name case))
+                  (progn
+                    ;; FIXME: this message could probably do with
+                    ;; some loving pretty-printer format controls.
+                    (style-warn "Treating bare ~A in ~A as introducing a normal-clause, not an otherwise-clause" keyoid name)
+                    (push keyoid keys)
+                    (push `((,test ,keyform-value ',keyoid) nil ,@forms)
+                          clauses))
                   (push `(t nil ,@forms) clauses)))
              ((and multi-p (listp keyoid))
               (setf keys (append keyoid keys))