summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-04-18 07:04:29 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-04-18 07:04:29 -0700
commitcec66e0bf8148d846efe16c31b74041eea3bb16d (patch)
tree48190d007b2a33eebfba5af224de46f87042b146
parent34791cb5f9f0eb75d7e0ad6024e254e82daa923c (diff)
downloadtxr-cec66e0bf8148d846efe16c31b74041eea3bb16d.tar.gz
txr-cec66e0bf8148d846efe16c31b74041eea3bb16d.tar.bz2
txr-cec66e0bf8148d846efe16c31b74041eea3bb16d.zip
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.
-rw-r--r--eval.c15
1 files 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));
}