summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-02-18 07:56:33 -0800
committerKaz Kylheku <kaz@kylheku.com>2021-02-18 07:56:33 -0800
commitd460fe76189c477d2fca48477fc26612148c469f (patch)
treee732252c5cb70efbf020118828c3aed19b3594c9 /share
parente164d0cfe329ddc8aceea393f10279bcb7c95b49 (diff)
downloadtxr-d460fe76189c477d2fca48477fc26612148c469f.tar.gz
txr-d460fe76189c477d2fca48477fc26612148c469f.tar.bz2
txr-d460fe76189c477d2fca48477fc26612148c469f.zip
compiler: use fixed-point macro for reduce-lisp.
* share/txr/stdlib/compiler.tl (fixed-point): New macro. (reduce-lisp): Hide irrelevant iteration details by using fixed-point macro.
Diffstat (limited to 'share')
-rw-r--r--share/txr/stdlib/compiler.tl59
1 files changed, 32 insertions, 27 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index ebc2bda3..cd602573 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -1468,34 +1468,39 @@
(defun simplify-or (form)
(reduce-or (flatten-or form)))
+(defmacro fixed-point (eqfn sym exp)
+ (with-gensyms (osym)
+ ^(let (,osym)
+ (while* (not (,eqfn ,osym ,sym))
+ (set ,osym ,sym
+ ,sym ,exp))
+ ,sym)))
+
(defun reduce-lisp (form)
- (let (oform)
- (while* (nequal oform form)
- (set oform form
- form (match-case form
- ((append (list . @largs) . @aargs)
- ^(list* ,*largs (append ,*aargs)))
- ((@(or append list*) @arg) arg)
- (@(require (list* . @(listp @args))
- (equal '(nil) (last args)))
- ^(list ,*(butlastn 1 args)))
- (@(with (list* . @(listp @args))
- ((@(and @op @(or list list*)) . @largs)) (last args))
- ^(,op ,*(butlast args) ,*largs))
- (@(with (list* . @(listp @args))
- ((append . @aargs)) (last args))
- ^(list* ,*(butlast args) ,(reduce-lisp ^(append ,*aargs))))
- ((@(or append list list*)) nil)
- ((cons @a @b)
- (let* ((lstar ^(list* ,a ,b))
- (rstar (reduce-lisp lstar)))
- (if (eq lstar rstar) form rstar)))
- ((cons @a (cons @b @c))
- ^(list* ,a ,b ,c))
- ((cons @a (@(and @op @(or list list*)) . @args))
- ^(,op ,a ,*args))
- (@else else))))
- form))
+ (fixed-point equal form
+ (match-case form
+ ((append (list . @largs) . @aargs)
+ ^(list* ,*largs (append ,*aargs)))
+ ((@(or append list*) @arg) arg)
+ (@(require (list* . @(listp @args))
+ (equal '(nil) (last args)))
+ ^(list ,*(butlastn 1 args)))
+ (@(with (list* . @(listp @args))
+ ((@(and @op @(or list list*)) . @largs)) (last args))
+ ^(,op ,*(butlast args) ,*largs))
+ (@(with (list* . @(listp @args))
+ ((append . @aargs)) (last args))
+ ^(list* ,*(butlast args) ,(reduce-lisp ^(append ,*aargs))))
+ ((@(or append list list*)) nil)
+ ((cons @a @b)
+ (let* ((lstar ^(list* ,a ,b))
+ (rstar (reduce-lisp lstar)))
+ (if (eq lstar rstar) form rstar)))
+ ((cons @a (cons @b @c))
+ ^(list* ,a ,b ,c))
+ ((cons @a (@(and @op @(or list list*)) . @args))
+ ^(,op ,a ,*args))
+ (@else else))))
(defun expand-quasi-mods (obj mods : form)
(let (plist num sep rng-ix scalar-ix-p flex gens)