1> (defun rewrite (fun list)
(build
(while* list
(let ((nlist [fun list]))
(if (eq list nlist)
(if list (add (pop list)))
(set list nlist))))))
rewrite
2> (defmacro rewrite-case (sym list . cases)
^(rewrite (lambda (,sym)
(match-case ,sym
,*cases))
,list))
rewrite-case
3> (rewrite-case x '(foo bar * select * fox select * bravo)
((select * . @rest) ^(select _ . ,rest))
(@else else))
(foo bar * select _ fox select _ bravo)
rewrite-case and rewrite appear in the TXR Lisp internals; they are used in the compiler for scanning instruction sequences for patterns and rewriting them.
E.g. a function early-peephole looks for one particular four instruction pattern (six items, when the labels are included). Rewriting it to a different form helps it disappear later on.
This is much more general and powerful than a hack which just looks at successive pairs for an ad-hoc match. rewrite-case can have multiple clauses, of different lengths, and arbitrary matching complexity.
The original requirements should be addressed. The thing being matched is not just select, but actually any one of a set of symbols that appear in K.
We can stick that data into the pattern matching syntax using the or operator:
3> (rewrite-case x '(foo bar * select * fox where * bravo)
((@(or select distinct partition from where
group having order limit) * . @rest) ^(,(car x) _ . ,rest))
(@else else))
(foo bar * select _ fox where _ bravo)
Or put it into a variable:
4> (defvarl K '(select distinct partition from where group having order limit))
K
5> (rewrite-case x '(foo bar * select * fox where * bravo)
((@(member @sym K) * . @rest) ^(,sym _ . ,rest))
(@else else))
(foo bar * select _ fox where _ bravo)
"If an object sym which is a member of K is followed by * and some remaining material, replace that by sym, underscore and that remaining material."
Hash table:
6> (set K (hash-list '(select distinct partition from where group having order limit)))
#H(() (select select) (where where) (limit limit) (order order)
(having having) (distinct distinct) (partition partition) (group group)
(from from))
7> (rewrite-case x '(foo bar * select * fox where * bravo)
((@[K @sym] * . @rest) ^(,sym _ . ,rest))
(@else else))
(foo bar * select _ fox where _ bravo)
E.g. a function early-peephole looks for one particular four instruction pattern (six items, when the labels are included). Rewriting it to a different form helps it disappear later on.
This is much more general and powerful than a hack which just looks at successive pairs for an ad-hoc match. rewrite-case can have multiple clauses, of different lengths, and arbitrary matching complexity.