ref: dd7fbc0240b45fafd4d380b328b196661ea750cf
parent: 85cdc11b3ad306110ae43fe5b35c04c37cd776fd
author: Ori Bernstein <[email protected]>
date: Sat Dec 24 11:29:50 EST 2011
Do type substitutions.
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -68,8 +68,8 @@
static void outnode(Node *n, FILE *fd, int depth)
{
int i;
+ char *ty;
-
indent(fd, depth);
if (!n) {
fprintf(fd, "Nil\n");
@@ -117,7 +117,9 @@
fprintf(fd, " (name = %s, islocal = %d)\n", n->use.name, n->use.islocal);
break;
case Nexpr:
- fprintf(fd, " (op = %s, flags = %d)\n", opstr(n->expr.op), n->expr.isconst);
+ ty = tystr(n->expr.type);
+ fprintf(fd, " (type = %s, op = %s, flags = %d)\n", ty, opstr(n->expr.op), n->expr.isconst);
+ free(ty);
for (i = 0; i < n->expr.nargs; i++)
outnode(n->expr.args[i], fd, depth+1);
break;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -16,8 +16,15 @@
static Type *tf(Type *t)
{
assert(t != NULL);
- while (typetab[t->tid])
- t = typetab[t->tid];
+
+ if (typetab[t->tid]) {
+ printf ("%s => ", tystr(t));
+ while (typetab[t->tid]) {
+ t = typetab[t->tid];
+ printf("%s => ", tystr(t));
+ }
+ printf("nil\n");
+ }
return t;
}
@@ -34,6 +41,14 @@
/* a => b */
static void settype(Node *n, Type *t)
{
+ switch (n->type) {
+ case Nexpr: n->expr.type = t; break;
+ case Ndecl: n->decl.sym->type = t; break;
+ default:
+ die("can't set type of %s", nodestr(n->type));
+ break;
+ }
+
}
static Op exprop(Node *e)
@@ -42,14 +57,28 @@
return e->expr.op;
}
+static Type *littype(Node *n)
+{
+ switch (n->lit.littype) {
+ case Lchr: return mktyvar(n->line); break;
+ case Lbool: return mktyvar(n->line); break;
+ case Lint: return mktyvar(n->line); break;
+ case Lflt: return mktyvar(n->line); break;
+ case Lstr: return mktyvar(n->line); break;
+ case Lfunc: return NULL; break;
+ case Larray: return NULL; break;
+ };
+ return NULL;
+}
+
static Type *type(Node *n)
{
Type *t;
switch (n->type) {
- case Nlit: t = littypes[n->lit.littype]; break;
- case Nexpr: t = n->expr.type; break;
- case Ndecl: t = decltype(n); break;
+ case Nlit: t = littype(n); break;
+ case Nexpr: t = n->expr.type; break;
+ case Ndecl: t = decltype(n); break;
default:
t = NULL;
die("untypeable %s", nodestr(n->type));
@@ -105,6 +134,10 @@
assert(n->type == Nexpr);
args = n->expr.args;
nargs = n->expr.nargs;
+ for (i = 0; i < nargs; i++)
+ /* Nlit, Nvar, etc should not be inferred as exprs */
+ if (args[i]->type == Nexpr)
+ inferexpr(args[i], ret);
switch (exprop(n)) {
/* all operands are same type */
case Oadd: /* @a + @a -> @a */
@@ -194,7 +227,7 @@
settype(n, decltype(n));
break;
case Olit: /* <lit>:@a::tyclass -> @a */
- settype(n, type(n));
+ settype(n, type(args[0]));
break;
case Olbl: /* :lbl -> void* */
settype(n, mktyptr(n->line, mkty(-1, Tyvoid)));
@@ -268,6 +301,48 @@
static void typesub(Node *n)
{
+ int i;
+
+ switch (n->type) {
+ case Nfile:
+ for (i = 0; i < n->file.nstmts; i++)
+ typesub(n->file.stmts[i]);
+ break;
+ case Ndecl:
+ settype(n, tf(type(n)));
+ if (n->decl.init)
+ typesub(n->decl.init);
+ break;
+ case Nblock:
+ for (i = 0; i < n->block.nstmts; i++)
+ typesub(n->block.stmts[i]);
+ break;
+ case Nifstmt:
+ typesub(n->ifstmt.cond);
+ typesub(n->ifstmt.iftrue);
+ typesub(n->ifstmt.iffalse);
+ break;
+ case Nloopstmt:
+ typesub(n->loopstmt.cond);
+ typesub(n->loopstmt.init);
+ typesub(n->loopstmt.step);
+ typesub(n->loopstmt.body);
+ break;
+ case Nexpr:
+ settype(n, tf(type(n)));
+ for (i = 0; i < n->expr.nargs; i++)
+ typesub(n->expr.args[i]);
+ break;
+ case Nfunc:
+ die("don't do funcs yet...");
+ typesub(n);
+ break;
+ case Nname:
+ case Nlit:
+ case Nuse:
+ case Nlbl:
+ break;
+ }
}
void infer(Node *file)