From 00a1dfe7aa136bdb7aa3832da052d853261e05ad Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 7 Jul 2017 07:52:09 -0700 Subject: 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. --- eval.c | 19 +++++++++++++++---- 1 file 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(); } -- cgit v1.2.3