1.0.19.23: COMPILER-WARN accepts conditions
[sbcl/pkhuong.git] / src / code / defmacro.lisp
blob5bc4f4704d395178b38853e9a422713da476a08a
1 ;;;; DEFMACRO machinery
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.
12 (in-package "SB!IMPL")
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 `(eval-when (:compile-toplevel :load-toplevel :execute)
52 (sb!c::%defmacro ',name #',def ',lambda-list
53 ,doc ',debug-name)))))))
55 (macrolet
56 ((def (times set-p)
57 `(eval-when (,@times)
58 (defun sb!c::%defmacro (name definition lambda-list doc debug-name)
59 ;; old note (ca. 1985, maybe:-): "Eventually %%DEFMACRO
60 ;; should deal with clearing old compiler information for
61 ;; the functional value."
62 ,@(unless set-p
63 '((declare (ignore lambda-list debug-name))))
64 (ecase (info :function :kind name)
65 ((nil))
66 (:function
67 ;; (remhash name *free-funs*)
68 (undefine-fun-name name)
69 (style-warn
70 "~S is being redefined as a macro when it was ~
71 previously ~(~A~) to be a function."
72 name
73 (info :function :where-from name)))
74 (:macro)
75 (:special-form
76 (error "The special form ~S can't be redefined as a macro."
77 name)))
78 (clear-info :function :where-from name)
79 ;; FIXME: It would be nice to warn about DEFMACRO of an
80 ;; already-defined macro, but that's slightly hard to do
81 ;; because in common usage DEFMACRO is defined at compile
82 ;; time and then redefined at load time. We'd need to make a
83 ;; distinction between the defined-at-compile-time state and
84 ;; the defined-at-load-time state to make this work. (Trying
85 ;; to warn about duplicate DEFTYPEs runs into the same
86 ;; problem.)
87 #+nil (when (sb!xc:macro-function name)
88 ;; Someday we could check for macro arguments
89 ;; being incompatibly redefined. Doing this right
90 ;; will involve finding the old macro lambda-list
91 ;; and comparing it with the new one.
92 (style-warn "redefining ~S in DEFMACRO" name))
93 (setf (sb!xc:macro-function name) definition
94 (fdocumentation name 'function) doc)
95 ,(when set-p
96 `(case (widetag-of definition)
97 (#.sb!vm:closure-header-widetag
98 (setf (%simple-fun-arglist (%closure-fun definition))
99 lambda-list
100 (%simple-fun-name (%closure-fun definition))
101 debug-name))
102 (#.sb!vm:simple-fun-header-widetag
103 (setf (%simple-fun-arglist definition) lambda-list
104 (%simple-fun-name definition) debug-name))))
105 name))))
106 (progn
107 (def (:load-toplevel :execute) #-sb-xc-host t #+sb-xc-host nil)
108 (def (#-sb-xc :compile-toplevel) nil)))
110 ;;; Parse the definition and make an expander function. The actual
111 ;;; definition is done by %DEFMACRO which we expand into. After the
112 ;;; compiler has gotten the information it wants out of macro
113 ;;; definition, it compiles a call to %DEFMACRO which happens at load
114 ;;; time.
115 (defmacro sb!xc:defmacro (name lambda-list &rest body)
116 (%expander-for-defmacro name lambda-list body))
118 ;;; In the cross-compiler, we not only need to support the definition
119 ;;; of target macros at cross-compiler-build-time (with SB!XC:DEFMACRO
120 ;;; running in the cross-compilation host), we also need to support
121 ;;; the definition of target macros at target compilation time (with
122 ;;; CL:DEFMACRO processed by the cross-compiler)..
123 #+sb-xc-host
124 (sb!xc:defmacro defmacro (name lambda-list &rest body)
125 (%expander-for-defmacro name lambda-list body))
127 ;;; DEFMACRO-MUNDANELY is like SB!XC:DEFMACRO, except that it doesn't
128 ;;; have any EVAL-WHEN or IR1 magic associated with it, so it only
129 ;;; takes effect in :LOAD-TOPLEVEL or :EXECUTE situations.
130 (def!macro defmacro-mundanely (name lambda-list &body body)
132 ;; old way:
133 ;;(let ((whole (gensym "WHOLE-"))
134 ;; (environment (gensym "ENVIRONMENT-")))
135 ;; (multiple-value-bind (new-body local-decs doc)
136 ;; (parse-defmacro lambda-list whole body name 'defmacro
137 ;; :environment environment)
138 ;; `(progn
139 ;; (setf (sb!xc:macro-function ',name)
140 ;; (lambda (,whole ,environment)
141 ;; ,@local-decs
142 ;; (block ,name
143 ;; ,new-body)))
144 ;; (setf (fdocumentation ',name 'macro)
145 ;; ,doc)
146 ;; ',name)))
148 `(let ()
149 (sb!xc:defmacro ,name ,lambda-list ,@body)))