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