Function: macroexpand
macroexpand is a function defined in eval.c.
Signature
(macroexpand FORM &optional ENVIRONMENT)
Documentation
Return result of expanding macros at top level of FORM.
If FORM is not a macro call, it is returned unchanged. Otherwise, the macro is expanded and the expansion is considered in place of FORM. When a non-macro-call results, it is returned.
The second optional arg ENVIRONMENT specifies an environment of macro definitions to shadow the loaded ones for use in file byte-compilation.
Probably introduced at or before Emacs version 24.3.
Aliases
cl-macroexpand (obsolete since 24.3)
Source Code
// Defined in /usr/src/emacs/src/eval.c
{
/* With cleanups from Hallvard Furuseth. */
register Lisp_Object expander, sym, def, tem;
while (1)
{
/* Come back here each time we expand a macro call,
in case it expands into another macro call. */
if (!CONSP (form))
break;
/* Set SYM, give DEF and TEM right values in case SYM is not a symbol. */
def = sym = XCAR (form);
tem = Qnil;
/* Trace symbols aliases to other symbols
until we get a symbol that is not an alias. */
while (SYMBOLP (def))
{
maybe_quit ();
sym = def;
tem = Fassq (sym, environment);
if (NILP (tem))
{
def = XSYMBOL (sym)->u.s.function;
if (!NILP (def))
continue;
}
break;
}
/* Right now TEM is the result from SYM in ENVIRONMENT,
and if TEM is nil then DEF is SYM's function definition. */
if (NILP (tem))
{
/* SYM is not mentioned in ENVIRONMENT.
Look at its function definition. */
def = Fautoload_do_load (def, sym, Qmacro);
if (!CONSP (def))
/* Not defined or definition not suitable. */
break;
if (!EQ (XCAR (def), Qmacro))
break;
else expander = XCDR (def);
}
else
{
expander = XCDR (tem);
if (NILP (expander))
break;
}
{
Lisp_Object newform = apply1 (expander, XCDR (form));
if (EQ (form, newform))
break;
else
form = newform;
}
}
return form;
}