diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-12-02 08:24:28 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-12-02 08:24:28 -0800 |
commit | 536216aa9932b9ab5627f7defb6608b67709c547 (patch) | |
tree | 0412f95c7ae616c4f29a0966fd09feec121ae0d3 | |
parent | 29ffa06feca713b458f810194b5a5a733c93a3f7 (diff) | |
download | txr-536216aa9932b9ab5627f7defb6608b67709c547.tar.gz txr-536216aa9932b9ab5627f7defb6608b67709c547.tar.bz2 txr-536216aa9932b9ab5627f7defb6608b67709c547.zip |
tuples: change to abstract iteration.
* lib.c (make_like): In the COBJ case, recognize an iterator
object. Pull out the underlying object and recurse on it.
This is needed in tuples_func, where make_like will now be
called on the abstract iterator, rather than the actual
sequence object.
(tuples_func): The incoming object is now an iterator, and not
a sequence; we need to handle it with iter_more, iter_item and
iter_step.
(tuples): Instead of nullify, begin iteration with
iter_begin, and use iter_more to test for empty.
In non-empty case, put propagate the iterator thorugh the lazy
cons car field, rather than the sequence.
-rw-r--r-- | lib.c | 26 |
1 files changed, 16 insertions, 10 deletions
@@ -1937,6 +1937,11 @@ val make_like(val list, val thatobj) return buf_list(list); break; case COBJ: + if (thatobj->co.cls == seq_iter_cls) + { + struct seq_iter *si = coerce(struct seq_iter *, thatobj->co.handle); + return make_like(list, si->inf.obj); + } if (obj_struct_p(thatobj)) { val from_list_meth = get_special_slot(thatobj, from_list_m); if (from_list_meth) @@ -3553,22 +3558,23 @@ val lazy_flatcar(val tree) static val tuples_func(val n, val lcons) { list_collect_decl (out, ptail); - us_cons_bind (seq_in, fill, lcons); - val seq = seq_in; + us_cons_bind (iter_in, fill, lcons); + val iter = iter_in; val count; - for (count = n; count != zero && seq; count = minus(count, one)) - ptail = list_collect(ptail, pop(&seq)); + for (count = n; count != zero && iter_more(iter); + count = minus(count, one), iter = iter_step(iter)) + ptail = list_collect(ptail, iter_item(iter)); if (!missingp(fill)) for (; gt(count, zero); count = minus(count, one)) ptail = list_collect(ptail, fill); - if (seq) - us_rplacd(lcons, make_lazy_cons_car_cdr(us_lcons_fun(lcons), seq, fill)); + if (iter_more(iter)) + us_rplacd(lcons, make_lazy_cons_car_cdr(us_lcons_fun(lcons), iter, fill)); else us_rplacd(lcons, nil); - us_rplaca(lcons, make_like(out, seq_in)); + us_rplaca(lcons, make_like(out, iter_in)); return nil; } @@ -3576,15 +3582,15 @@ static val tuples_func(val n, val lcons) val tuples(val n, val seq, val fill) { val self = lit("tuples"); - seq = nullify(seq); + val iter = iter_begin(seq); if (!plusp(n) || !integerp(n)) uw_throwf(error_s, lit("~a: positive integer required, not ~s"), self, n, nao); - if (!seq) + if (!iter_more(iter)) return nil; - return make_lazy_cons_car_cdr(func_f1(n, tuples_func), seq, fill); + return make_lazy_cons_car_cdr(func_f1(n, tuples_func), iter, fill); } static val partition_by_func(val func, val lcons) |