diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-09-01 07:25:10 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-09-01 07:25:10 -0700 |
commit | c8332b8695ca6a9748fc8ab2fd9e3f9fe74240e8 (patch) | |
tree | d870b99fb30cc2a104478278e93eae4e3002af28 /struct.c | |
parent | f8963593eb0fbac6f101542f9673507462553ce1 (diff) | |
download | txr-c8332b8695ca6a9748fc8ab2fd9e3f9fe74240e8.tar.gz txr-c8332b8695ca6a9748fc8ab2fd9e3f9fe74240e8.tar.bz2 txr-c8332b8695ca6a9748fc8ab2fd9e3f9fe74240e8.zip |
equal comparison and hashing for structs.
* struct.c (struct_inst_equal, struct_inst_hash): New functions.
(struct_inst_ops): Wire new functions into operations table.
Diffstat (limited to 'struct.c')
-rw-r--r-- | struct.c | 38 |
1 files changed, 36 insertions, 2 deletions
@@ -477,6 +477,40 @@ static void struct_inst_mark(val obj) gc_mark(si->type); } +static val struct_inst_equal(val left, val right) +{ + struct struct_inst *ls = coerce(struct struct_inst *, left->co.handle); + struct struct_inst *rs = coerce(struct struct_inst *, right->co.handle); + struct struct_type *st = coerce(struct struct_type *, ls->type->co.handle); + cnum nslots = st->nslots, sl; + + if (rs->type != ls->type) + return nil; + + for (sl = 0; sl < nslots; sl++) + if (!equal(ls->slot[sl], rs->slot[sl])) + return nil; + + gc_hint(left); + gc_hint(right); + return t; +} + +static cnum struct_inst_hash(val obj) +{ + struct struct_inst *si = coerce(struct struct_inst *, obj->co.handle); + struct struct_type *st = coerce(struct struct_type *, si->type->co.handle); + cnum nslots = st->nslots, sl, out = c_num(hash_equal(si->type)); + + for (sl = 0; sl < nslots; sl++) { + val hash = hash_equal(si->slot[sl]); + out += c_num(hash); + out &= NUM_MAX; + } + + return out; +} + static struct cobj_ops struct_type_ops = { eq, struct_type_print, @@ -486,9 +520,9 @@ static struct cobj_ops struct_type_ops = { }; static struct cobj_ops struct_inst_ops = { - eq, + struct_inst_equal, struct_inst_print, cobj_destroy_free_op, struct_inst_mark, - cobj_hash_op + struct_inst_hash, }; |