5
Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya.
6
Copyright (c) 1990, Giuseppe Attardi.
7
Copyright (c) 2001, Juan Jose Garcia Ripoll.
9
ECL is free software; you can redistribute it and/or
10
modify it under the terms of the GNU Library General Public
11
License as published by the Free Software Foundation; either
12
version 2 of the License, or (at your option) any later version.
14
See file '../Copyright' for full details.
18
#include <ecl/internal.h>
20
/******************************* REQUIRES ******************************/
22
/* Requires expand-defmacro, from lsp/defmacro.lsp */
24
/******************************* ------- ******************************/
27
MACRO_DEF is an internal function which, given a form, returns
28
the expansion function if the form is a macro form. Otherwise,
29
MACRO_DEF returns NIL.
32
search_symbol_macro(cl_object name, cl_object env)
34
cl_object record = assq(name, CAR(env));
36
return si_get_sysprop(name, @'si::symbol-macro');
37
else if (CADR(record) == @'si::symbol-macro')
44
search_macro(cl_object name, cl_object env)
46
cl_object record = assq(name, CDR(env));
47
if (CONSP(record) && CADR(record) == @'si::macro')
53
macro_def(cl_object form, cl_object env)
60
/* First look for SYMBOL-MACROLET definitions */
61
fd = search_symbol_macro(form, env);
67
fd = search_macro(head, env);
70
else if (head->symbol.mflag)
71
return(SYM_FUN(head));
76
@(defun macroexpand (form &optional (env Cnil))
77
cl_object new_form = OBJNULL;
78
cl_object done = Cnil;
80
new_form = macro_expand1(form, env);
81
while (new_form != form) {
84
new_form = macro_expand(form, env);
86
@(return new_form done)
89
@(defun macroexpand_1 (form &optional (env Cnil))
92
new_form = macro_expand1(form, env);
93
@(return new_form (new_form == form? Cnil : Ct))
97
MACRO_EXPAND1 is an internal function which simply applies the
98
function EXP_FUN to FORM. On return, the expanded form is stored
102
macro_expand1(cl_object form, cl_object env)
104
cl_object hook, exp_fun;
106
exp_fun = macro_def(form, env);
109
hook = symbol_value(@'*macroexpand-hook*');
110
if (hook == @'funcall')
111
return funcall(3, exp_fun, form, env);
113
return funcall(4, hook, exp_fun, form, env);
117
MACRO_EXPAND expands a form as many times as possible and returns
118
the finally expanded form.
121
macro_expand(cl_object form, cl_object env)
125
for (new_form = OBJNULL; new_form != form; form = new_form) {
126
new_form = macro_expand1(form, env);
132
or_macro(cl_object whole, cl_object env)
134
cl_object output = Cnil;
136
if (Null(whole)) /* (OR) => NIL */
138
while (!Null(CDR(whole))) {
139
output = CONS(CONS(CAR(whole), Cnil), output);
142
if (Null(output)) /* (OR form1) => form1 */
143
@(return CAR(whole));
144
/* (OR form1 ... formn forml) => (COND (form1) ... (formn) (t forml)) */
145
output = CONS(cl_list(2, Ct, CAR(whole)), output);
146
@(return CONS(@'cond', cl_nreverse(output)))
150
expand_and(cl_object whole)
154
if (Null(CDR(whole)))
156
return cl_list(3, @'if', CAR(whole), expand_and(CDR(whole)));
160
and_macro(cl_object whole, cl_object env)
162
@(return expand_and(CDR(whole)))
166
when_macro(cl_object whole, cl_object env)
168
cl_object args = CDR(whole);
170
FEprogram_error("Syntax error: ~S.", 1, whole);
171
return cl_list(3, @'if', CAR(args), CONS(@'progn', CDR(args)));
177
ECL_SET(@'*macroexpand-hook*', @'funcall');
178
cl_def_c_macro(@'or', or_macro, 2);
179
cl_def_c_macro(@'and', and_macro, 2);
180
cl_def_c_macro(@'when', when_macro, 2);