ref: 254736fb93f759fa95d4c89041aba062b383a5fc
parent: 65d803f25c3311d3918a743ce174350abe2b5833
author: Ori Bernstein <[email protected]>
date: Sun May 13 11:54:47 EDT 2012
Infer compound types with members properly.
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -12,6 +12,9 @@
#include "parse.h"
+static Node **checkmemb;
+static size_t ncheckmemb;
+
static void infernode(Node *n, Type *ret, int *sawret);
static void inferexpr(Node *n, Type *ret, int *sawret);
@@ -25,18 +28,23 @@
st->super = super;
}
+static Node **aggrmemb(Type *t, int *n)
+{
+ *n = t->nmemb;
+ switch (t->type) {
+ case Tystruct: return t->sdecls; break;
+ case Tyunion: return t->udecls; break;
+ case Tyenum: return t->edecls; break;
+ default: return NULL;
+ }
+}
+
static void tyresolve(Type *t)
{
int i, nn;
Node **n;
- nn = t->nmemb;
- switch (t->type) {
- case Tystruct: n = t->sdecls; break;
- case Tyunion: n = t->udecls; break;
- case Tyenum: n = t->edecls; break;
- default: return;
- }
+ n = aggrmemb(t, &nn);
for (i = 0; i < nn; i++)
infernode(n[i], NULL, NULL);
}
@@ -128,6 +136,7 @@
return NULL;
}
+
static Type *type(Node *n)
{
Type *t;
@@ -304,7 +313,8 @@
/* special cases */
case Omemb: /* @a.Ident -> @b, verify type(@a.Ident)==@b later */
- die("members not done yet");
+ settype(n, mktyvar(n->line));
+ lappend(&checkmemb, &ncheckmemb, n);
break;
case Osize: /* sizeof @a -> size */
die("inference of sizes not done yet");
@@ -454,10 +464,6 @@
}
}
-static void infercompn(Node *n)
-{
-}
-
static void checkcast(Node *n)
{
}
@@ -484,6 +490,34 @@
if (t->type == Tyvar)
fatal(t->line, "underconstrained type %s near %s", tyfmt(buf, 1024, t), ctxstr(ctx));
return t;
+}
+
+static char *namestr(Node *name)
+{
+ assert(name->type == Nname);
+ return name->name.parts[0];
+}
+
+static void infercompn(Node *file)
+{
+ int i, j, nn;
+ Node *aggr;
+ Node *memb;
+ Node *n;
+ Node **nl;
+
+ for (i = 0; i < ncheckmemb; i++) {
+ n = checkmemb[i];
+ aggr = checkmemb[i]->expr.args[0];
+ memb = checkmemb[i]->expr.args[1];
+
+ nl = aggrmemb(aggr->expr.type, &nn);
+ for (j = 0; j < nn; j++) {
+ if (!strcmp(namestr(memb), declname(nl[i])))
+ break;
+ }
+ unify(n, n->expr.type, decltype(nl[i]));
+ }
}
static void typesub(Node *n)
--- a/parse/type.c
+++ b/parse/type.c
@@ -413,15 +413,6 @@
#include "cstr.def"
#undef Tc
-/* define and register the type */
-#define Ty(t, n) {\
- ty = mkty(-1, t); \
- if (n) { \
- puttype(st, mkname(-1, n), ty); \
- }}
-#include "types.def"
-#undef Ty
-
/* bool :: tctest */
tycstrs[Tybool][0] = cstrtab[Tctest];
@@ -461,4 +452,15 @@
tycstrs[Tyslice][0] = cstrtab[Tcidx];
tycstrs[Tyslice][1] = cstrtab[Tcslice];
tycstrs[Tyslice][1] = cstrtab[Tctest];
+
+/* Definining and registering the types has to go after we define the
+ * constraints, otherwise they will have no constraints set on them. */
+#define Ty(t, n) {\
+ ty = mkty(-1, t); \
+ if (n) { \
+ puttype(st, mkname(-1, n), ty); \
+ }}
+#include "types.def"
+#undef Ty
+
}