summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-01-28 06:51:26 -0800
committerKaz Kylheku <kaz@kylheku.com>2021-01-28 06:51:26 -0800
commit83d294fe8651643b7064dfea1402e24629853452 (patch)
treee930033012fef8d6531d36782844c016fd5843eb /share
parent600ec3af3f742f361164aac53cda6b02b90e5173 (diff)
downloadtxr-83d294fe8651643b7064dfea1402e24629853452.tar.gz
txr-83d294fe8651643b7064dfea1402e24629853452.tar.bz2
txr-83d294fe8651643b7064dfea1402e24629853452.zip
compiler: bug: append-each mutates lists.
* share/txr/stdlib/compiler.tl (expand-each): The algorithm for appending is completely wrong. Not only does it destructively mutate, it doesn't look like it will behave like the interpreted append-each operator, since it assumes it can rplacd the tail cons of the output list, which won't work for non-list sequence types. * share/txr/stdlib/compiler.tl (expand-each): New translation strategy: append-each each will now accumulate the values of the body expression into a list, exactly like collect-each does. Then it will apply the sys:append function to that list. This ensures the "as if" semantics (append-each behaves like the append function), and non-destructive behavior: everything is copied that needs to be, except that a list tail can share substructure.
Diffstat (limited to 'share')
-rw-r--r--share/txr/stdlib/compiler.tl12
1 files changed, 7 insertions, 5 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index 65ce119c..bf06548e 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -1416,14 +1416,16 @@
,*(if accum ^((,out (cons nil nil)) (,accum ,out))))
(block nil
(sys:for-op ()
- ((and ,*(mapcar (op list 'iter-more) gens)) ,*(if accum ^((cdr ,out))))
+ ((and ,*(mapcar (op list 'iter-more) gens))
+ ,*(if accum (if (eq each-type 'collect-each)
+ ^((cdr ,out))
+ ^((sys:apply (fun append) ,out)))))
(,*(mapcar (ret ^(sys:setq ,@1 (iter-step ,@1))) gens))
,*(mapcar (ret ^(sys:setq ,@1 (iter-item ,@2))) vars gens)
,*(caseq each-type
- (collect-each ^((rplacd ,accum (cons (progn ,*body) nil))
- (sys:setq ,accum (cdr ,accum))))
- (append-each ^((rplacd ,accum (append (cdr ,accum) (progn ,*body)))
- (sys:setq ,accum (last ,accum))))
+ ((collect-each append-each)
+ ^((rplacd ,accum (cons (progn ,*body) nil))
+ (sys:setq ,accum (cdr ,accum))))
(t body))))))))
(defun expand-bind-mac-params (ctx-form err-form params menv-var