diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2024-07-10 04:15:22 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2024-07-10 04:15:22 -0700 |
commit | a51888496ffbe18b3fcd7b27fec5c743a629a719 (patch) | |
tree | 1840aa344821eb04fee84c8081a971ba0b433887 | |
parent | 36a83b0c6ba341377a3fe0595993599d172e70a8 (diff) | |
download | txr-a51888496ffbe18b3fcd7b27fec5c743a629a719.tar.gz txr-a51888496ffbe18b3fcd7b27fec5c743a629a719.tar.bz2 txr-a51888496ffbe18b3fcd7b27fec5c743a629a719.zip |
partition, split, split*: bug handling negative indices.
* lib.c (partition_func, split_func, split_star_func):
When negative indices occur after the sequence has already
been shortened, the conversion to positivce must take into
account the base. This must be added so that the positive
index produced is relative to the original length of the input
sequence. When index_rebased is calculated, the base is
subtracted out again. If we based the positive index off the
shortened length, it's as if we are subtracting base twice.
* tests/012/seq.tl: Dubious test cases for split* are replaced
with the new results that make sense. Additional test cases
are added which cover this issue, for not only split* but
split and partition.
-rw-r--r-- | lib.c | 7 | ||||
-rw-r--r-- | tests/012/seq.tl | 50 |
2 files changed, 35 insertions, 22 deletions
@@ -4205,7 +4205,8 @@ static val partition_func(val base, val lcons) if (iter_more(indices)) { val raw_index = iter_item(indices); val index = if3((!opt_compat || opt_compat > 170) && minusp(raw_index), - plus(raw_index, if3(len, len, len = length(seq))), + plus(plus(raw_index, if3(len, len, len = length(seq))), + base), raw_index); val index_rebased = minus(index, base); @@ -4247,7 +4248,7 @@ static val split_func(val base, val lcons) val len = if3(le, le, le = length(seq)); val raw_index = iter_item(indices); val index = if3((!opt_compat || opt_compat > 170) && minusp(raw_index), - plus(raw_index, len), + plus(plus(raw_index, len), base), raw_index); val index_rebased = minus(index, base); @@ -4290,7 +4291,7 @@ static val split_star_func(val base, val lcons) val len = if3(le, le, le = length(seq)); val raw_index = iter_item(indices); val index = if3((!opt_compat || opt_compat > 170) && minusp(raw_index), - plus(raw_index, len), + plus(plus(raw_index, len), base), raw_index); val index_rebased = minus(index, base); diff --git a/tests/012/seq.tl b/tests/012/seq.tl index 9164516a..5746939b 100644 --- a/tests/012/seq.tl +++ b/tests/012/seq.tl @@ -1107,6 +1107,10 @@ (split 2..5 '(2 3)) ((2 3) (4) nil)) (mtest + (split "abcdef" '(4 -1)) ("abcd" "e" "f") + (split "abcdef" '(4 5)) ("abcd" "e" "f")) + +(mtest (split* nil -3) nil (split* nil -2) nil (split* nil -1) nil @@ -1203,12 +1207,12 @@ (split* '(a b) 1) ((a) nil) (split* '(a b) 2) ((a b) nil) (split* '(a b) 3) ((a b)) - (split* '(a b) '(0 -1)) (nil (b)) ;; questionable - (split* '(a b) '(0 1)) (nil nil nil) ;; questionabble - (split* '(a b) '(0 -1 2)) (nil (b) nil) ;; questionable - (split* '(a b) '(0 1 2)) (nil nil nil) ;; questionable + (split* '(a b) '(0 -1)) (nil nil nil) + (split* '(a b) '(0 1)) (nil nil nil) + (split* '(a b) '(0 -1 2)) (nil nil nil) + (split* '(a b) '(0 1 2)) (nil nil nil) (split* '(a b) '(1 2)) ((a) nil) - (split* '(a b) '(-1 2)) ((a) nil)) ;; questionable + (split* '(a b) '(-1 2)) ((a) nil)) (mtest (split* #(a b) -4) (#(a b)) @@ -1219,12 +1223,12 @@ (split* #(a b) 1) (#(a) #()) (split* #(a b) 2) (#(a b) #()) (split* #(a b) 3) (#(a b)) - (split* #(a b) '(0 -1)) (#() #(b)) ;; questionable - (split* #(a b) '(0 1)) (#() #() #()) ;; questionable - (split* #(a b) '(0 -1 2)) (#() #(b) #()) ;; questionable - (split* #(a b) '(0 1 2)) (#() #() #()) ;; questionable - (split* #(a b) '(1 2)) (#(a) #()) ;; questionable - (split* #(a b) '(-1 2)) (#(a) #())) ;; questionable + (split* #(a b) '(0 -1)) (#() #() #()) + (split* #(a b) '(0 1)) (#() #() #()) + (split* #(a b) '(0 -1 2)) (#() #() #()) + (split* #(a b) '(0 1 2)) (#() #() #()) + (split* #(a b) '(1 2)) (#(a) #()) + (split* #(a b) '(-1 2)) (#(a) #())) (mtest (split* "ab" -4) ("ab") @@ -1235,12 +1239,12 @@ (split* "ab" 1) ("a" "") (split* "ab" 2) ("ab" "") (split* "ab" 3) ("ab") - (split* "ab" #(0 -1)) ("" "b") ;; questionable - (split* "ab" '(0 1)) ("" "" "") ;; questionable - (split* "ab" '(0 -1 2)) ("" "b" "") ;; questionable - (split* "ab" '(0 1 2)) ("" "" "") ;; questionable - (split* "ab" '(1 2)) ("a" "") ;; questionable - (split* "ab" '(-1 2)) ("a" "")) ;; questionable + (split* "ab" #(0 -1)) ("" "" "") + (split* "ab" '(0 1)) ("" "" "") + (split* "ab" '(0 -1 2)) ("" "" "") + (split* "ab" '(0 1 2)) ("" "" "") + (split* "ab" '(1 2)) ("a" "") + (split* "ab" '(-1 2)) ("a" "")) (mtest (split* 2..4 -4) ((2 3)) @@ -1251,9 +1255,9 @@ (split* 2..4 1) ((2) nil) (split* 2..4 2) ((2 3) nil) (split* 2..4 3) ((2 3)) - (split* 2..4 '(0 -1)) (nil (3)) + (split* 2..4 '(0 -1)) (nil nil nil) (split* 2..4 '(0 1)) (nil nil nil) - (split* 2..4 '(0 -1 2)) (nil (3) nil) + (split* 2..4 '(0 -1 2)) (nil nil nil) (split* 2..4 '(0 1 2)) (nil nil nil) (split* 2..4 '(1 2)) ((2) nil) (split* 2..4 '(-1 2)) ((2) nil)) @@ -1315,6 +1319,10 @@ (split* 2..5 '(2 3)) ((2 3) nil)) (mtest + (split* "abcdef" '(4 -1)) ("abcd" "" "") + (split* "abcdef" '(4 5)) ("abcd" "" "")) + +(mtest (partition nil -3) nil (partition nil -2) nil (partition nil -1) nil @@ -1525,3 +1533,7 @@ (partition 2..5 '(1 2)) ((2) (3) (4)) (partition 2..5 '(1 3)) ((2) (3 4)) (partition 2..5 '(2 3)) ((2 3) (4))) + +(mtest + (partition "abcdef" '(4 -1)) ("abcd" "e" "f") + (partition "abcdef" '(4 5)) ("abcd" "e" "f")) |