summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-04-16 21:46:37 -0700
committerKaz Kylheku <kaz@kylheku.com>2024-04-16 21:46:37 -0700
commit262cf47d2c701bf71143f312427b1f4fa140deb9 (patch)
tree0828d9e7641147aa0687cb65c48404ae12533fdb /lib.c
parent12c24e79baa50ce2e345956bcbabe567c5339130 (diff)
downloadtxr-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.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index 4ee9cd59..832d704b 100644
--- a/lib.c
+++ b/lib.c
@@ -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;