summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eval.c5
-rw-r--r--lib.c111
-rw-r--r--lib.h5
-rw-r--r--txr.1162
4 files changed, 276 insertions, 7 deletions
diff --git a/eval.c b/eval.c
index e94b4c14..7f3e2b23 100644
--- a/eval.c
+++ b/eval.c
@@ -6970,6 +6970,11 @@ void eval_init(void)
reg_fun(intern(lit("seq-begin"), user_package), func_n1(seq_begin));
reg_fun(intern(lit("seq-next"), user_package), func_n2(seq_next));
reg_fun(intern(lit("seq-reset"), user_package), func_n2(seq_reset));
+ reg_fun(intern(lit("iter-begin"), user_package), func_n1(iter_begin));
+ reg_fun(intern(lit("iter-more"), user_package), func_n1(iter_more));
+ reg_fun(intern(lit("iter-item"), user_package), func_n1(iter_item));
+ reg_fun(intern(lit("iter-step"), user_package), func_n1(iter_step));
+ reg_fun(intern(lit("iter-reset"), user_package), func_n2(iter_reset));
reg_fun(intern(lit("rcons"), user_package), func_n2(rcons));
reg_fun(intern(lit("rangep"), user_package), func_n1(rangep));
diff --git a/lib.c b/lib.c
index 1b9fefa9..cc8d00bb 100644
--- a/lib.c
+++ b/lib.c
@@ -416,9 +416,10 @@ void seq_iter_rewind(seq_iter_t *it)
}
}
-void seq_iter_init(val self, seq_iter_t *it, val obj)
+static void seq_iter_init_with_info(val self, seq_iter_t *it,
+ val obj, seq_info_t si)
{
- it->inf = seq_info(obj);
+ it->inf = si;
switch (it->inf.kind) {
case SEQ_NIL:
@@ -450,6 +451,11 @@ void seq_iter_init(val self, seq_iter_t *it, val obj)
}
}
+void seq_iter_init(val self, seq_iter_t *it, val obj)
+{
+ seq_iter_init_with_info(self, it, obj, seq_info(obj));
+}
+
val seq_getpos(val self, seq_iter_t *it)
{
switch (it->inf.kind) {
@@ -528,6 +534,107 @@ val seq_reset(val iter, val obj)
return iter;
}
+val iter_begin(val obj)
+{
+ val self = lit("iter-begin");
+ seq_info_t sinf = seq_info(obj);
+
+ switch (sinf.kind) {
+ case SEQ_NIL:
+ case SEQ_LISTLIKE:
+ return sinf.obj;
+ default:
+ {
+ 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_with_info(self, si, obj, sinf);
+ return si_obj;
+ }
+ }
+}
+
+val iter_more(val iter)
+{
+ switch (type(iter)) {
+ case NIL:
+ return nil;
+ case COBJ:
+ if (iter->co.cls == seq_iter_s)
+ {
+ struct seq_iter *si = coerce(struct seq_iter *, iter->co.handle);
+ val item = nil;
+ return if2(seq_peek(si, &item), t);
+ }
+ /* fallthrough */
+ default:
+ return t;
+ }
+}
+
+val iter_item(val iter)
+{
+ switch (type(iter)) {
+ case NIL:
+ return nil;
+ case COBJ:
+ if (iter->co.cls == seq_iter_s)
+ {
+ struct seq_iter *si = coerce(struct seq_iter *, iter->co.handle);
+ val item = nil;
+ return if2(seq_peek(si, &item), item);
+ }
+ /* fallthrough */
+ default:
+ return car(iter);
+ }
+}
+
+val iter_step(val iter)
+{
+ switch (type(iter)) {
+ case NIL:
+ return nil;
+ case COBJ:
+ if (iter->co.cls == seq_iter_s)
+ {
+ struct seq_iter *si = coerce(struct seq_iter *, iter->co.handle);
+ val item = nil;
+ (void) seq_get(si, &item);
+ return iter;
+ }
+ /* fallthrough */
+ default:
+ return cdr(iter);
+ }
+}
+
+val iter_reset(val iter, val obj)
+{
+ val self = lit("iter-reset");
+ seq_info_t sinf = seq_info(obj);
+
+ switch (sinf.kind) {
+ case SEQ_NIL:
+ case SEQ_LISTLIKE:
+ return sinf.obj;
+ default:
+ switch (type(iter)) {
+ case COBJ:
+ if (iter->co.cls == seq_iter_s)
+ {
+ struct seq_iter *si = coerce(struct seq_iter *, iter->co.handle);
+ seq_iter_init_with_info(self, si, obj, sinf);
+ return iter;
+ }
+ /* fallthrough */
+ default:
+ return iter_begin(obj);
+ }
+ }
+}
+
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);
diff --git a/lib.h b/lib.h
index d23484c1..37180204 100644
--- a/lib.h
+++ b/lib.h
@@ -556,6 +556,11 @@ void seq_setpos(val self, seq_iter_t *it, val pos);
val seq_begin(val obj);
val seq_next(val iter, val end_val);
val seq_reset(val iter, val obj);
+val iter_begin(val obj);
+val iter_more(val iter);
+val iter_item(val iter);
+val iter_step(val iter);
+val iter_reset(val iter, val obj);
val throw_mismatch(val self, val obj, type_t);
INLINE val type_check(val self, val obj, type_t typecode)
{
diff --git a/txr.1 b/txr.1
index 6088c914..cc1a9bb7 100644
--- a/txr.1
+++ b/txr.1
@@ -33080,15 +33080,167 @@ and tests for termination with
.SS* Open Sequence Traversal
-Functions in this category perform efficient traversal of sequences
-of various kinds.
+Functions in this category perform efficient traversal of sequences.
+
+There are two flavors of these functions: functions in the
+.code iter-begin
+group, and functions in the
+.code seq-begin
+group. The latter are obsolescent.
+
+.coNP Function @ iter-begin
+.synb
+.mets (iter-begin << seq )
+.syne
+.desc
+The
+.code iter-begin
+function returns an iterator object specialized for the task of traversing
+the sequence
+.metn seq .
+
+If
+.meta object
+isn't a sequence, an exception is thrown.
+
+Note: if
+.meta seq
+is a list-like sequence, then
+.code iter-begin
+may return
+.meta seq
+itself as the iterator.
+
+.coNP Function @ iter-more
+.synb
+.mets (iter-more << iter )
+.syne
+.desc
+The
+.code iter-more
+function returns
+.code t
+if there remain more elements to be traversed.
+Otherwise it returns
+.codn nil .
+
+The
+.meta iter
+argument must be a valid iterator returned by a call to
+.metn iter-begin ,
+.meta iter-step
+or
+.metn iter-reset .
+
+The
+.code iter-more
+function doesn't change the state of
+.metn iter .
+
+.coNP Function @ iter-item
+.synb
+.mets (iter-item << iter )
+.syne
+.desc
+If the
+.code iter-more
+function indicates that more items remain to be visited, then
+the next item can be retrieved using
+.codn iter-item .
+
+The
+.meta iter
+argument must be a valid iterator returned by a call to
+.metn iter-begin ,
+.meta iter-step
+or
+.metn iter-reset .
+
+The
+.code iter-more
+function doesn't change the state of
+.metn iter .
+
+If
+.code iter-more
+is invoked on an iterator which indicates that no more items
+remain to be visited, the return value is
+.codn nil .
+
+.coNP Function @ iter-step
+.synb
+.mets (iter-step << iter )
+.syne
+.desc
+If the
+.code iter-more
+function indicates that more items remain to be visited, then the
+.code iter-step
+function may be used to consume the next item.
+
+The function returns an iterator denoting the traversal of the
+remaining items in the sequence.
+
+The
+.meta iter
+argument must be a valid iterator returned by a call to
+.metn iter-begin ,
+.meta iter-step
+or
+.metn iter-reset .
+
+The
+.code iter-step
+function may return a new object, in which case it avoids
+changing the state of
+.metn iter ,
+or else it may change the state of
+.meta iter
+and return it.
+
+If the application discontinues the use of
+.metn iter ,
+and continues the
+traversal using the returned iterator, it will work correctly in either
+situation.
+
+If
+.code iter-step
+is invoked on an iterator which indicates that no more items
+remain to be visited, the return value is unspecified.
+
+.coNP Function @ iter-reset
+.synb
+.mets (iter-reset < iter << seq )
+.syne
+.desc
+The
+.code iter-reset
+function returns an iterator object specialized for the task of traversing
+the sequence
+.metn seq .
+
+If it is possible for
+.meta iter
+to be that object, then the function may adjust the state of
+.meta iter
+and return it.
+
+If
+.code iter-reset
+doesn't use
+.metn iter ,
+then it behaves exactly like
+.code iter-begin
+being invoked on
+.metn seq .
.coNP Function @ seq-begin
.synb
.mets (seq-begin << object )
.syne
.desc
-The
+The obsolescent
.code seq-begin
function returns an iterator object specialized to the task of traversing
the sequence represented by the input
@@ -33111,7 +33263,7 @@ is not suitable for indefinite iteration over infinite lists.
.mets (seq-next < iter << end-value )
.syne
.desc
-The
+The obsolescent
.code seq-next
function retrieves the next available item from the sequence iterated by
.metn iter ,
@@ -33132,7 +33284,7 @@ freshly allocated object.
.mets (seq-reset < iter << object )
.syne
.desc
-The
+The obsolescent
.code seq-reset
re-initializes the existing iterator object
.meta iter