From 6c9d1315ca6da5f3b5d365d952259480be5b7e58 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 2 Jul 2020 06:21:35 -0700 Subject: 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. --- eval.c | 1 + lib.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- lib.h | 1 + txr.1 | 24 ++++++++++++++++++++++++ 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 ) -- cgit v1.2.3