1 ;;;; DEFMACRO machinery
3 ;;;; This software is part of the SBCL system. See the README file for
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
17 ;;; CL:DEFMACRO SB!XC:DEFMACRO
18 ;;; SB!XC:DEFMACRO CL:DEFMACRO
19 (eval-when (: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 (special-operator-p name
)
24 (error "The special operator ~S can't be redefined as a macro."
26 (let ((whole (gensym "WHOLE-"))
27 (environment (gensym "ENV-")))
28 (multiple-value-bind (new-body local-decs doc
)
29 (parse-defmacro lambda-list whole body name
'defmacro
30 :environment environment
)
31 (let ((def `(lambda (,whole
,environment
)
35 ;; if we want to move over to list-style names
36 ;; [e.g. (DEFMACRO FOO), maybe to support some XREF-like
37 ;; functionality] here might be a good place to start.
38 (debug-name (debug-namify "DEFMACRO ~S" name
)))
39 `(eval-when (:compile-toplevel
:load-toplevel
:execute
)
40 (sb!c
::%defmacro
',name
#',def
',lambda-list
,doc
,debug-name
)))))))
45 (defun sb!c
::%defmacro
(name definition lambda-list doc debug-name
)
46 ;; old note (ca. 1985, maybe:-): "Eventually %%DEFMACRO
47 ;; should deal with clearing old compiler information for
48 ;; the functional value."
50 '((declare (ignore lambda-list debug-name
))))
51 (ecase (info :function
:kind name
)
54 ;; (remhash name *free-funs*)
55 (undefine-fun-name name
)
57 "~S is being redefined as a macro when it was ~
58 previously ~(~A~) to be a function."
60 (info :function
:where-from name
)))
63 (error "The special form ~S can't be redefined as a macro."
65 (clear-info :function
:where-from name
)
66 ;; FIXME: It would be nice to warn about DEFMACRO of an
67 ;; already-defined macro, but that's slightly hard to do
68 ;; because in common usage DEFMACRO is defined at compile
69 ;; time and then redefined at load time. We'd need to make a
70 ;; distinction between the defined-at-compile-time state and
71 ;; the defined-at-load-time state to make this work. (Trying
72 ;; to warn about duplicate DEFTYPEs runs into the same
74 #+nil
(when (sb!xc
:macro-function name
)
75 ;; Someday we could check for macro arguments
76 ;; being incompatibly redefined. Doing this right
77 ;; will involve finding the old macro lambda-list
78 ;; and comparing it with the new one.
79 (style-warn "redefining ~S in DEFMACRO" name
))
80 (setf (sb!xc
:macro-function name
) definition
81 (fdocumentation name
'function
) doc
)
83 `(case (widetag-of definition
)
84 (#.sb
!vm
:closure-header-widetag
85 (setf (%simple-fun-arglist
(%closure-fun definition
))
87 (%simple-fun-name
(%closure-fun definition
))
89 ((#.sb
!vm
:simple-fun-header-widetag
90 #.sb
!vm
:closure-fun-header-widetag
)
91 (setf (%simple-fun-arglist definition
) lambda-list
92 (%simple-fun-name definition
) debug-name
))))
95 (def (:load-toplevel
:execute
) #-sb-xc-host t
#+sb-xc-host nil
)
96 (def (:compile-toplevel
) nil
)))
98 ;;; Parse the definition and make an expander function. The actual
99 ;;; definition is done by %DEFMACRO which we expand into. After the
100 ;;; compiler has gotten the information it wants out of macro
101 ;;; definition, it compiles a call to %DEFMACRO which happens at load
103 (defmacro sb
!xc
:defmacro
(name lambda-list
&rest body
)
104 (%expander-for-defmacro name lambda-list body
))
106 ;;; In the cross-compiler, we not only need to support the definition
107 ;;; of target macros at cross-compiler-build-time (with SB!XC:DEFMACRO
108 ;;; running in the cross-compilation host), we also need to support
109 ;;; the definition of target macros at target compilation time (with
110 ;;; CL:DEFMACRO processed by the cross-compiler)..
112 (sb!xc
:defmacro defmacro
(name lambda-list
&rest body
)
113 (%expander-for-defmacro name lambda-list body
))
115 ;;; DEFMACRO-MUNDANELY is like SB!XC:DEFMACRO, except that it doesn't
116 ;;; have any EVAL-WHEN or IR1 magic associated with it, so it only
117 ;;; takes effect in :LOAD-TOPLEVEL or :EXECUTE situations.
118 (def!macro defmacro-mundanely
(name lambda-list
&body body
)
121 ;;(let ((whole (gensym "WHOLE-"))
122 ;; (environment (gensym "ENVIRONMENT-")))
123 ;; (multiple-value-bind (new-body local-decs doc)
124 ;; (parse-defmacro lambda-list whole body name 'defmacro
125 ;; :environment environment)
127 ;; (setf (sb!xc:macro-function ',name)
128 ;; (lambda (,whole ,environment)
132 ;; (setf (fdocumentation ',name 'macro)
137 (sb!xc
:defmacro
,name
,lambda-list
,@body
)))