diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-12-20 20:46:59 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-12-20 20:46:59 -0800 |
commit | 75b1508c61d3805d1678a8dabf8d48b9e76c8d37 (patch) | |
tree | 3eaf1d1d355152b483be81775933f5f665c66929 /stdlib/each-prod.tl | |
parent | f0a538af2282cd9425c547b151779c982a3ebc03 (diff) | |
download | txr-75b1508c61d3805d1678a8dabf8d48b9e76c8d37.tar.gz txr-75b1508c61d3805d1678a8dabf8d48b9e76c8d37.tar.bz2 txr-75b1508c61d3805d1678a8dabf8d48b9e76c8d37.zip |
product/arithmetic each: missing block nil.
* stdlib/arith-each.tl (sys:vars-check): New function, copy
and pasted from each-prod.tl.
(sys:arith-each): New macro.
(sum-each, sum-each*, mul-each, mul-each*): Reworked using
sys:arith-each macro. This macro uses logic borrowed from
a stripped-down expand-each in the compiler.
* stdlib/each-prod.tl (sys:expand-each-prod,
sys:expand-arith-each-prod*): Add the block nil around the
mapping call, taking care that the initialization forms
are evaluated outside of the block, and their values bound to
gensyms that then form the function arguments.
* txr.1: Document the missing requirements for all the
affected macros that there must be an anonymous block around
the body, which, if used, determines the return value.
Diffstat (limited to 'stdlib/each-prod.tl')
-rw-r--r-- | stdlib/each-prod.tl | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/stdlib/each-prod.tl b/stdlib/each-prod.tl index 1393b80a..d48263f6 100644 --- a/stdlib/each-prod.tl +++ b/stdlib/each-prod.tl @@ -37,13 +37,16 @@ (defun sys:expand-each-prod (form vars body) (sys:vars-check form vars) (let ((syms [mapcar car vars]) - (inits [mapcar cadr vars])) + (inits [mapcar cadr vars]) + (gens [mapcar (ret (gensym)) vars])) (sys:bindable-check form syms) (let ((fun (caseq (car form) (each-prod 'maprodo) (collect-each-prod 'maprod) (append-each-prod 'maprend)))) - ^(,fun (lambda (,*syms) ,*body) ,*inits)))) + ^(let ,(zip gens inits) + (block nil + (,fun (lambda (,*syms) ,*body) ,*gens)))))) (defun sys:expand-each-prod* (form vars body) (sys:vars-check form vars) @@ -61,17 +64,20 @@ (defun sys:expand-arith-each-prod (form vars body) (sys:vars-check form vars) (let ((syms [mapcar car vars]) - (inits [mapcar cadr vars])) + (inits [mapcar cadr vars]) + (gens [mapcar (ret (gensym)) vars])) (sys:bindable-check form syms) (let ((op-iv (caseq (car form) (sum-each-prod '(+ . 0)) (mul-each-prod '(* . 1))))) (with-gensyms (acc) - ^(let ((,acc ,(cdr op-iv))) - (maprodo (lambda (,*syms) - (set ,acc (,(car op-iv) ,acc (progn ,*body)))) - ,*inits) - ,acc))))) + ^(let ((,acc ,(cdr op-iv)) + ,*(zip gens inits)) + (block nil + (maprodo (lambda (,*syms) + (set ,acc (,(car op-iv) ,acc (progn ,*body)))) + ,*gens) + ,acc)))))) (defmacro each-prod (:form f vars . body) (sys:expand-each-prod f vars body)) |