summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-07-02 06:21:35 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-07-02 06:21:35 -0700
commit6c9d1315ca6da5f3b5d365d952259480be5b7e58 (patch)
treef4d43ca5d3f8be5d6d2b67768be89c6005bd9dfd
parentf3101cf296dfa0c7f97fd573ded8409905ae9ca1 (diff)
downloadtxr-6c9d1315ca6da5f3b5d365d952259480be5b7e58.tar.gz
txr-6c9d1315ca6da5f3b5d365d952259480be5b7e58.tar.bz2
txr-6c9d1315ca6da5f3b5d365d952259480be5b7e58.zip
New function: iterable.
* eval.c (eval_init): Register iterable intrinsic. * lib.c (seq_iterable): New static function. (nullify): Use seq_iterable to simplify function. (iterable): New function. * lib.h (iterable): Declared. * txr.1: Documented.
-rw-r--r--eval.c1
-rw-r--r--lib.c47
-rw-r--r--lib.h1
-rw-r--r--txr.124
4 files changed, 69 insertions, 4 deletions
diff --git a/eval.c b/eval.c
index f0a1c90d..f1e0a53e 100644
--- a/eval.c
+++ b/eval.c
@@ -6942,6 +6942,7 @@ void eval_init(void)
reg_fun(intern(lit("uni"), user_package), func_n4o(uni, 2));
reg_fun(intern(lit("seqp"), user_package), func_n1(seqp));
+ reg_fun(intern(lit("iterable"), user_package), func_n1(iterable));
reg_fun(intern(lit("list-seq"), user_package), func_n1(list_seq));
reg_fun(intern(lit("vec-seq"), user_package), func_n1(vec_seq));
reg_fun(intern(lit("str-seq"), user_package), func_n1(str_seq));
diff --git a/lib.c b/lib.c
index 766fa817..dd667b7a 100644
--- a/lib.c
+++ b/lib.c
@@ -328,6 +328,38 @@ seq_info_t seq_info(val obj)
return ret;
}
+static val seq_iterable(seq_info_t si)
+{
+ if (si.kind != SEQ_NOTSEQ)
+ return t;
+
+ switch (si.type) {
+ case RNG:
+ {
+ val rf = from(si.obj);
+
+ switch (type(rf)) {
+ case NUM:
+ case CHR:
+ case BGNUM:
+ return t;
+ default:
+ break;
+ }
+ }
+ break;
+ case CHR:
+ case NUM:
+ case BGNUM:
+ case FLNUM:
+ return t;
+ default:
+ break;
+ }
+
+ return nil;
+}
+
static void noreturn unsup_obj(val self, val obj)
{
uw_throwf(error_s, lit("~a: unsupported object ~s"), self, obj, nao);
@@ -1459,16 +1491,17 @@ val tolist(val seq)
val nullify(val obj)
{
val self = lit("nullify");
- val elem;
seq_info_t si = seq_info(obj);
- if (si.kind == SEQ_NOTSEQ && si.type != RNG) {
- return obj;
- } else {
+ if (seq_iterable(si))
+ {
seq_iter_t iter;
+ val elem;
seq_iter_init_with_info(self, &iter, si, 0);
return if2(seq_peek(&iter, &elem), obj);
}
+
+ return si.obj;
}
val empty(val seq)
@@ -1487,6 +1520,12 @@ val seqp(val obj)
return tnil(si.kind != SEQ_NOTSEQ);
}
+val iterable(val obj)
+{
+ seq_info_t si = seq_info(obj);
+ return seq_iterable(si);
+}
+
val list_seq(val seq)
{
val self = lit("list-seq");
diff --git a/lib.h b/lib.h
index 84de4c4b..e50ba931 100644
--- a/lib.h
+++ b/lib.h
@@ -619,6 +619,7 @@ val tolist(val seq);
val nullify(val obj);
val empty(val seq);
val seqp(val obj);
+val iterable(val obj);
val list_seq(val seq);
val vec_seq(val seq);
val str_seq(val seq);
diff --git a/txr.1 b/txr.1
index 05c96ae7..e0bbd032 100644
--- a/txr.1
+++ b/txr.1
@@ -29342,6 +29342,30 @@ methods are considered sequences.
No other objects are sequences. However, future revisions of
the language may specify additional objects that are sequences.
+.coNP Function @ iterable
+.synb
+.mets (iterable << object )
+.syne
+.desc
+The
+.code iterable
+function returns
+.code t
+if
+.meta object
+is iterable, otherwise
+.conp nil .
+
+If
+.meta object
+is a sequence according to the
+.code seqp
+function, then it is iterable.
+
+Additional objects that are not sequences are also iterable:
+numeric or character ranges, and numbers. Future revisions
+of the language may specify additional iterable objects.
+
.coNP Function @ make-like
.synb
.mets (make-like < list << object )