summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-01-15 16:07:31 -0800
committerKaz Kylheku <kaz@kylheku.com>2021-01-15 16:07:31 -0800
commitc058a946c6fbc918ff233aea1e301921e7ce68b8 (patch)
tree1ef5eac5e21ffeb0a8039efd58e821b7a375a414
parent2d9d10ad41490e7bb58cc74af357a52373c0ed5e (diff)
downloadtxr-c058a946c6fbc918ff233aea1e301921e7ce68b8.tar.gz
txr-c058a946c6fbc918ff233aea1e301921e7ce68b8.tar.bz2
txr-c058a946c6fbc918ff233aea1e301921e7ce68b8.zip
mapcar/maprod: show-stopper bug.
Observed wrong result: (mapcar (lambda (. args) (list . args)) '#(1 2 3) '#(4 5 6)) -> #((1 4) nil nil) Correct result: -> #((1 4) (2 5) (3 6)) This is not specific to vector input; it's broken for sequences of all types. Functions affected are mapcar, mapf, mappend, mapdo, maprod, maprend, maprodo. * eval.c (map_common, prod_common): Because we reuse the args structure across iterations, we must reinitialize the fill and list members. These can be modified by the functionw which is called. In particular, the arguments are applied, they may be turned into a list (fill decrements to zero, and a list is produced).
-rw-r--r--eval.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/eval.c b/eval.c
index 0b707e78..a466fde8 100644
--- a/eval.c
+++ b/eval.c
@@ -5303,7 +5303,6 @@ static val map_common(val self, val fun, struct args *lists,
seq_iter_t *iter_array = coerce(seq_iter_t *,
alloca(argc * sizeof *iter_array));
args_decl(args_fun, max(argc, ARGS_MIN));
- args_fun->fill = argc;
list_collect_decl (out, otail);
for (i = 0, idx = 0; i < argc; i++)
@@ -5325,6 +5324,9 @@ static val map_common(val self, val fun, struct args *lists,
args_fun->arg[i] = elem;
}
+ args_fun->fill = argc;
+ args_fun->list = 0;
+
fun_ret = generic_funcall(fun, args_fun);
if (collect_fn != 0)
@@ -5438,7 +5440,6 @@ static val prod_common(val self, val fun, struct args *lists,
args_copy(args_reset, lists);
args_normalize_exact(args_reset, argc);
args_work->fill = argc;
- args_fun->fill = argc;
for (i = 0; i < argc; i++)
if (!iter_more((args_work->arg[i] = iter_begin(args_reset->arg[i]))))
@@ -5449,6 +5450,9 @@ static val prod_common(val self, val fun, struct args *lists,
for (i = 0; i < argc; i++)
args_fun->arg[i] = iter_item(args_work->arg[i]);
+ args_fun->fill = argc;
+ args_fun->list = 0;
+
ptail = collect_fn(ptail, generic_funcall(fun, args_fun));
for (i = argc - 1; ; i--) {