summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-05-25 06:07:00 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-05-25 06:07:00 -0700
commitf390cac7b32c4e9d612eaaad21093d2c0ebdfb0a (patch)
tree0deae7cbde307d3cc47c4f0740cd8ed6bafb8256 /lib.c
parentf2f951350516e4b959ef28f220e31b91b466fa16 (diff)
downloadtxr-f390cac7b32c4e9d612eaaad21093d2c0ebdfb0a.tar.gz
txr-f390cac7b32c4e9d612eaaad21093d2c0ebdfb0a.tar.bz2
txr-f390cac7b32c4e9d612eaaad21093d2c0ebdfb0a.zip
window-map: broken :wrap and :reflect.
* lib.c (window_map_list): Rewrite :wrap and :reflect support. The main issue with these is that they only sample items from the front of the input list and generate both flanks of the boundary from that prefix; :reflect is additionaly buggy due to applying nreverse to a sub which can return the original sequence. * tests/012/seq.tl: Some test coverage for window-map.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/lib.c b/lib.c
index 4883e08b..206eead7 100644
--- a/lib.c
+++ b/lib.c
@@ -9491,17 +9491,27 @@ static val window_map_list(val range, val boundary, val fun, val list,
args_set_fill(args, ws);
- if (boundary == wrap_k) {
- val lcopy = take(range, list);
- while (lt(length(lcopy), range))
- lcopy = append2(lcopy, lcopy);
- boundary = append2(sub(lcopy, num_fast(-ra), t), sub(lcopy, zero, range));
- } else if (boundary == reflect_k) {
- val lcopy = take(range, list);
- while (lt(length(lcopy), range))
- lcopy = append2(lcopy, lcopy);
- boundary = nappend2(nreverse(sub(lcopy, zero, range)),
- nreverse(sub(lcopy, num_fast(-ra), t)));
+ if (boundary == wrap_k || boundary == reflect_k) {
+ val lw = sub(list, num_fast(-ra), t), lwing = lw;
+ val rw = sub(list, zero, range), rwing = rw;
+ cnum i, len = c_fixnum(length(list), self);
+
+ if (boundary == reflect_k) {
+ lwing = reverse(rw);
+ rwing = reverse(lw);
+ lw = lwing;
+ rw = rwing;
+ }
+
+ for (i = len; i < ra; i += len) {
+ lwing = append2(lwing, lw);
+ rwing = append2(rwing, rw);
+ }
+
+ if (len < ra)
+ boundary = append2(sub(lwing, num_fast(-ra), t), sub(rwing, zero, range));
+ else
+ boundary = append2(lwing, rwing);
}
for (i = 0; i < ra; i++)