summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-06-03 22:32:34 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-06-03 22:32:34 -0700
commitfff34360b061c93926826945d6c570da3c2fbcca (patch)
tree83c7e7b503eb18344f2a1c961f4405d1ba527f1b /lib.c
parent91c85dc6a85bef1c62743bd278ebeb8914bf8b4b (diff)
downloadtxr-fff34360b061c93926826945d6c570da3c2fbcca.tar.gz
txr-fff34360b061c93926826945d6c570da3c2fbcca.tar.bz2
txr-fff34360b061c93926826945d6c570da3c2fbcca.zip
seq_iter: integers and ranges become iterable.
I think with the iter-begin API, we have the the "Maxwell's Equations of Iteration". This not only works well for conses, but it extends to numbers and ranges. * lib.h (seq_iter_t): New union member ul, containing a new member lim. existing len member moved into ul union. * lib.c (seq_iter_get_vec, seq_iter_peek_vec): Adjust access of len, now wrapped in union. (seq_iter_get_range_cnum, seq_iter_peek_range_cnum, seq_iter_get_range_chr, seq_iter_peek_range_chr, seq_iter_get_range_bignum, seq_iter_peek_range_bignum, seq_iter_get_chr, seq_iter_peek_chr, seq_iter_get_num, seq_iter_peek_num): New static functions. (seq_iter_init_with_info): Support RNG object, further classifying the iteration based on the type of the from element. Support numbers and characters as iterable. (iter_begin, iter_more, iter_item, iter_step, iter_reset): Support numbers directly as unencapsulated iterators.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c186
1 files changed, 172 insertions, 14 deletions
diff --git a/lib.c b/lib.c
index cc8d00bb..a098be02 100644
--- a/lib.c
+++ b/lib.c
@@ -361,7 +361,7 @@ static int seq_iter_peek_list(seq_iter_t *it, val *pval)
static int seq_iter_get_vec(seq_iter_t *it, val *pval)
{
- if (it->ui.index < it->len) {
+ if (it->ui.index < it->ul.len) {
*pval = ref(it->inf.obj, num(it->ui.index++));
return 1;
}
@@ -370,7 +370,7 @@ static int seq_iter_get_vec(seq_iter_t *it, val *pval)
static int seq_iter_peek_vec(seq_iter_t *it, val *pval)
{
- if (it->ui.index < it->len) {
+ if (it->ui.index < it->ul.len) {
*pval = ref(it->inf.obj, num(it->ui.index));
return 1;
}
@@ -389,6 +389,92 @@ static int seq_iter_peek_hash(seq_iter_t *it, val *pval)
return *pval != nil;
}
+static int seq_iter_get_range_cnum(seq_iter_t *it, val *pval)
+{
+ if (it->ui.index < it->ul.len) {
+ *pval = num(it->ui.index++);
+ return 1;
+ }
+ return 0;
+}
+
+static int seq_iter_peek_range_cnum(seq_iter_t *it, val *pval)
+{
+ if (it->ui.index < it->ul.len) {
+ *pval = num(it->ui.index);
+ return 1;
+ }
+ return 0;
+}
+
+static int seq_iter_get_range_chr(seq_iter_t *it, val *pval)
+{
+ if (it->ui.index < it->ul.len) {
+ *pval = chr(it->ui.index++);
+ return 1;
+ }
+ return 0;
+}
+
+static int seq_iter_peek_range_chr(seq_iter_t *it, val *pval)
+{
+ if (it->ui.index < it->ul.len) {
+ *pval = chr(it->ui.index);
+ return 1;
+ }
+ return 0;
+}
+
+static int seq_iter_get_range_bignum(seq_iter_t *it, val *pval)
+{
+ if (lt(it->ui.iter, it->ul.lim)) {
+ *pval = it->ui.iter;
+ it->ui.iter = succ(it->ui.iter);
+ return 1;
+ }
+ return 0;
+}
+
+static int seq_iter_peek_range_bignum(seq_iter_t *it, val *pval)
+{
+ if (lt(it->ui.iter, it->ul.lim)) {
+ *pval = it->ui.iter;
+ return 1;
+ }
+ return 0;
+}
+
+static int seq_iter_get_chr(seq_iter_t *it, val *pval)
+{
+ if (it->ui.index <= 0x10FFFF) {
+ *pval = chr(it->ui.index++);
+ return 1;
+ }
+ return 0;
+}
+
+static int seq_iter_peek_chr(seq_iter_t *it, val *pval)
+{
+ if (it->ui.index <= 0x10FFFF) {
+ *pval = chr(it->ui.index);
+ return 1;
+ }
+ return 0;
+}
+
+static int seq_iter_get_num(seq_iter_t *it, val *pval)
+{
+ *pval = it->ui.iter;
+ it->ui.iter = succ(it->ui.iter);
+ return 1;
+}
+
+static int seq_iter_peek_num(seq_iter_t *it, val *pval)
+{
+ *pval = it->ui.iter;
+ return 1;
+}
+
val seq_geti(seq_iter_t *it)
{
val v = nil;
@@ -424,30 +510,78 @@ static void seq_iter_init_with_info(val self, seq_iter_t *it,
switch (it->inf.kind) {
case SEQ_NIL:
it->ui.iter = nil;
- it->len = 0;
+ it->ul.len = 0;
it->get = seq_iter_get_nil;
it->peek = seq_iter_peek_nil;
break;
case SEQ_LISTLIKE:
it->ui.iter = it->inf.obj;
- it->len = 0;
+ it->ul.len = 0;
it->get = seq_iter_get_list;
it->peek = seq_iter_peek_list;
break;
case SEQ_VECLIKE:
it->ui.index = 0;
- it->len = c_num(length(it->inf.obj));
+ it->ul.len = c_num(length(it->inf.obj));
it->get = seq_iter_get_vec;
it->peek = seq_iter_peek_vec;
break;
case SEQ_HASHLIKE:
it->ui.iter = hash_begin(it->inf.obj);
- it->len = 0;
+ it->ul.len = 0;
it->get = seq_iter_get_hash;
it->peek = seq_iter_peek_hash;
break;
default:
- unsup_obj(self, obj);
+ switch (it->inf.type) {
+ case RNG:
+ {
+ val rf = from(obj);
+ val rt = to(obj);
+
+ switch (type(rf))
+ {
+ case NUM:
+ it->ui.index = c_num(rf);
+ it->ul.len = c_num(rt);
+ it->get = seq_iter_get_range_cnum;
+ it->peek = seq_iter_peek_range_cnum;
+ break;
+ case CHR:
+ it->ui.index = c_chr(rf);
+ it->ul.len = c_chr(rt);
+ it->get = seq_iter_get_range_chr;
+ it->peek = seq_iter_peek_range_chr;
+ break;
+ case BGNUM:
+ it->ui.iter = rf;
+ it->ul.lim = rt;
+ it->get = seq_iter_get_range_bignum;
+ it->peek = seq_iter_peek_range_bignum;
+ break;
+ default:
+ unsup_obj(self, obj);
+ }
+ }
+ break;
+ case CHR:
+ it->ui.index = c_chr(it->inf.obj);
+ it->ul.len = 0;
+ it->get = seq_iter_get_chr;
+ it->peek = seq_iter_peek_chr;
+ break;
+ case NUM:
+ case BGNUM:
+ case FLNUM:
+ it->ui.iter = it->inf.obj;
+ it->ul.lim = nil;
+ it->get = seq_iter_get_num;
+ it->peek = seq_iter_peek_num;
+ break;
+ default:
+ unsup_obj(self, obj);
+ }
+ break;
}
}
@@ -544,13 +678,20 @@ val iter_begin(val obj)
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;
+ switch (sinf.type) {
+ case CHR:
+ case NUM:
+ case BGNUM:
+ return 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;
+ }
}
}
}
@@ -560,6 +701,11 @@ val iter_more(val iter)
switch (type(iter)) {
case NIL:
return nil;
+ case CHR:
+ return if2(c_chr(iter) <= 0x10FFFF, t);
+ case NUM:
+ case BGNUM:
+ return t;
case COBJ:
if (iter->co.cls == seq_iter_s)
{
@@ -578,6 +724,10 @@ val iter_item(val iter)
switch (type(iter)) {
case NIL:
return nil;
+ case CHR:
+ case NUM:
+ case BGNUM:
+ return iter;
case COBJ:
if (iter->co.cls == seq_iter_s)
{
@@ -596,6 +746,10 @@ val iter_step(val iter)
switch (type(iter)) {
case NIL:
return nil;
+ case CHR:
+ case NUM:
+ case BGNUM:
+ return plus(iter, one);
case COBJ:
if (iter->co.cls == seq_iter_s)
{
@@ -621,6 +775,10 @@ val iter_reset(val iter, val obj)
return sinf.obj;
default:
switch (type(iter)) {
+ case CHR:
+ case NUM:
+ case BGNUM:
+ return obj;
case COBJ:
if (iter->co.cls == seq_iter_s)
{