From 4098bdfbe0406bfacfc8a1b46bfad38964cfd2df Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Mon, 11 Mar 2019 22:11:29 -0700 Subject: New sequence iterator object and functions. * eval.c (eval_init): Register seq-begin, seq-next and seq-reset. * lib.c (seq_iter_s): New symbol variable. (seq_iter_mark): New static function. (seq_iter_ops): New static structure. (seq_begin, seq_next, seq_reset): New functions. (obj_init): Intern seq-iter symbol, used as class name for iterators. * lib.h (seq_iter_s, seq_begin, seq_next, seq_reset): Declared. * txr.1: Documented. --- lib.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'lib.c') diff --git a/lib.c b/lib.c index 194d8cb6..f23e40df 100644 --- a/lib.c +++ b/lib.c @@ -109,7 +109,7 @@ val query_error_s, file_error_s, process_error_s, syntax_error_s; val timeout_error_s, system_error_s, alloc_error_s; val warning_s, defr_warning_s, restart_s, continue_s; val gensym_counter_s, nullify_s, from_list_s, lambda_set_s, length_s; -val rplaca_s, rplacd_s; +val rplaca_s, rplacd_s, seq_iter_s; val nothrow_k, args_k, colon_k, auto_k, fun_k; val wrap_k, reflect_k; @@ -402,6 +402,57 @@ void seq_iter_init(val self, seq_iter_t *it, val obj) } } +static void seq_iter_mark(val seq_iter) +{ + struct seq_iter *si = coerce(struct seq_iter *, seq_iter->co.handle); + + gc_mark(si->inf.obj); + + switch (si->inf.kind) { + case SEQ_LISTLIKE: + case SEQ_HASHLIKE: + gc_mark(si->ui.iter); + break; + default: + break; + } +} + +static struct cobj_ops seq_iter_ops = cobj_ops_init(eq, + cobj_print_op, + cobj_destroy_free_op, + seq_iter_mark, + cobj_eq_hash_op); + +val seq_begin(val obj) +{ + val self = lit("seq-begin"); + val si_obj; + struct seq_iter *si = coerce(struct seq_iter *, chk_calloc(1, sizeof *si)); + si_obj = cobj(coerce(mem_t *, si), seq_iter_s, &seq_iter_ops); + seq_iter_init(self, si, obj); + si->inf.obj = nil; + return si_obj; +} + +val seq_next(val iter, val end_val) +{ + val self = lit("seq-next"); + struct seq_iter *si = coerce(struct seq_iter *, + cobj_handle(self, iter, seq_iter_s)); + val item = nil; + return if3(seq_get(si, &item), item, end_val); +} + +val seq_reset(val iter, val obj) +{ + val self = lit("seq-reset"); + struct seq_iter *si = coerce(struct seq_iter *, + cobj_handle(self, iter, seq_iter_s)); + seq_iter_init(self, si, obj); + return iter; +} + val throw_mismatch(val self, val obj, type_t t) { type_mismatch(lit("~a: ~s is not of type ~s"), self, obj, code2type(t), nao); @@ -11087,6 +11138,7 @@ static void obj_init(void) length_s = intern(lit("length"), user_package); rplaca_s = intern(lit("rplaca"), user_package); rplacd_s = intern(lit("rplacd"), user_package); + seq_iter_s = intern(lit("seq-iter"), user_package); args_k = intern(lit("args"), keyword_package); nothrow_k = intern(lit("nothrow"), keyword_package); -- cgit v1.2.3