summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-01-17 19:54:22 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-01-17 19:54:22 -0800
commita1c7cc2f9faf4463722e78f24b9433dc9cf0bbf7 (patch)
treedd4e724c28760398435ff2e7c06fda4d2381416a /lib.c
parent1157ea776e88fa956e1e524813ab22a9c4e46ca0 (diff)
downloadtxr-a1c7cc2f9faf4463722e78f24b9433dc9cf0bbf7.tar.gz
txr-a1c7cc2f9faf4463722e78f24b9433dc9cf0bbf7.tar.bz2
txr-a1c7cc2f9faf4463722e78f24b9433dc9cf0bbf7.zip
New function, split*.
* eval.c (eval_init): Register split*. * lib.c (split_star_func): New static function. (partition_split_common): Take pointer-to-function argument instead of boolean. Hoist this C function into the lazy cons. (partition): Pass pointer to partition_func ito partition_split_common, intsead of a flag requesting the use of partition_func. (split): Pass apointer to split_func into partition_split_common. (split_star): New function. * lib.h (split_star): Declared. * txr.1: Documented split*.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/lib.c b/lib.c
index 0cff2bb5..e6aa748e 100644
--- a/lib.c
+++ b/lib.c
@@ -1929,7 +1929,44 @@ static val split_func(val env, val lcons)
return nil;
}
-static val partition_split_common(val seq, val indices, val partition_p)
+static val split_star_func(val env, val lcons)
+{
+ cons_bind (seq, indices_base, env);
+ cons_bind (indices, base, indices_base);
+
+ for (;;) {
+ if (indices) {
+ val index = pop(&indices);
+ val index_rebased = minus(index, base);
+
+ if (lt(index_rebased, zero)) {
+ continue;
+ } else {
+ val first = sub(seq, zero, index_rebased);
+ val rsub = sub(seq, succ(index_rebased), t);
+ val rest = nullify(rsub);
+
+ rplaca(env, rest);
+ rplaca(indices_base, indices);
+ rplacd(indices_base, succ(index));
+
+ rplacd(lcons, if3(rest,
+ make_lazy_cons(lcons_fun(lcons)),
+ cons(rsub, nil)));
+
+ rplaca(lcons, first);
+ }
+ } else {
+ rplaca(lcons, seq);
+ }
+ break;
+ }
+
+ return nil;
+}
+
+static val partition_split_common(val seq, val indices,
+ val (*split_fptr)(val env, val lcons))
{
seq = nullify(seq);
@@ -1947,18 +1984,22 @@ static val partition_split_common(val seq, val indices, val partition_p)
if (!seqp(indices))
indices = cons(indices, nil);
- return make_lazy_cons(func_f1(cons(seq, cons(indices, zero)),
- if3(partition_p, partition_func, split_func)));
+ return make_lazy_cons(func_f1(cons(seq, cons(indices, zero)), split_fptr));
}
val partition(val seq, val indices)
{
- return partition_split_common(seq, indices, t);
+ return partition_split_common(seq, indices, partition_func);
}
val split(val seq, val indices)
{
- return partition_split_common(seq, indices, nil);
+ return partition_split_common(seq, indices, split_func);
+}
+
+val split_star(val seq, val indices)
+{
+ return partition_split_common(seq, indices, split_star_func);
}
static val partition_star_func(val env, val lcons)