summaryrefslogtreecommitdiffstats
path: root/lib.c
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 /lib.c
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.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c60
1 files changed, 46 insertions, 14 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);