ref: 12b66049f3881fa6b36ed803358c659a96071e16
parent: 6b42532ddf1b3ebfd1c5b9b369f8478a7d8711ea
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Aug 26 15:17:20 EDT 2017
Add monotonically increasing equality check. Because unlike the bit sets, nothing gets removed from here, we should either converge on equality, or error out.
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -120,7 +120,7 @@
struct Type {
Ty type;
- int tid;
+ uint32_t tid;
Srcloc loc;
Vis vis;
--- a/parse/type.c
+++ b/parse/type.c
@@ -15,6 +15,7 @@
#include "parse.h"
typedef struct Typename Typename;
+typedef struct Typair Typair;
Type **tytab = NULL;
Type **types = NULL;
size_t ntypes;
@@ -22,7 +23,14 @@
size_t ntraittab;
Node **impltab;
size_t nimpltab;
+Htab *eqcache;
+struct Typair {
+ uint32_t atid;
+ uint32_t btid;
+};
+
+
static Htab *tydeduptab;
/* Built in type constraints */
static int tybfmt(char *buf, size_t len, Bitset *visted, Type *t);
@@ -715,7 +723,44 @@
return hash;
}
+ulong
+typairhash(void *pp)
+{
+ Typair *p;
+
+ p = pp;
+ return inthash(p->atid) ^ inthash(p->btid);
+}
+
int
+typaireq(void *a, void *b)
+{
+ Typair *pa, *pb;
+ pa = a;
+ pb = b;
+ return pa->atid == pb->atid && pa->btid == pb->btid;
+}
+
+void
+equate(int32_t ta, int32_t tb)
+{
+ Typair *pa, *pb;
+
+ /*
+ * unfortunately, we can't negatively cache
+ * here because tyvars may unify down and
+ * eventually make the negative result inaccurate.
+ */
+ pa = zalloc(sizeof(Typair));
+ *pa = (Typair){ta, tb};
+ pb = zalloc(sizeof(Typair));
+ *pb = (Typair){ta, tb};
+
+ htput(eqcache, pa, pa);
+ htput(eqcache, pb, pb);
+}
+
+int
tyeq_rec(Type *a, Type *b, Bitset *avisited, Bitset *bvisited, int search)
{
Type *x, *y;
@@ -736,6 +781,8 @@
return 0;
if (a->nmemb != b->nmemb)
return 0;
+ if (hthas(eqcache, &(Typair){a->tid, b->tid}))
+ return 1;
if (a->tid == b->tid)
return 1;
@@ -784,16 +831,22 @@
break;
}
break;
+ case Tygeneric:
+ if (!nameeq(a->name, b->name))
+ ret = 0;
+ for (i = 0; i < a->ngparam; i++) {
+ ret = ret && tyeq_rec(a->gparam[i], b->gparam[i], avisited, bvisited, search);
+ if (!ret)
+ break;
+ }
+ break;
case Tyname:
if (!nameeq(a->name, b->name))
ret = 0;
for (i = 0; i < a->narg; i++) {
- x = a->arg[i];
- y = b->arg[i];
- if (!tyeq_rec(x, y, avisited, bvisited, search)) {
- ret = 0;
+ ret = ret && tyeq_rec(a->arg[i], b->arg[i], avisited, bvisited, search);
+ if (!ret)
break;
- }
}
break;
case Tyarray:
@@ -813,6 +866,8 @@
}
}
}
+ if (ret) {
+ }
bsdel(avisited, a->tid);
bsdel(bvisited, b->tid);
@@ -1026,6 +1081,7 @@
Type *ty;
Trait *tr;
+ eqcache = mkht(typairhash, typaireq);
tydeduptab = mkht(tyhash, tystricteq);
/* this must be done after all the types are created, otherwise we will
* clobber the memoized bunch of types with the type params. */