diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-01-15 16:07:31 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-01-15 16:07:31 -0800 |
commit | c058a946c6fbc918ff233aea1e301921e7ce68b8 (patch) | |
tree | 1ef5eac5e21ffeb0a8039efd58e821b7a375a414 | |
parent | 2d9d10ad41490e7bb58cc74af357a52373c0ed5e (diff) | |
download | txr-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.c | 8 |
1 files changed, 6 insertions, 2 deletions
@@ -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--) { |