ref: da4e9c9216aeb8455dfd972956e29942fd9d4690
parent: 3e73a19648bd78bb9defb1ccb458f21206450fe2
author: Ori Bernstein <[email protected]>
date: Sun Jun 24 08:04:52 EDT 2012
A number of misc fixes I can't be arsed to separate.
binary files a/8/8m b/8/8m differ
--- a/8/isel.c
+++ b/8/isel.c
@@ -62,6 +62,7 @@
l = locmem(-stkoff, locphysreg(Rebp), NULL, ModeL);
} else if (hthas(s->globls, n)) {
l = locstrlbl(htget(s->globls, n));
+ assert(!strcmp(namestr(n->expr.args[0]), l->lbl));
} else {
die("%s (id=%ld) not found", namestr(n->expr.args[0]), n->expr.did);
}
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -100,6 +100,7 @@
%token<tok> Tendln /* ; or \n */
%token<tok> Tendblk /* ;; */
%token<tok> Tcolon /* : */
+%token<tok> Tcoloncolon /* :: */
%token<tok> Tdot /* . */
%token<tok> Tcomma /* , */
%token<tok> Tret /* -> */
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -19,7 +19,10 @@
static Node **genericdecls;
static size_t ngenericdecls;
static Node **specializations;
+static Node **specializations;
static size_t nspecializations;
+static Stab **specializationscope;
+static size_t nspecializationscope;
static void infernode(Node *n, Type *ret, int *sawret);
static void inferexpr(Node *n, Type *ret, int *sawret);
@@ -119,20 +122,6 @@
return t;
}
-/* does b satisfy all the constraints of a? */
-static int cstrcheck(Type *a, Type *b)
-{
- /* a has no cstrs to satisfy */
- if (!a->cstrs)
- return 1;
- /* b satisfies no cstrs; only valid if a requires none */
- if (!b->cstrs)
- return bscount(a->cstrs) == 0;
- /* if a->cstrs is a subset of b->cstrs, all of
- * a's constraints are satisfied by b. */
- return bsissubset(b->cstrs, a->cstrs);
-}
-
static void loaduses(Node *n)
{
size_t i;
@@ -215,6 +204,20 @@
}
}
+/* does b satisfy all the constraints of a? */
+static int cstrcheck(Type *a, Type *b)
+{
+ /* a has no cstrs to satisfy */
+ if (!a->cstrs)
+ return 1;
+ /* b satisfies no cstrs; only valid if a requires none */
+ if (!b->cstrs)
+ return bscount(a->cstrs) == 0;
+ /* if a->cstrs is a subset of b->cstrs, all of
+ * a's constraints are satisfied by b. */
+ return bsissubset(b->cstrs, a->cstrs);
+}
+
static void mergecstrs(Node *ctx, Type *a, Type *b)
{
if (b->type == Tyvar) {
@@ -228,7 +231,7 @@
} else {
if (!cstrcheck(a, b)) {
dump(file, stdout);
- fatal(ctx->line, "%s does not match constraints for %s near %s", tystr(a), tystr(b), ctxstr(ctx));
+ fatal(ctx->line, "%s missing constraints for %s near %s", tystr(b), tystr(a), ctxstr(ctx));
}
}
}
@@ -445,7 +448,7 @@
lappend(&postcheck, &npostcheck, n);
break;
case Osize: /* sizeof @a -> size */
- die("inference of sizes not done yet");
+ settype(n, mkty(n->line, Tyuint));
break;
case Ocall: /* (@a, @b, @c, ... -> @r)(@a,@b,@c, ... -> @r) -> @r */
unifycall(n);
@@ -484,6 +487,7 @@
settype(n, t);
n->expr.did = s->decl.did;
if (s->decl.isgeneric) {
+ lappend(&specializationscope, &nspecializationscope, curstab());
lappend(&specializations, &nspecializations, n);
lappend(&genericdecls, &ngenericdecls, s);
}
@@ -689,7 +693,7 @@
t = tf(t);
if (t->type == Tyvar) {
- if (hascstr(t, cstrtab[Tcint]) && cstrcheck(t, tyint))
+ if (hascstr(t, cstrtab[Tcint]) || cstrcheck(t, tyint))
return tyint;
} else {
if (t->type == Tyarray)
@@ -892,12 +896,15 @@
void specialize(Node *f)
{
- Node *name;
+ Node *d, *name;
size_t i;
for (i = 0; i < nspecializations; i++) {
- specializedcl(genericdecls[i], specializations[i]->expr.type, &name);
+ pushstab(specializationscope[i]);
+ d = specializedcl(genericdecls[i], specializations[i]->expr.type, &name);
specializations[i]->expr.args[0] = name;
+ specializations[i]->expr.did = d->decl.did;
+ popstab();
}
}
--- a/parse/node.c
+++ b/parse/node.c
@@ -54,7 +54,6 @@
n = mknode(line, Nexpr);
n->expr.op = op;
- n->expr.did = -1;
va_start(ap, op);
while ((arg = va_arg(ap, Node*)) != NULL)
lappend(&n->expr.args, &n->expr.nargs, arg);
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -13,6 +13,7 @@
#include "parse.h"
typedef struct Tydefn Tydefn;
+typedef struct Cstrdefn Cstrdefn;
struct Tydefn {
int line;
Node *name;
@@ -19,6 +20,12 @@
Type *type;
};
+struct Cstrdefn {
+ int line;
+ Node *name;
+ Cstr *cstr;
+};
+
#define Maxstabdepth 128
static Stab *stabstk[Maxstabdepth];
static int stabstkoff;
@@ -91,6 +98,18 @@
return NULL;
}
+Cstr *getcstr(Stab *st, Node *n)
+{
+ Cstrdefn *c;
+
+ do {
+ if ((c = htget(st->ty, n)))
+ return c->cstr;
+ st = st->super;
+ } while (st);
+ return NULL;
+}
+
Stab *getns(Stab *st, Node *n)
{
Stab *s;
@@ -126,11 +145,9 @@
void puttype(Stab *st, Node *n, Type *t)
{
- Type *ty;
Tydefn *td;
- ty = gettype(st, n);
- if (ty)
+ if (gettype(st, n))
fatal(n->line, "Type %s already defined", namestr(n));
td = xalloc(sizeof(Tydefn));
td->line = n->line;
@@ -137,6 +154,19 @@
td->name = n;
td->type = t;
htput(st->ty, td->name, td);
+}
+
+void putcstr(Stab *st, Node *n, Cstr *c)
+{
+ Cstrdefn *cd;
+
+ if (gettype(st, n))
+ fatal(n->line, "Type %s already defined", namestr(n));
+ cd = xalloc(sizeof(Tydefn));
+ cd->line = n->line;
+ cd->name = n;
+ cd->cstr = c;
+ htput(st->ty, cd->name, cd);
}
void putns(Stab *st, Stab *scope)
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -240,8 +240,8 @@
else if (c == '\n')
fatal(line, "Newlines not allowed in char lit");
};
- t = mktok(Tstrlit);
- t->str = strdupn(&fbuf[sstart], fidx - sstart);
+ t = mktok(Tchrlit);
+ t->str = strdupn(&fbuf[sstart], fidx - sstart - 1);
return t;
}
@@ -259,7 +259,12 @@
case '[': tt = Tosqbrac; break;
case ']': tt = Tcsqbrac; break;
case ',': tt = Tcomma; break;
- case ':': tt = Tcolon; break;
+ case ':':
+ if (match(':'))
+ tt = Tcoloncolon;
+ else
+ tt = Tcolon;
+ break;
case '~': tt = Tbnot; break;
case ';':
if (match(';'))
--- a/test/tests
+++ b/test/tests
@@ -37,6 +37,8 @@
B log-or E 1
B str E 102
B generic E 42
+B sizeof E 4
+B gsizeof E 5
F declmismatch
F infermismatch
F flow