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
commit167d6231e3cb6a4be4c84c302bdc888163bc5d97 (patch)
tree48190d007b2a33eebfba5af224de46f87042b146
parent6dc9186c6afc5f8e7f4b3dee3d6cffa144555fdd (diff)
downloadtxr-167d6231e3cb6a4be4c84c302bdc888163bc5d97.tar.gz
txr-167d6231e3cb6a4be4c84c302bdc888163bc5d97.tar.bz2
txr-167d6231e3cb6a4be4c84c302bdc888163bc5d97.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));
}