diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2024-04-16 21:46:37 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2024-04-16 21:46:37 -0700 |
commit | 262cf47d2c701bf71143f312427b1f4fa140deb9 (patch) | |
tree | 0828d9e7641147aa0687cb65c48404ae12533fdb /lib.c | |
parent | 12c24e79baa50ce2e345956bcbabe567c5339130 (diff) | |
download | txr-262cf47d2c701bf71143f312427b1f4fa140deb9.tar.gz txr-262cf47d2c701bf71143f312427b1f4fa140deb9.tar.bz2 txr-262cf47d2c701bf71143f312427b1f4fa140deb9.zip |
New function: iter-cat.
* eval.c (eval_init): Register iter-cat intrinsic.
* lib.h (struct seq_iter): New union member dargs.
(iter_catv): Declared.
* lib.c (seq_iter_get_cat, seq_iter_peek_cat): New
static functions.
(si_cat_ops): New static structure.
(iter_catv): New function.
* tests/012/iter.tl: New tests.
* txr.1: Documented.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 64 |
1 files changed, 64 insertions, 0 deletions
@@ -869,6 +869,47 @@ static void seq_iter_rewind(seq_iter_t *it) } } +static int seq_iter_get_cat(seq_iter_t *it, val *pval) +{ + val dargs = it->ul.dargs; + cnum index = it->ui.index; + varg args = dargs->a.args; + val iter = dargs->a.car; + + for (;;) { + if (iter_more(iter)) { + *pval = iter_item(iter); + set(mkloc(dargs->a.car, dargs), iter_step(iter)); + return 1; + } + if (!args_more(args, index)) + return 0; + iter = iter_begin(args_get(args, &index)); + it->ui.index = index; + set(mkloc(dargs->a.car, dargs), iter); + } +} + +static int seq_iter_peek_cat(seq_iter_t *it, val *pval) +{ + val dargs = it->ul.dargs; + cnum index = it->ui.index; + varg args = dargs->a.args; + val iter = dargs->a.car; + + for (;;) { + if (iter_more(iter)) { + *pval = iter_item(iter); + return 1; + } + if (!args_more(args, index)) + return 0; + iter = iter_begin(args_get(args, &index)); + it->ui.index = index; + set(mkloc(dargs->a.car, dargs), iter); + } +} + static void seq_iter_mark_op(struct seq_iter *it) { gc_mark(it->ui.iter); @@ -933,6 +974,9 @@ struct seq_iter_ops si_oop_ops = seq_iter_ops_init(seq_iter_get_oop, struct seq_iter_ops si_fast_oop_ops = seq_iter_ops_init(seq_iter_get_fast_oop, seq_iter_peek_fast_oop); +struct seq_iter_ops si_cat_ops = seq_iter_ops_init(seq_iter_get_cat, + seq_iter_peek_cat); + void seq_iter_init_with_info(val self, seq_iter_t *it, seq_info_t si, int support_rewind) { @@ -1406,6 +1450,26 @@ val iter_reset(val iter, val obj) } } +val iter_catv(varg iters) +{ + cnum index = 0; + if (args_more(iters, index)) { + val iter0 = iter_begin(args_get(iters, &index)); + val dargs = dyn_args(iters, iter0, nil); + val si_obj, iter; + struct seq_iter *si = coerce(struct seq_iter *, chk_calloc(1, sizeof *si)); + si->inf.type = DARG; + si->inf.obj = dargs; + si->ui.index = index; + si->ul.dargs = dargs; + si->ops = &si_cat_ops; + si_obj = cobj(coerce(mem_t *, si), seq_iter_cls, &seq_iter_ops); + gc_hint(iter); + return si_obj; + } + return nil; +} + static void seq_build_generic_pend(seq_build_t *bu, val seq) { seq_iter_t it; |