Fix make-array transforms.
[sbcl.git] / src / code / defmacro.lisp
1 ;;;; DEFMACRO machinery
2
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
11
12 (in-package "SB!IMPL")
13
14 ;;; the guts of the DEFMACRO macro, pulled out into a separate
15 ;;; function in order to make it easier to express the common
16 ;;; bootstrap idiom
17 ;;;   CL:DEFMACRO SB!XC:DEFMACRO
18 ;;;   SB!XC:DEFMACRO CL:DEFMACRO
19 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
20   (defun %expander-for-defmacro (name lambda-list body)
21     (unless (symbolp name)
22       (error "The macro name ~S is not a symbol." name))
23     ;; When we are building the cross-compiler, we could be in a host
24     ;; lisp which implements CL macros (e.g. CL:AND) as special
25     ;; operators (while still providing a macroexpansion for
26     ;; compliance): therefore can't use the host's SPECIAL-OPERATOR-P
27     ;; as a discriminator, but that's OK because the set of forms the
28     ;; cross-compiler compiles is tightly controlled.  -- CSR,
29     ;; 2003-04-20
30     #-sb-xc-host
31     (when (special-operator-p name)
32       (error "The special operator ~S can't be redefined as a macro."
33              name))
34     (with-unique-names (whole environment)
35       (multiple-value-bind (new-body local-decs doc)
36           (parse-defmacro lambda-list whole body name 'defmacro
37                           :environment environment)
38         (let ((def `(#+sb-xc-host lambda
39                      ;; Use a named-lambda rather than a lambda so that
40                      ;; proper xref information can be stored. Use a
41                      ;; list-based name, since otherwise the compiler
42                      ;; will momentarily assume that it names a normal
43                      ;; function, and report spurious warnings about
44                      ;; redefinition a macro as a function, and then
45                      ;; vice versa.
46                      #-sb-xc-host named-lambda #-sb-xc-host (defmacro ,name)
47                      (,whole ,environment)
48                       ,@local-decs
49                       ,new-body))
50               (debug-name (sb!c::debug-name 'macro-function name)))
51           `(progn
52              (eval-when (:compile-toplevel :load-toplevel :execute)
53                (sb!c::%defmacro ',name #',def ',lambda-list ,doc ',debug-name
54                                 (sb!c:source-location)))))))))
55
56 (macrolet
57     ((def (times set-p)
58        `(eval-when (,@times)
59           (defun sb!c::%defmacro (name definition lambda-list doc debug-name
60                                   source-location)
61             ;; old note (ca. 1985, maybe:-): "Eventually %%DEFMACRO
62             ;; should deal with clearing old compiler information for
63             ;; the functional value."
64             ,@(unless set-p
65                 '((declare (ignore lambda-list debug-name doc))))
66             (let ((kind (info :function :kind name)))
67               ;; Check for special form before package locks.
68               (when (eq :special-form kind)
69                 (error "The special operator ~S can't be redefined as a macro."
70                        name))
71               (with-single-package-locked-error (:symbol name "defining ~S as a macro")
72                 (when (eq :function kind)
73                   (style-warn
74                    "~S is being redefined as a macro when it was ~
75                      previously ~(~A~) to be a function."
76                    name (info :function :where-from name))
77                   (undefine-fun-name name))
78                 (clear-info :function :where-from name)
79                 #-sb-xc-host
80                 (when (fboundp name)
81                   ;; Someday we could check for macro arguments
82                   ;; being incompatibly redefined. Doing this right
83                   ;; will involve finding the old macro lambda-list
84                   ;; and comparing it with the new one.
85                   (warn 'sb!kernel::redefinition-with-defmacro
86                         :name name
87                         :new-function definition
88                         :new-location source-location))
89                (setf (sb!xc:macro-function name) definition)
90                ,(when set-p
91                       `(setf (%fun-doc definition) doc
92                              (%fun-lambda-list definition) lambda-list
93                              (%fun-name definition) debug-name))))
94             name))))
95   (progn
96     (def (:load-toplevel :execute) #-sb-xc-host t #+sb-xc-host nil)
97     (def (#-sb-xc :compile-toplevel) nil)))
98
99 ;;; Parse the definition and make an expander function. The actual
100 ;;; definition is done by %DEFMACRO which we expand into. After the
101 ;;; compiler has gotten the information it wants out of macro
102 ;;; definition, it compiles a call to %DEFMACRO which happens at load
103 ;;; time.
104 (defmacro sb!xc:defmacro (name lambda-list &rest body)
105   (%expander-for-defmacro name lambda-list body))
106
107 ;;; In the cross-compiler, we not only need to support the definition
108 ;;; of target macros at cross-compiler-build-time (with SB!XC:DEFMACRO
109 ;;; running in the cross-compilation host), we also need to support
110 ;;; the definition of target macros at target compilation time (with
111 ;;; CL:DEFMACRO processed by the cross-compiler)..
112 #+sb-xc-host
113 (sb!xc:defmacro defmacro (name lambda-list &rest body)
114   (%expander-for-defmacro name lambda-list body))
115
116 ;;; DEFMACRO-MUNDANELY is like SB!XC:DEFMACRO, except that it doesn't
117 ;;; have any EVAL-WHEN or IR1 magic associated with it, so it only
118 ;;; takes effect in :LOAD-TOPLEVEL or :EXECUTE situations.
119 (def!macro defmacro-mundanely (name lambda-list &body body)
120
121   ;; old way:
122   ;;(let ((whole (gensym "WHOLE-"))
123   ;;      (environment (gensym "ENVIRONMENT-")))
124   ;;  (multiple-value-bind (new-body local-decs doc)
125   ;;      (parse-defmacro lambda-list whole body name 'defmacro
126   ;;                      :environment environment)
127   ;;    `(progn
128   ;;       (setf (sb!xc:macro-function ',name)
129   ;;             (lambda (,whole ,environment)
130   ;;                 ,@local-decs
131   ;;                 (block ,name
132   ;;                 ,new-body)))
133   ;;       (setf (fdocumentation ',name 'macro)
134   ;;             ,doc)
135   ;;       ',name)))
136
137   `(let ()
138      (sb!xc:defmacro ,name ,lambda-list ,@body)))