summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c71
1 files changed, 63 insertions, 8 deletions
diff --git a/lib.c b/lib.c
index cf137699..8aeda9ab 100644
--- a/lib.c
+++ b/lib.c
@@ -859,6 +859,34 @@ static int seq_iter_peek_cat(seq_iter_t *it, val *pval)
}
}
+static int seq_iter_get_skip(seq_iter_t *it, val *pval)
+{
+ val iter = it->ui.iter;
+ cnum skip = it->ul.skip;
+
+ if (iter_more(iter)) {
+ cnum i;
+ *pval = iter_item(iter);
+ for (i = 0; i < skip; i++)
+ iter = iter_step(iter);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int seq_iter_peek_skip(seq_iter_t *it, val *pval)
+{
+ val iter = it->ui.iter;
+
+ if (iter_more(iter)) {
+ *pval = iter_item(iter);
+ return 1;
+ }
+
+ return 0;
+}
+
static void seq_iter_mark_cat(struct seq_iter *it)
{
gc_mark(it->ul.dargs);
@@ -941,6 +969,9 @@ struct seq_iter_ops si_cat_ops = seq_iter_ops_init_mark(seq_iter_get_cat,
seq_iter_peek_cat,
seq_iter_mark_cat);
+struct seq_iter_ops si_skip_ops = seq_iter_ops_init(seq_iter_get_skip,
+ seq_iter_peek_skip);
+
static void seq_iter_clone(seq_iter_t *dit, const seq_iter_t *sit)
{
if (sit->ops->clone)
@@ -949,6 +980,14 @@ static void seq_iter_clone(seq_iter_t *dit, const seq_iter_t *sit)
*dit = *sit;
}
+static val iter_dynamic(struct seq_iter *si_orig)
+{
+ struct seq_iter *si = coerce(struct seq_iter *,
+ chk_copy_obj(coerce(mem_t *, si_orig),
+ sizeof *si));
+ return cobj(coerce(mem_t *, si), seq_iter_cls, &seq_iter_cobj_ops);
+}
+
void seq_iter_init_with_info(val self, seq_iter_t *it, seq_info_t si)
{
it->inf = si;
@@ -964,6 +1003,30 @@ void seq_iter_init_with_info(val self, seq_iter_t *it, seq_info_t si)
break;
}
+ if (rangep(rt)) {
+ val rtf = from(rt);
+ val rtt = to(rt);
+
+ if (!integerp(rtt) || !plusp(rtt)) {
+ uw_throwf(type_error_s,
+ lit("~a: skip amount ~s in ~s..~s..~s "
+ "must be positive integer"),
+ self, rtt, rf, rtf, rtt, nao);
+ } else if (rtt == one) {
+ rt = rtf;
+ } else {
+ val rng = rcons(rf, rtf);
+ seq_iter_t lower_iter;
+
+ seq_iter_init_with_info(self, &lower_iter, seq_info(rng));
+
+ it->ui.iter = iter_dynamic(&lower_iter);
+ it->ul.skip = c_num(rtt, self);
+ it->ops = &si_skip_ops;
+ return;
+ }
+ }
+
if (less(rf, rt)) switch (type(rf)) {
case NUM:
num_range_fwd:
@@ -1277,14 +1340,6 @@ val iter_begin(val obj)
}
}
-static val iter_dynamic(struct seq_iter *si_orig)
-{
- struct seq_iter *si = coerce(struct seq_iter *,
- chk_copy_obj(coerce(mem_t *, si_orig),
- sizeof *si));
- return cobj(coerce(mem_t *, si), seq_iter_cls, &seq_iter_cobj_ops);
-}
-
val iter_more(val iter)
{
val self = lit("iter-more");