summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-01-29 21:59:23 -0800
committerKaz Kylheku <kaz@kylheku.com>2021-01-29 21:59:23 -0800
commit1be771848455687da7a3a96a159f75a6a5bde9f1 (patch)
tree9e9cf4d206a70b74237da98b6485de45ef2c6da8 /share
parent58c1642901889829eb55ceea2ae868dea848eab9 (diff)
downloadtxr-1be771848455687da7a3a96a159f75a6a5bde9f1.tar.gz
txr-1be771848455687da7a3a96a159f75a6a5bde9f1.tar.bz2
txr-1be771848455687da7a3a96a159f75a6a5bde9f1.zip
matcher: prune @nil in cons and vector matches.
Elimination of unused temporaries is really the job of the compiler, but we can do some simple things to get better code from the matcher in the meanwhile. In list and vector matches, @nil gets used just for placeholding. We can avoid generating the code which binds the corresponding value to an unused gensym. share/txr/stdlib/match.tl (compile-var-match): When the variable is nil, then do not generate a match-guard with empty content. Just generate an empty guard-chain. The higher level compiler can then check for this empty guard chain and prune its own material away. (compile-vec-match, compile-cons-structure): Eliminate every gensym and its initializing expression, whose corresponding compiled sub-match has an empty guard chain.
Diffstat (limited to 'share')
-rw-r--r--share/txr/stdlib/match.tl28
1 files changed, 19 insertions, 9 deletions
diff --git a/share/txr/stdlib/match.tl b/share/txr/stdlib/match.tl
index 8c7a4fcf..8518d68f 100644
--- a/share/txr/stdlib/match.tl
+++ b/share/txr/stdlib/match.tl
@@ -179,9 +179,9 @@
(new compiled-match
pattern sym
obj-var obj-var
- guard-chain (list (new match-guard
- vars (if sym (list sym))
- var-exprs (if sym (list obj-var))))))
+ guard-chain (if sym (list (new match-guard
+ vars (list sym)
+ var-exprs (list obj-var))))))
(t (new compiled-match
pattern sym
obj-var obj-var
@@ -190,12 +190,16 @@
(defun compile-vec-match (vec-pat obj-var var-list)
(let* ((elem-gensyms (mapcar (op gensym `elem-@1-`) (range* 0 (len vec-pat))))
+ (elem-exprs (mapcar (ret ^[,obj-var ,@1]) (range* 0 (len vec-pat))))
(elem-matches (list-vec [mapcar (lop compile-match var-list)
- vec-pat elem-gensyms]))
+ vec-pat elem-gensyms]))
+ (pruned-triple (multi (op keep-if .guard-chain @1 third)
+ elem-gensyms
+ elem-exprs
+ elem-matches))
(guard (new match-guard
- pure-temps elem-gensyms
- pure-temp-exprs (mapcar (ret ^[,obj-var ,@1])
- (range* 0 (len vec-pat)))
+ pure-temps (first pruned-triple)
+ pure-temp-exprs (second pruned-triple)
guard-expr ^(and (vectorp ,obj-var)
(eql (len ,obj-var) ,(len vec-pat))))))
(new compiled-match
@@ -283,8 +287,14 @@
(t (compile-cons-structure cdr cdr-gensym var-list)))
(compile-atom-match cdr cdr-gensym var-list)))
(guard (new match-guard
- pure-temps ^(,car-gensym ,cdr-gensym)
- pure-temp-exprs ^((car ,obj-var) (cdr ,obj-var))
+ pure-temps (append (if car-match.guard-chain
+ (list car-gensym))
+ (if cdr-match.guard-chain
+ (list cdr-gensym)))
+ pure-temp-exprs (append (if car-match.guard-chain
+ ^((car ,obj-var)))
+ (if cdr-match.guard-chain
+ ^((cdr ,obj-var))))
guard-expr ^(consp ,obj-var))))
(new compiled-match
pattern cons-pat