From 5e89795f66750094ccac9d13a1f2001dde3d1226 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku <kaz@kylheku.com> Date: Sat, 15 Feb 2014 04:32:23 -0800 Subject: Bugfix: parameters of defun were not being treated by expander. They need to be since they can contain evaluable initforms for default arguments. Ditto with lambda; lambda parameters were being treated using expand_vars, which is not appropriate. * eval.c (expand_opt_params, expand_params): New static functions. (expand_vars): Bugfix: added some missing rlcp's to propagate line number info. (expand): Move lambda to separate case, and expand its params --- eval.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 8 deletions(-) (limited to 'eval.c') diff --git a/eval.c b/eval.c index 296558f3..14f561e9 100644 --- a/eval.c +++ b/eval.c @@ -329,6 +329,44 @@ twocol: car(ctx_form), nao); } +static val expand_opt_params(val params) +{ + if (atom(params)) { + return params; + } else { + val form = car(params); + if (atom(form) || !consp(cdr(form))) { /* sym, or no init form */ + val params_ex = expand_opt_params(cdr(params)); + if (params_ex == cdr(params)) + return params; + return rlcp(cons(form, params_ex), cdr(params)); + } else { /* has initform */ + val initform = car(cdr(form)); + val initform_ex = rlcp(expand(initform), initform); + val form_ex = rlcp(cons(car(form), cons(initform_ex, cdr(cdr(form)))), + form); + return rlcp(cons(form_ex, expand_opt_params(rest(params))), cdr(params)); + } + } +} + +static val expand_params(val params) +{ + if (atom(params)) { + return params; + } else if (car(params) == colon_k) { + val params_ex = expand_opt_params(cdr(params)); + if (params_ex == cdr(params)) + return params; + return rlcp(cons(colon_k, params_ex), cdr(params)); + } else { + val params_ex = expand_params(cdr(params)); + if (params_ex == cdr(params)) + return params; + return rlcp(cons(car(params), params_ex), cdr(params)); + } +} + val apply(val fun, val arglist, val ctx_form) { val arg[32], *p = arg; @@ -1494,17 +1532,17 @@ static val expand_vars(val vars) val rest_vars_ex = expand_vars(rest_vars); if (rest_vars == rest_vars_ex) return vars; - return cons(car(vars), rest_vars_ex); + return rlcp(cons(car(vars), rest_vars_ex), vars); } else { cons_bind (var, init, car(vars)); val rest_vars = rest(vars); - val init_ex = expand_forms(init); - val rest_vars_ex = expand_vars(rest_vars); + val init_ex = rlcp(expand_forms(init), init); + val rest_vars_ex = rlcp(expand_vars(rest_vars), rest_vars); if (init == init_ex && rest_vars == rest_vars_ex) return vars; - return cons(cons(var, init_ex), rest_vars_ex); + return rlcp(cons(cons(var, init_ex), rest_vars_ex), vars); } } @@ -1719,7 +1757,7 @@ val expand(val form) } else { val sym = car(form); - if (sym == let_s || sym == let_star_s || sym == lambda_s || + if (sym == let_s || sym == let_star_s || sym == each_s || sym == each_star_s || sym == collect_each_s || sym == collect_each_star_s || sym == append_each_s || sym == append_each_star_s) @@ -1753,15 +1791,25 @@ val expand(val form) if (init == init_ex) return form; return rlcp(cons(sym, cons(name, cons(init_ex, nil))), form); + } else if (sym == lambda_s) { + val params = second(form); + val body = rest(rest(form)); + val params_ex = expand_params(params); + val body_ex = expand_forms(body); + + if (body == body_ex && params == params_ex) + return form; + return rlcp(cons(sym, cons(params_ex, body_ex)), form); } else if (sym == defun_s) { val name = second(form); - val args = third(form); + val params = third(form); + val params_ex = expand_params(params); val body = rest(rest(rest(form))); val body_ex = expand_forms(body); - if (body == body_ex) + if (body == body_ex && params == params_ex) return form; - return rlcp(cons(sym, cons(name, cons(args, body_ex))), form); + return rlcp(cons(sym, cons(name, cons(params_ex, body_ex))), form); } else if (sym == set_s || sym == inc_s || sym == dec_s) { val place = second(form); val inc = third(form); -- cgit v1.2.3