Eliminate style-warning about undefined type GLOBAL-VAR
[sbcl.git] / src / code / macroexpand.lisp
blob10b010c0c753bfab1acd387db988910ef738bc0a
1 ;;;; MACROEXPAND and friends
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 ;;;; syntactic environment access
16 (defun sb!xc:special-operator-p (symbol)
17 #!+sb-doc
18 "If the symbol globally names a special form, return T, otherwise NIL."
19 (declare (symbol symbol))
20 (eq (info :function :kind symbol) :special-form))
22 (defvar sb!xc:*macroexpand-hook* 'funcall
23 #!+sb-doc
24 "The value of this variable must be a designator for a function that can
25 take three arguments, a macro expander function, the macro form to be
26 expanded, and the lexical environment to expand in. The function should
27 return the expanded form. This function is called by MACROEXPAND-1
28 whenever a runtime expansion is needed. Initially this is set to
29 FUNCALL.")
31 (defun sb!xc:macroexpand-1 (form &optional env)
32 #!+sb-doc
33 "If form is a macro (or symbol macro), expand it once. Return two values,
34 the expanded form and a T-or-NIL flag indicating whether the form was, in
35 fact, a macro. ENV is the lexical environment to expand in, which defaults
36 to the null environment."
37 (flet ((perform-expansion (expander)
38 ;; I disagree that expanders need to receive a "proper" environment
39 ;; - whatever that is - in lieu of NIL because an environment is
40 ;; opaque, and the only thing an expander can do with it (per the
41 ;; CL standard, barring things that code-walkers might want)
42 ;; is recursively invoke macroexpand[-1] or one of the handful of
43 ;; other builtins (9 or so) accepting an environment.
44 ;; Those functions all must in turn accept NIL as an environment.
45 ;; Whether or not this is put back to the way it was in CMUCL, it's
46 ;; good to have a single entry point for macros and symbol-macros.
47 (values (funcall sb!xc:*macroexpand-hook*
48 expander
49 form
50 ;; As far as I can tell, it's not clear from
51 ;; the ANSI spec whether a MACRO-FUNCTION
52 ;; function needs to be prepared to handle
53 ;; NIL as a lexical environment. CMU CL
54 ;; passed NIL through to the MACRO-FUNCTION
55 ;; function, but I prefer SBCL "be conservative
56 ;; in what it sends and liberal in what it
57 ;; accepts" by doing the defaulting itself.
58 ;; -- WHN 19991128
59 (coerce-to-lexenv env))
60 t)))
61 (cond ((consp form)
62 (let ((expander (and (symbolp (car form))
63 (sb!xc:macro-function (car form) env))))
64 (if expander
65 (perform-expansion expander)
66 (values form nil))))
67 ((symbolp form)
68 (multiple-value-bind (expansion winp)
69 (let* ((venv (when env (sb!c::lexenv-vars env)))
70 (local-def (cdr (assoc form venv))))
71 (cond ((not local-def)
72 (info :variable :macro-expansion form))
73 ((and (consp local-def) (eq (car local-def) 'macro))
74 (values (cdr local-def) t))))
75 (if winp
76 ;; CLHS 3.1.2.1.1 specifies that symbol-macros are expanded
77 ;; via the macroexpand hook, too.
78 (perform-expansion (lambda (form env)
79 (declare (ignore form env))
80 expansion))
81 (values form nil))))
83 (values form nil)))))
85 (defun sb!xc:macroexpand (form &optional env)
86 #!+sb-doc
87 "Repetitively call MACROEXPAND-1 until the form can no longer be expanded.
88 Returns the final resultant form, and T if it was expanded. ENV is the
89 lexical environment to expand in, or NIL (the default) for the null
90 environment."
91 (labels ((frob (form expanded)
92 (multiple-value-bind (new-form newly-expanded-p)
93 (sb!xc:macroexpand-1 form env)
94 (if newly-expanded-p
95 (frob new-form t)
96 (values new-form expanded)))))
97 (frob form nil)))
99 ;;; Like MACROEXPAND-1, but takes care not to expand special forms.
100 (defun %macroexpand-1 (form &optional env)
101 (if (or (atom form)
102 (let ((op (car form)))
103 (not (and (symbolp op) (sb!xc:special-operator-p op)))))
104 (sb!xc:macroexpand-1 form env)
105 (values form nil)))
107 ;;; Like MACROEXPAND, but takes care not to expand special forms.
108 (defun %macroexpand (form &optional env)
109 (labels ((frob (form expanded)
110 (multiple-value-bind (new-form newly-expanded-p)
111 (%macroexpand-1 form env)
112 (if newly-expanded-p
113 (frob new-form t)
114 (values new-form expanded)))))
115 (frob form nil)))