diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-07-09 07:42:28 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-07-09 07:42:28 -0700 |
commit | 618a854df42cb43e410ba488a6634dae16a3e36f (patch) | |
tree | 1f143263a194f7bb565dc7bf718a9388906bc63d /lib.c | |
parent | 35e464c8cbd8a5ce386cc2d095ae916bf9d9a118 (diff) | |
download | txr-618a854df42cb43e410ba488a6634dae16a3e36f.tar.gz txr-618a854df42cb43e410ba488a6634dae16a3e36f.tar.bz2 txr-618a854df42cb43e410ba488a6634dae16a3e36f.zip |
subtypep: handle COBJ inheritance.
* lib.c (class_from_sym): New static function.
(subtypep): Remove special case handling of stream versus
stdio-stream. If the two types are not both structures, then
check whether they are both cobj classes. If so, check if they
are in an inheritance relationship via the cobj_hash.
(cobj_populate_hash): Map each symbol to a fixnum integer
which gives class handle'position in the cobj_class table.
(cobj_class_exists): Style: compare to nil instead of 0.
(obj_init): Do not call cobj_populate_hash here, it is far too
early: only a couple of COBJ types exist at this point.
Moreover, hash_init has not been called so hash_cls and
hash_iter_cls still have null symbols.
(init): Call obj_populate_hash here, as the last step.
* tests/012/type.tl: New file.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 40 |
1 files changed, 30 insertions, 10 deletions
@@ -252,6 +252,12 @@ val typeof(val obj) } } +static struct cobj_class *class_from_sym(val cls_sym) +{ + val idx = gethash(cobj_hash, cls_sym); + return idx ? cobj_class + c_n(idx) : 0; +} + val subtypep(val sub, val sup) { if (sub == sup) { @@ -284,16 +290,30 @@ val subtypep(val sub, val sup) sub == lcons_s || sub == list_s || sub == string_s); } else if (sup == string_s) { return tnil(sub == str_s || sub == lit_s || sub == lstr_s); - } else if (sup == stream_s) { - return tnil(sub == stdio_stream_s); } else if (sup == struct_s) { return tnil(find_struct_type(sub)); } else { - val sub_struct = find_struct_type(sub); - val sup_struct = find_struct_type(sup); + { + val sub_struct = find_struct_type(sub); + val sup_struct = find_struct_type(sup); + + if (sub_struct && sup_struct) + return struct_subtype_p(sub_struct, sup_struct); + } + + { + struct cobj_class *sub_cls = class_from_sym(sub); + struct cobj_class *sup_cls = class_from_sym(sup); - if (sub_struct && sup_struct) - return struct_subtype_p(sub_struct, sup_struct); + if (sub_cls && sup_cls) { + struct cobj_class *pcls = sub_cls; + do { + if (pcls == sup_cls) + return t; + pcls = pcls->super; + } while (pcls); + } + } return nil; } @@ -9183,12 +9203,12 @@ static void cobj_populate_hash(void) { struct cobj_class *ptr; for (ptr = cobj_class; ptr < cobj_ptr; ptr++) - sethash(cobj_hash, ptr->cls_sym, ptr->cls_sym); + sethash(cobj_hash, ptr->cls_sym, num_fast(ptr - cobj_class)); } int cobj_class_exists(val cls_sym) { - return gethash(cobj_hash, cls_sym) != 0; + return gethash(cobj_hash, cls_sym) != nil; } val cobj(mem_t *handle, struct cobj_class *cls, struct cobj_ops *ops) @@ -12667,8 +12687,6 @@ static void obj_init(void) prog_string = string(progname); cobj_hash = make_hash(nil, nil, nil); - - cobj_populate_hash(); } static val simple_qref_args_p(val args, val pos) @@ -13916,6 +13934,8 @@ void init(val *stack_bottom) time_init(); chksum_init(); + cobj_populate_hash(); + gc_state(gc_save); } |