summaryrefslogtreecommitdiffstats
path: root/struct.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-09-01 07:25:10 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-09-01 07:25:10 -0700
commitc8332b8695ca6a9748fc8ab2fd9e3f9fe74240e8 (patch)
treed870b99fb30cc2a104478278e93eae4e3002af28 /struct.c
parentf8963593eb0fbac6f101542f9673507462553ce1 (diff)
downloadtxr-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.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/struct.c b/struct.c
index 28cbec2a..0dc0dc1e 100644
--- a/struct.c
+++ b/struct.c
@@ -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,
};