Initial revision
[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 (file-comment
15   "$Header$")
16
17 ;;; the guts of the DEFMACRO macro, pulled out into a separate
18 ;;; function in order to make it easier to express the common 
19 ;;; bootstrap idiom
20 ;;;   CL:DEFMACRO SB!XC:DEFMACRO
21 ;;;   SB!XC:DEFMACRO CL:DEFMACRO
22 (eval-when (:compile-toplevel :load-toplevel :execute)
23   (defun %expander-for-defmacro (name lambda-list body)
24     (let ((whole (gensym "WHOLE-"))
25           (environment (gensym "ENV-")))
26       (multiple-value-bind (new-body local-decs doc)
27           (parse-defmacro lambda-list whole body name 'defmacro
28                           :environment environment)
29         (let ((def `(lambda (,whole ,environment)
30                       ,@local-decs
31                       (block ,name
32                         ,new-body))))
33           `(sb!c::%defmacro ',name #',def ',lambda-list ,doc))))))
34
35 ;;; Ordinarily this definition of SB!C:%DEFMACRO as an ordinary
36 ;;; function is not used: the parallel (but different) definition as
37 ;;; an IR1 transform takes precedence. However, this definition is
38 ;;; still useful in the target interpreter, and in the
39 ;;; cross-compilation host.
40 (defun sb!c::%defmacro (name definition lambda-list doc)
41   (try-to-rename-interpreted-function-as-macro definition name lambda-list)
42   (sb!c::%%defmacro name definition doc))
43
44 ;;; (called by SB!C::%DEFMACRO)
45 (eval-when (:compile-toplevel :load-toplevel :execute)
46   (defun sb!c::%%defmacro (name definition doc)
47     ;; Old note (ca. 1985, maybe:-): "Eventually %%DEFMACRO should deal with
48     ;; clearing old compiler information for the functional value."
49     (clear-info :function :where-from name)
50     ;; FIXME: It would be nice to warn about DEFMACRO of an
51     ;; already-defined macro, but that's slightly hard to do because
52     ;; in common usage DEFMACRO is defined at compile time and then
53     ;; redefined at load time. We'd need to make a distinction between
54     ;; the defined-at-compile-time state and the defined-at-load-time
55     ;; state to make this work. (Trying to warn about duplicate DEFTYPEs
56     ;; runs into the same problem.)
57     #+nil (when (sb!xc:macro-function name)
58             (style-warn "redefining ~S in DEFMACRO" name))
59     (setf (sb!xc:macro-function name) definition
60           (fdocumentation name 'function) doc)
61     name))
62
63 ;;; Parse the definition and make an expander function. The actual
64 ;;; definition is done by %DEFMACRO which we expand into, and which is
65 ;;; handled magically by an IR1 transform. After the compiler has
66 ;;; gotten the information it wants out of macro definition, it
67 ;;; compiles a call to %%DEFMACRO which happens at load time.
68 (defmacro sb!xc:defmacro (name lambda-list &rest body)
69   (%expander-for-defmacro name lambda-list body))
70
71 ;;; In the cross-compiler, we not only need to support the definition
72 ;;; of target macros at cross-compiler-build-time (with SB!XC:DEFMACRO
73 ;;; running in the cross-compilation host), we also need to support
74 ;;; the definition of target macros at target compilation time (with
75 ;;; CL:DEFMACRO processed by the cross-compiler)..
76 #+sb-xc-host
77 (sb!xc:defmacro defmacro (name lambda-list &rest body)
78   (%expander-for-defmacro name lambda-list body))
79
80 ;;; DEFMACRO-MUNDANELY is like SB!XC:DEFMACRO, except that it doesn't
81 ;;; have any EVAL-WHEN or IR1 magic associated with it, so it only
82 ;;; takes effect in :LOAD-TOPLEVEL or :EXECUTE situations.
83 ;;;
84 ;;; KLUDGE: Currently this is only used for various special
85 ;;; circumstances in bootstrapping, but it seems to me that it might
86 ;;; be a good basis for reimplementation of DEFMACRO in terms of
87 ;;; EVAL-WHEN, which might be easier to understand than the current
88 ;;; approach based on IR1 magic. -- WHN 19990811
89 (def!macro defmacro-mundanely (name lambda-list &body body)
90   `(setf (sb!xc:macro-function ',name)
91          ,(let ((whole (gensym "WHOLE-"))
92                 (environment (gensym "ENVIRONMENT-")))
93             (multiple-value-bind (new-body local-decs doc)
94                 (parse-defmacro lambda-list whole body name 'defmacro
95                                 :environment environment)
96               (declare (ignore doc))
97               `(lambda (,whole ,environment)
98                  ,@local-decs
99                  (block ,name
100                    ,new-body))))))