|
|
|
|
|
by kazinator
1850 days ago
|
|
TXR Lisp: 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. (defun early-peephole (code)
(rewrite-case insns code
(((mov (t @t1) (d @d1))
(jmp @lab2)
@(symbolp @lab1)
(mov (t @t1) (t 0))
@lab2
(ifq (t @t1) (t 0) @lab3)
. @rest)
^((mov (t ,t1) (d ,d1))
(jmp ,lab3)
,lab1
(mov (t ,t1) (t 0))
,lab2
,*rest))
(@else else)))
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. |
|
We can stick that data into the pattern matching syntax using the or operator:
Or put it into a variable: "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:
This code golfs moderately well: https://news.ycombinator.com/item?id=27227276