summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-08-31 22:39:55 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-08-31 22:39:55 -0700
commit154443d90f4991e052bafca372a61c0669d11b8c (patch)
tree96cfe0c7254dc46ccd475d64e4a7f8a24bf3de0a
parent20e77fc437b96e4ccaa39c99a3f846eb2efdb897 (diff)
downloadtxr-154443d90f4991e052bafca372a61c0669d11b8c.tar.gz
txr-154443d90f4991e052bafca372a61c0669d11b8c.tar.bz2
txr-154443d90f4991e052bafca372a61c0669d11b8c.zip
new: macroexpand-lisp1 and macroexpand-1-lisp1.
* eval.c (do_macroexpand_1, do_macroexpand): New static functions; take symbol macro lookup function poiner as argument. (macroexpand_1): Reimplemented as wrapper around do_macroexpand_1. (macroexpand): Reimplemented as wrapper around do_macroexpand. (macroexpand_1_lisp1, macroexpand_lisp1): New static functions. (eval_init): Registered intrinsics macroexpand-1-lisp1 and macroexpand-lisp1. * txr.1: Documented.
-rw-r--r--eval.c32
-rw-r--r--txr.139
2 files changed, 67 insertions, 4 deletions
diff --git a/eval.c b/eval.c
index 1aa56866..9977883d 100644
--- a/eval.c
+++ b/eval.c
@@ -4501,7 +4501,7 @@ val macro_form_p(val form, val menv)
return nil;
}
-static val macroexpand_1(val form, val menv)
+static val do_macroexpand_1(val form, val menv, val (*lookup)(val, val))
{
val macro;
@@ -4514,7 +4514,7 @@ static val macroexpand_1(val form, val menv)
return rlcp_tree(rlcp_tree(mac_expand, form), macro);
}
- if (bindable(form) && (macro = lookup_symac(menv, form))) {
+ if (bindable(form) && (macro = lookup(menv, form))) {
val mac_expand = cdr(macro);
if (mac_expand == form)
return form;
@@ -4524,16 +4524,36 @@ static val macroexpand_1(val form, val menv)
return form;
}
-static val macroexpand(val form, val menv)
+static val macroexpand_1(val form, val menv)
+{
+ return do_macroexpand_1(form, menv, lookup_symac);
+}
+
+static val macroexpand_1_lisp1(val form, val menv)
+{
+ return do_macroexpand_1(form, menv, lookup_symac_lisp1);
+}
+
+static val do_macroexpand(val form, val menv, val (*lookup_sm)(val, val))
{
for (;;) {
- val mac_expand = macroexpand_1(form, menv);
+ val mac_expand = do_macroexpand_1(form, menv, lookup_sm);
if (mac_expand == form)
return form;
form = mac_expand;
}
}
+static val macroexpand(val form, val menv)
+{
+ return do_macroexpand(form, menv, lookup_symac);
+}
+
+static val macroexpand_lisp1(val form, val menv)
+{
+ return do_macroexpand(form, menv, lookup_symac_lisp1);
+}
+
static val constantp_noex(val form)
{
if (consp(form)) {
@@ -5976,8 +5996,12 @@ void eval_init(void)
reg_fun(intern(lit("macro-form-p"), user_package), func_n2o(macro_form_p, 1));
reg_fun(intern(lit("macroexpand-1"), user_package),
func_n2o(macroexpand_1, 1));
+ reg_fun(intern(lit("macroexpand-1-lisp1"), user_package),
+ func_n2o(macroexpand_1_lisp1, 1));
reg_fun(intern(lit("macroexpand"), user_package),
func_n2o(macroexpand, 1));
+ reg_fun(intern(lit("macroexpand-lisp1"), user_package),
+ func_n2o(macroexpand_lisp1, 1));
reg_fun(intern(lit("expand-params"), system_package), func_n5(expand_params));
reg_fun(intern(lit("constantp"), user_package), func_n2o(constantp, 1));
reg_fun(intern(lit("make-env"), user_package), func_n3o(make_env_intrinsic, 0));
diff --git a/txr.1 b/txr.1
index 72ad9949..ed998606 100644
--- a/txr.1
+++ b/txr.1
@@ -30172,6 +30172,45 @@ and
.code a
respectively.
+.coNP Functions @ macroexpand-1-lisp1 and @ macroexpand-lisp1
+.synb
+.mets (macroexpand-1-lisp1 < obj <> [ env ])
+.mets (macroexpand-lisp1 < obj <> [ env ])
+.syne
+.desc
+The
+.code macroexpand-1-lisp1
+and
+.code macroexpand-lisp1
+functions closely resemble, respectively,
+.code macroexpand-1
+and
+.codn macroexpand .
+
+The argument and return value syntax and semantics is almost
+identical, except for one difference. These functions consider argument
+.meta obj
+to be syntax in a Lisp-1 evaluation context, such as any argument
+position of the
+.code dwim
+operator, or the equivalent DWIM Brackets notation.
+
+This makes a difference because in a Lisp-1 evaluation context, an
+inner function binding is able to shadow an outer symbol macro binding
+of the same name.
+
+The requirements about this language area are given in more
+detail in the description of the
+.code dwim
+operator.
+
+Note: the
+.code macroexpand-lisp1
+function is useful to the implementor of a macro whose semantics requires
+one or more argument forms to be treated in a Lisp-1 context, in situations
+when such a macro needs to itself expand the material, rather than merely
+insert it as-is into the output code template.
+
.coNP Functions @ lexical-var-p and @ lexical-fun-p
.synb
.mets (lexical-var-p < env << form )