diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-03-14 06:34:55 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-03-14 06:34:55 -0700 |
commit | bf6054c12230343aa0068fd21a6a167cf987444e (patch) | |
tree | 12759f77f3eaadee677aa197c82d4a42203a09c4 /lib.c | |
parent | f3a0b4ddc516de5524862b51af548e277a43a28a (diff) | |
download | txr-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.c | 60 |
1 files changed, 46 insertions, 14 deletions
@@ -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); |