summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-06-28 07:54:35 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-06-28 07:54:35 -0700
commit43323e1431d5919b8e296b37c38affe1228c27d1 (patch)
tree49a6bb7cdc3e5de1dbad3ec7136bdf1535309d51 /lib.c
parentdc7842296466eba508f791ef1f9a9c3b16f7d4da (diff)
downloadtxr-43323e1431d5919b8e296b37c38affe1228c27d1.tar.gz
txr-43323e1431d5919b8e296b37c38affe1228c27d1.tar.bz2
txr-43323e1431d5919b8e296b37c38affe1228c27d1.zip
seq_info: nullify bugfix.
A change in the nullify function to support hash tables has broken various functions which classify an object using seq_info, obtainig a SEQ_HASHLIKE kind, and then work with si.obj using hash functions. But si.obj has been nullified. An example of a broken function is find-max. Basically, this can be attributed to a careless use of nullify in seq_info. The purpose of nullify is to support code which treats any sequence as if it were a list. But seq_info doesn't do that; it classifies sequences and treats them according to their kind. Under seq_info, the only non-list objects that get treated as lists are list-like structures. For these it makes sense to call nullify, in case they have a nullify method. * lib.c (seq_info): Don't unconditionally call nullify on all COBJ objects. Only call nullify on struct objects. If that returns nil, then treat the object as SEQ_NIL; and if it returns an object different from the original, then recurse.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/lib.c b/lib.c
index 522128a6..9cc20045 100644
--- a/lib.c
+++ b/lib.c
@@ -268,17 +268,12 @@ seq_info_t seq_info(val obj)
seq_info_t ret;
type_t to = type(obj);
+ ret.obj = 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;
@@ -287,12 +282,23 @@ seq_info_t seq_info(val obj)
} else if (cls == carray_s) {
ret.kind = SEQ_VECLIKE;
} else if (obj_struct_p(obj)) {
- 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;
+ val sub = nullify(obj);
+
+ if (!sub) {
+ ret.kind = SEQ_NIL;
+ ret.obj = nil;
+ } else if (sub != obj) {
+ return seq_info(sub);
+ } else {
+ if (maybe_slot(obj, length_s))
+ ret.kind = SEQ_VECLIKE;
+ if (maybe_slot(obj, car_s))
+ ret.kind = SEQ_LISTLIKE;
+ if (maybe_slot(obj, car_s))
+ ret.kind = SEQ_LISTLIKE;
+ else
+ ret.kind = SEQ_NOTSEQ;
+ }
} else {
ret.kind = SEQ_NOTSEQ;
}