diff options
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 71 |
1 files changed, 63 insertions, 8 deletions
@@ -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"); |