diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-07-02 06:21:35 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-07-02 06:21:35 -0700 |
commit | 6c9d1315ca6da5f3b5d365d952259480be5b7e58 (patch) | |
tree | f4d43ca5d3f8be5d6d2b67768be89c6005bd9dfd | |
parent | f3101cf296dfa0c7f97fd573ded8409905ae9ca1 (diff) | |
download | txr-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.c | 1 | ||||
-rw-r--r-- | lib.c | 47 | ||||
-rw-r--r-- | lib.h | 1 | ||||
-rw-r--r-- | txr.1 | 24 |
4 files changed, 69 insertions, 4 deletions
@@ -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)); @@ -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"); @@ -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); @@ -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 ) |