From 7c8076e433d8bd95a91a9392bdbc2b5ba019542d Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Wed, 12 Dec 2018 13:10:10 -0500 Subject: [PATCH] Added Cyc_is_list() --- include/cyclone/runtime.h | 1 + runtime.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/cyclone/runtime.h b/include/cyclone/runtime.h index 2f7668c5..69aa1fee 100644 --- a/include/cyclone/runtime.h +++ b/include/cyclone/runtime.h @@ -421,6 +421,7 @@ double MRG32k3a (double seed); int equal(object, object); object equalp(object, object); object Cyc_has_cycle(object lst); +object Cyc_is_list(object lst); //object Cyc_is_boolean(object o); #define Cyc_is_boolean(o) (make_boolean(o == boolean_f || o == boolean_t)) #define Cyc_is_pair(o) ((is_object_type(o) && ((list) o)->tag == pair_tag) ? boolean_t : boolean_f) diff --git a/runtime.c b/runtime.c index 6f84676d..204d9c34 100644 --- a/runtime.c +++ b/runtime.c @@ -779,6 +779,39 @@ object Cyc_has_cycle(object lst) } } +/** + * Predicate - is the object a proper list? + * Based on `Cyc_has_cycle` so it is safe to call on circular lists. + */ +object Cyc_is_list(object lst) +{ + object slow_lst, fast_lst; + if ((lst == NULL)){ + return boolean_t; + } else if (is_value_type(lst)) { + return boolean_f; + } else if (is_object_type(lst) && type_of(lst) != pair_tag) { + return boolean_f; + } + slow_lst = lst; + fast_lst = cdr(lst); + while (1) { + if (fast_lst == NULL) + return boolean_t; + if (Cyc_is_pair(fast_lst) == boolean_f) + return boolean_f; // Improper list + if ((cdr(fast_lst)) == NULL) + return boolean_t; + if (Cyc_is_pair(cdr(fast_lst)) == boolean_f) + return boolean_f; // Improper + if (slow_lst == fast_lst) + return boolean_t; // Cycle; we have a list + + slow_lst = cdr(slow_lst); + fast_lst = cddr(fast_lst); + } +} + /** * Write string representation of a double to a buffer. * Added code from Chibi Scheme to print a ".0" if the