summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-07-07 07:52:09 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-07-07 07:52:09 -0700
commit00a1dfe7aa136bdb7aa3832da052d853261e05ad (patch)
tree271195498c545316b28153d9f1c05f6f1d842ed1 /eval.c
parente78c6b33e8664b69cb0daf85110e539f81380d11 (diff)
downloadtxr-00a1dfe7aa136bdb7aa3832da052d853261e05ad.tar.gz
txr-00a1dfe7aa136bdb7aa3832da052d853261e05ad.tar.bz2
txr-00a1dfe7aa136bdb7aa3832da052d853261e05ad.zip
expander: fix neglect to expand lambda and fun.
Now that lambda expressions are supported as function names in the first position of a compound expression and as an argument to the fun operator, it will greatly behoove us if we expand them properly. Then tests/012/quine.tl will pass. * eval.c (do_expand): Handle fun specially. If the argument is a lambda expression, then expand that and generate an expanded fun form, otherwise just yield form. When expanding function calls, check whether the first argument is a lambda and expand it.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/eval.c b/eval.c
index e2759186..0a6940eb 100644
--- a/eval.c
+++ b/eval.c
@@ -4182,7 +4182,14 @@ static val do_expand(val form, val menv)
if (body_ex == body)
return form;
return rlcp(cons(sym, cons(syms, body_ex)), form);
- } else if (sym == quote_s || sym == fun_s || sym == dvbind_s) {
+ } else if (sym == fun_s) {
+ val arg = second(form);
+ if (consp(arg) && car(arg) == lambda_s) {
+ val arg_ex = expand(arg, menv);
+ return rlcp(list(sym, arg_ex, nao), form);
+ }
+ return form;
+ } else if (sym == quote_s || sym == dvbind_s) {
return form;
} else if (sym == for_op_s) {
val vars = second(form);
@@ -4301,7 +4308,8 @@ static val do_expand(val form, val menv)
unwind-protect, return and other special forms whose arguments
are evaluated */
val form_ex = dot_to_apply(form, nil);
- val sym_ex = first(form_ex);
+ val insym = first(form_ex);
+ val insym_ex = insym;
val args = rest(form_ex);
val args_ex = expand_forms(args, menv);
@@ -4326,6 +4334,9 @@ static val do_expand(val form, val menv)
}
}
+ if (consp(insym) && car(insym) == lambda_s)
+ insym_ex = expand(insym, menv);
+
if (!lookup_fun(menv, sym) && !special_operator_p(sym)) {
if (!bindable(sym))
eval_warn(last_form_expanded,
@@ -4337,13 +4348,13 @@ static val do_expand(val form, val menv)
sym, nao);
}
- if (args_ex == args) {
+ if (insym_ex == insym && args_ex == args) {
if (form_ex == form)
return form;
return form_ex;
}
- return rlcp(cons(sym_ex, args_ex), form);
+ return rlcp(cons(insym_ex, args_ex), form);
}
abort();
}