diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-07-07 07:52:09 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-07-07 07:52:09 -0700 |
commit | 00a1dfe7aa136bdb7aa3832da052d853261e05ad (patch) | |
tree | 271195498c545316b28153d9f1c05f6f1d842ed1 /eval.c | |
parent | e78c6b33e8664b69cb0daf85110e539f81380d11 (diff) | |
download | txr-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.c | 19 |
1 files changed, 15 insertions, 4 deletions
@@ -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(); } |