summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-02-08 20:34:34 -0800
committerKaz Kylheku <kaz@kylheku.com>2024-02-08 20:34:34 -0800
commit82cfcfdd91fb1cd8356fd6aaa537d329ecc3b78f (patch)
treeead36810f728ba9a7c666fec22003751a537f069
parented5672b77f5a2980872eca073608cb7bde4587e4 (diff)
downloadtxr-82cfcfdd91fb1cd8356fd6aaa537d329ecc3b78f.tar.gz
txr-82cfcfdd91fb1cd8356fd6aaa537d329ecc3b78f.tar.bz2
txr-82cfcfdd91fb1cd8356fd6aaa537d329ecc3b78f.zip
compiler: inlined chain: simplify variadic lambdas.
The opip syntax often generates lambdas that have a trailing parameter and use [sys:apply ...]. This is wasteful in the second and subsequent argument positions of a chain, because we know that only a single value is coming from the previous function. We can pattern match these lambdas and convert the trailing argument to a single fixed parameter. * stdlib/compiler.tl (simplify-variadic-lambda): New function. (inline-chain-rec): Try to simplify every function through simplify-variadic-lambda. The leftmost function is treated in inline-chain, so these are all second and subsequent functions.
-rw-r--r--stdlib/compiler.tl17
1 files changed, 15 insertions, 2 deletions
diff --git a/stdlib/compiler.tl b/stdlib/compiler.tl
index 00dbd292..e722cf41 100644
--- a/stdlib/compiler.tl
+++ b/stdlib/compiler.tl
@@ -2303,12 +2303,25 @@
,*lm-body))
lm-expr)))))
+(defun simplify-variadic-lambda (form)
+ (if-match @(require (lambda @(and @params @(or @(end (@nil . @rest))
+ @rest))
+ [sys:apply . @args])
+ rest
+ (eq 1 (count rest (flatten args)))
+ (eq [args -1] rest))
+ form
+ ^(lambda (,*(butlastn 0 params) ,rest)
+ [call ,*(butlastn 1 args) ,rest])
+ form))
+
(defun inline-chain-rec (form arg)
(match-ecase form
((chain @fun)
- ^(call ,fun ,arg))
+ ^(call ,(simplify-variadic-lambda fun) ,arg))
((chain @fun . @rest)
- (inline-chain-rec ^(chain ,*rest) ^(call ,fun ,arg)))))
+ (inline-chain-rec ^(chain ,*rest)
+ ^(call ,(simplify-variadic-lambda fun) ,arg)))))
(defun can-inline-chain (form)
(let (yes)