summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index 5a1e1979..5dd21df4 100644
--- a/lib.c
+++ b/lib.c
@@ -3593,6 +3593,60 @@ val tuples(val n, val seq, val fill)
return make_lazy_cons_car_cdr(func_f1(n, tuples_func), iter, fill);
}
+static val tuples_star_func(val tail, val lcons)
+{
+ us_cons_bind (tuple, iter, lcons);
+ val item = make_like(tuple, iter);
+
+ if (iter_more(iter)) {
+ val itemcopy = if3(tuple == item, copy_list(tuple), item);
+ us_rplaca(lcons, itemcopy);
+ us_rplacd(tail, cons(iter_item(iter), nil));
+
+ {
+ val nxtuple = us_cdr(tuple);
+ val fun = us_lcons_fun(lcons);
+ tail = us_cdr(tail);
+ iter = iter_step(iter);
+ rcyc_cons(tuple);
+ us_func_set_env(fun, tail);
+ us_rplacd(lcons, make_lazy_cons_car_cdr(fun, nxtuple, iter));
+ }
+ } else {
+ val item = make_like(tuple, iter);
+ us_rplaca(lcons, item);
+ us_rplacd(lcons, nil);
+ }
+
+ return nil;
+}
+
+val tuples_star(val n, val seq, val fill)
+{
+ val self = lit("tuples*");
+ val iter = iter_begin(seq);
+ cnum i, cn = c_num(n, self);
+ list_collect_decl (tuple, ptail);
+
+ if (!plusp(n) || !integerp(n))
+ uw_throwf(error_s, lit("~a: positive integer required, not ~s"), self, n, nao);
+
+ for (i = 0; i < cn; i++, iter = iter_step(iter))
+ {
+ if (!iter_more(iter)) {
+ if (missingp(fill))
+ return nil;
+ for (; i < cn; i++)
+ ptail = list_collect(ptail, fill);
+ break;
+ }
+
+ ptail = list_collect(ptail, iter_item(iter));
+ }
+
+ return make_lazy_cons_car_cdr(func_f1(lastcons(tuple), tuples_star_func), tuple, iter);
+}
+
static val partition_by_func(val func, val lcons)
{
list_collect_decl (out, ptail);