summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-03-14 06:34:55 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-03-14 06:34:55 -0700
commitbf6054c12230343aa0068fd21a6a167cf987444e (patch)
tree12759f77f3eaadee677aa197c82d4a42203a09c4
parentf3a0b4ddc516de5524862b51af548e277a43a28a (diff)
downloadtxr-bf6054c12230343aa0068fd21a6a167cf987444e.tar.gz
txr-bf6054c12230343aa0068fd21a6a167cf987444e.tar.bz2
txr-bf6054c12230343aa0068fd21a6a167cf987444e.zip
split, split*, partition, partition*: allow neg indices.
* lib.c (partition_split_common): Filter the list of indices, displacing any negative values by the length of the sequence, removing any that are still negative. This is subject to compatibility. (partition_star): Likewise. * txr.1: Document, and add compat notes.
-rw-r--r--lib.c60
-rw-r--r--txr.132
2 files changed, 76 insertions, 16 deletions
diff --git a/lib.c b/lib.c
index 7b208cd8..cb2594f5 100644
--- a/lib.c
+++ b/lib.c
@@ -2208,7 +2208,23 @@ static val partition_split_common(val seq, val indices,
if (!seqp(indices))
indices = cons(indices, nil);
- return make_lazy_cons(func_f1(cons(seq, cons(indices, zero)), split_fptr));
+ {
+ val len = nil;
+ list_collect_decl (out, ptail);
+
+ if (!opt_compat || opt_compat > 170) {
+ for (; indices; indices = cdr(indices)) {
+ val idx_raw = car(indices);
+ val idx = if3(minusp(idx_raw),
+ plus(idx_raw, if3(len, len, len = length(seq))),
+ idx_raw);
+ if (!minusp(idx))
+ ptail = list_collect(ptail, idx);
+ }
+ }
+
+ return make_lazy_cons(func_f1(cons(seq, cons(out, zero)), split_fptr));
+ }
}
val partition(val seq, val indices)
@@ -2289,22 +2305,38 @@ val partition_star(val seq, val indices)
if (!seqp(indices))
indices = cons(indices, nil);
- while (indices && lt(car(indices), zero))
- pop(&indices);
+ {
+ val len = nil;
+ list_collect_decl (tindices, ptail);
+
+ if (!opt_compat || opt_compat > 170) {
+ for (; indices; indices = cdr(indices)) {
+ val idx_raw = car(indices);
+ val idx = if3(minusp(idx_raw),
+ plus(idx_raw, if3(len, len, len = length(seq))),
+ idx_raw);
+ if (!minusp(idx))
+ ptail = list_collect(ptail, idx);
+ }
+ }
+
+ while (tindices && lt(car(tindices), zero))
+ pop(&tindices);
- while (indices && eql(car(indices), base)) {
- seq = nullify(cdr(seq));
- if (!seq)
- return nil;
- base = plus(base, one);
- pop(&indices);
- }
+ while (tindices && eql(car(tindices), base)) {
+ seq = nullify(cdr(seq));
+ if (!seq)
+ return nil;
+ base = plus(base, one);
+ pop(&tindices);
+ }
- if (!indices)
- return cons(seq, nil);
+ if (!tindices)
+ return cons(seq, nil);
- return make_lazy_cons(func_f1(cons(seq, cons(indices, base)),
- partition_star_func));
+ return make_lazy_cons(func_f1(cons(seq, cons(tindices, base)),
+ partition_star_func));
+ }
}
cnum c_num(val num);
diff --git a/txr.1 b/txr.1
index 3ec80d72..0efb32c0 100644
--- a/txr.1
+++ b/txr.1
@@ -25981,8 +25981,15 @@ to the original is produced.
If the second argument is of the form
.metn index-list ,
it shall be a sequence of
-strictly non-decreasing, integers. First, any leading negative or zero values
-in this sequence are dropped. The
+strictly non-decreasing, integers.
+
+First, the length of
+.meta sequence
+is added to every value in
+.meta index-list
+that is negative.
+Then, any leading negative or zero values are dropped.
+The
.code partition
function then divides
.meta sequence
@@ -26084,6 +26091,10 @@ includes an index greater than or equal to the length of
.meta sequence
(equivalently, an index beyond the last element of the sequence)
then an additional empty last piece is generated.
+The length of
+.meta sequence
+is added to any negative indices. An index which is still negative
+after being thus displaced is discarded.
If
.meta index-list
@@ -26161,6 +26172,12 @@ is empty then a one-element list containing the entire
.meta sequence
is returned.
+If
+.meta index-list
+contains negative values, these are displaced by adding to them
+the length of
+.metn sequence .
+
If the second argument is a function, then this function is applied
to
.metn sequence ,
@@ -52897,6 +52914,17 @@ which do not take any arguments, and do not select an input source using the
directive, or suppress the use of an input source using
.codn "@(next nil)" ,
may now accidentally read from standard input.
+Until version 170, the functions
+.codn split ,
+.codn split* ,
+.code partition
+and
+.code partition*
+ignored negative indices in their
+.meta index-list
+argument. The new behavior is that the length of the input sequence
+is added to any negative index values. The resulting values are then
+ignored if they are still negative.
.IP 165
A value of 165 restores the following behaviors, which changed starting in 166.
There was a in Lisp evaluation support of the \*(TX pattern language.