1 ;;;; MACROEXPAND and friends
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")
17 ;;;; syntactic environment access
19 (defun sb!xc:special-operator-p (symbol)
21 "If the symbol globally names a special form, returns T, otherwise NIL."
22 (declare (symbol symbol))
23 (eq (info :function :kind symbol) :special-form))
25 (defvar sb!xc:*macroexpand-hook* 'funcall
27 "The value of this variable must be a designator for a function that can
28 take three arguments, a macro expander function, the macro form to be
29 expanded, and the lexical environment to expand in. The function should
30 return the expanded form. This function is called by MACROEXPAND-1
31 whenever a runtime expansion is needed. Initially this is set to
34 (declaim (ftype (function (t &optional (or null sb!c::lexenv))) sb!xc:macroexpand-1))
35 (defun sb!xc:macroexpand-1 (form &optional env)
37 "If form is a macro (or symbol macro), expands it once. Returns two values,
38 the expanded form and a T-or-NIL flag indicating whether the form was, in
39 fact, a macro. Env is the lexical environment to expand in, which defaults
40 to the null environment."
41 (cond ((and (consp form) (symbolp (car form)))
42 (let ((def (sb!xc:macro-function (car form) env)))
44 (values (funcall sb!xc:*macroexpand-hook*
47 ;; As far as I can tell, it's not clear from
48 ;; the ANSI spec whether a MACRO-FUNCTION
49 ;; function needs to be prepared to handle
50 ;; NIL as a lexical environment. CMU CL
51 ;; passed NIL through to the MACRO-FUNCTION
52 ;; function, but I prefer SBCL "be conservative
53 ;; in what it sends and liberal in what it
54 ;; accepts" by doing the defaulting itself.
56 (or env (make-null-lexenv)))
60 (let* ((venv (when env (sb!c::lexenv-variables env)))
61 (local-def (cdr (assoc form venv))))
62 (if (and (consp local-def)
63 (eq (car local-def) 'macro))
64 (values (cdr local-def) t)
69 (declaim (ftype (function (t &optional (or null sb!c::lexenv))) sb!xc:macroexpand))
70 (defun sb!xc:macroexpand (form &optional env)
72 "Repetitively call MACROEXPAND-1 until the form can no longer be expanded.
73 Returns the final resultant form, and T if it was expanded. ENV is the
74 lexical environment to expand in, or NIL (the default) for the null
76 (labels ((frob (form expanded)
77 (multiple-value-bind (new-form newly-expanded-p)
78 (sb!xc:macroexpand-1 form env)
81 (values new-form expanded)))))