summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index e71a9a73..99db73f0 100644
--- a/lib.c
+++ b/lib.c
@@ -150,6 +150,28 @@ int null_or_missing_p(val v);
val default_null_arg(val arg);
#endif
+const seq_kind_t seq_kind_tab[MAXTYPE+1] = {
+ SEQ_NIL, /* NIL */
+ SEQ_NOTSEQ, /* NUM */
+ SEQ_NOTSEQ, /* CHR */
+ SEQ_VECLIKE, /* LIT */
+ SEQ_LISTLIKE, /* CONS */
+ SEQ_VECLIKE, /* STR */
+ SEQ_NOTSEQ, /* SYM */
+ SEQ_NOTSEQ, /* PKG */
+ SEQ_NOTSEQ, /* FUN */
+ SEQ_VECLIKE, /* VEC */
+ SEQ_LISTLIKE, /* LCONS */
+ SEQ_VECLIKE, /* LSTR */
+ SEQ_NOTSEQ, /* COBJ */
+ SEQ_NOTSEQ, /* CPTR */
+ SEQ_NOTSEQ, /* ENV */
+ SEQ_NOTSEQ, /* BGNUM */
+ SEQ_NOTSEQ, /* FLNUM */
+ SEQ_NOTSEQ, /* RNG */
+ SEQ_VECLIKE, /* BUF */
+};
+
val identity(val obj)
{
return obj;
@@ -257,6 +279,44 @@ val typep(val obj, val type)
return subtypep(typeof(obj), type);
}
+seq_info_t seq_info(val obj)
+{
+ seq_info_t ret;
+ type_t to = type(obj);
+
+ if (to != COBJ) {
+ ret.obj = obj;
+ ret.type = to;
+ ret.kind = seq_kind_tab[to];
+ return ret;
+ }
+
+ ret.obj = obj = nullify(obj);
+
+ if (!obj || (ret.type = to = type(obj)) != COBJ) {
+ ret.kind = seq_kind_tab[to];
+ } else {
+ val cls = obj->co.cls;
+
+ if (cls == hash_s) {
+ ret.kind = SEQ_HASHLIKE;
+ } else if (cls == carray_s) {
+ ret.kind = SEQ_VECLIKE;
+ } else if (structp(cls)) {
+ if (maybe_slot(obj, length_s))
+ ret.kind = SEQ_VECLIKE;
+ if (maybe_slot(obj, car_s))
+ ret.kind = SEQ_LISTLIKE;
+ else
+ ret.kind = SEQ_NOTSEQ;
+ } else {
+ ret.kind = SEQ_NOTSEQ;
+ }
+ }
+
+ return ret;
+}
+
val throw_mismatch(val obj, type_t t)
{
type_mismatch(lit("~s is not of type ~s"), obj, code2type(t), nao);