shithub: mc

Download patch

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