From 167d6231e3cb6a4be4c84c302bdc888163bc5d97 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 18 Apr 2018 07:04:29 -0700 Subject: dot-to-apply: optimize out call function. When a dotted form like (call x ... . z) is subject to the dot-to-apply transformation, this results in (apply (fun call) x ... . z). The (fun call) is useless and can be removed. Therefore, what we do is remove occurrences of call from the original form. * eval.c (dot_to_apply): Remove leading occurrences of call. Since this promotes the second or subsequent form into the operator position, we must be careful; if we are doing a Lisp-2 form, only the first element requires wrapping in (fun ...) when turned into an apply argument. The second and subsequent arguments are subject to ordinary evaluation and so if any of those becomes the operator, it doesn't need (fun ...) wrapping. --- eval.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/eval.c b/eval.c index 610c9b40..72f98210 100644 --- a/eval.c +++ b/eval.c @@ -3093,10 +3093,17 @@ static val dot_to_apply(val form, val lisp1_p) } if (args) { - val sym = car(form); - return cons(sys_apply_s, cons(if3(lisp1_p, - sym, - list(fun_s, sym, nao)), + val fun = car(form); + val nofun = nil; + + while (fun == call_s) { + fun = car(args); + nofun = t; + pop(&args); + } + return cons(sys_apply_s, cons(if3(lisp1_p || nofun, + fun, + list(fun_s, fun, nao)), args)); } -- cgit v1.2.3