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
commitfb3817c01bcc7a5520d274c4017e6aec4bd20662 (patch)
tree1ef5eac5e21ffeb0a8039efd58e821b7a375a414
parent5121a71dd6f8280583127e6e6733ec094b642f6a (diff)
downloadtxr-fb3817c01bcc7a5520d274c4017e6aec4bd20662.tar.gz
txr-fb3817c01bcc7a5520d274c4017e6aec4bd20662.tar.bz2
txr-fb3817c01bcc7a5520d274c4017e6aec4bd20662.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--) {