shithub: mc

Download patch

ref: c0af6b2f13dbc6b0a09986ad6ee4e2b8a06393c1
parent: 000472348577f453116a4fe4dd922546fd8466f9
parent: d47d4ee1be3d12dfde55d0b2a42c75c4cb57d51d
author: Ori Bernstein <[email protected]>
date: Wed Jan 4 05:44:30 EST 2012

Merge branch 'master' of git+ssh://eigenstate.org/git/ori/mc2

--- a/parse/Makefile
+++ b/parse/Makefile
@@ -8,6 +8,7 @@
     names.o \
     node.o \
     pickle.o \
+    stab.o \
     tok.o \
     type.o \
     use.o \
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -18,18 +18,24 @@
         fprintf(fd, " ");
 }
 
-static void outsym(Sym *s, FILE *fd, int depth)
+static void outname(Node *n, FILE *fd)
 {
     int i;
+    char *sep;
+    
+    sep = "";
+    for (i = 0; i < n->name.nparts; i++) {
+        fprintf(fd, "%s%s", sep, n->name.parts[i]);
+        sep = ".";
+    }
+}
+
+static void outsym(Sym *s, FILE *fd, int depth)
+{
     char buf[1024];
 
     indent(fd, depth);
-    fprintf(fd, "Sym ");
-    for (i = 0; i < s->name->name.nparts; i++) {
-        fprintf(fd, "%s", s->name->name.parts[i]);
-        if (i != s->name->name.nparts - 1)
-            fprintf(fd, ".");
-    }
+    outname(s->name, fd);
     fprintf(fd, " : %s\n", tyfmt(buf, 1024, s->type));
 }
 
@@ -40,24 +46,38 @@
 
 static void outstab(Stab *st, FILE *fd, int depth)
 {
-    int i;
+    int i, n;
+    void **k;
+    char *ty;
 
     indent(fd, depth);
     fprintf(fd, "Stab %p (super = %p)\n", st, st ? st->super : NULL);
     if (!st)
         return;
-    for (i = 0; i < st->ntypes; i++) {
+
+    /* print types */
+    k = htkeys(st->ty, &n);
+    for (i = 0; i < n; i++) {
         indent(fd, depth + 1);
         fprintf(fd, "T ");
         /* already indented */
-        outsym(st->types[i], fd, 0);
+        outname(k[i], fd); 
+        ty = tystr(gettype(st, k[i]));
+        fprintf(fd, " = %s", ty);
+        free(ty);
     }
-    for (i = 0; i < st->nsyms; i++) {
+    free(k);
+
+    k = htkeys(st->dcl, &n);
+    for (i = 0; i < n; i++) {
         indent(fd, depth + 1);
-        fprintf(fd, "V ");
+        fprintf(fd, "S ");
         /* already indented */
-        outsym(st->syms[i], fd, 0);
+        outsym(getdcl(st, k[i]), fd, 0);
     }
+    
+    /* FIXME: dump namespaces */
+    free(k);
 }
 
 void dumpstab(Stab *st, FILE *fd)
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -159,7 +159,7 @@
 toplev
         : decl
             {nlappend(&file->file.stmts, &file->file.nstmts, $1);
-             def(file->file.globls, $1);}
+             putdcl(file->file.globls, $1->decl.sym);}
         | use
             {nlappend(&file->file.uses, &file->file.nuses, $1);}
         | package
@@ -196,8 +196,8 @@
         | pkgbody pkgitem
         ;
 
-pkgitem : decl {def(file->file.exports, $1);}
-        | tydef {deftype($1.line, file->file.exports, $1.name, $1.type);}
+pkgitem : decl {putdcl(file->file.exports, $1->decl.sym);}
+        | tydef {puttype(file->file.exports, $1.name, $1.type);}
         | visdef {die("Unimplemented visdef");}
         | TEndln
         ;
@@ -523,7 +523,7 @@
 blockbody
         : stmt
             {
-                $$ = mkblock(line, NULL);
+                $$ = mkblock(line, mkstab(curscope));
                 nlappend(&$$->block.stmts, &$$->block.nstmts, $1);
             }
         | blockbody stmt
--- a/parse/htab.c
+++ b/parse/htab.c
@@ -122,7 +122,7 @@
     return htidx(ht, k) >= 0;
 }
 
-void **htkeys(Htab *ht)
+void **htkeys(Htab *ht, int *nkeys)
 {
     void **k;
     int i, j;
@@ -132,6 +132,7 @@
     for (i = 0; i < ht->sz; i++)
         if (ht->hashes[i])
             k[j++] = ht->keys[i];
+    *nkeys = ht->nelt;
     return k;
 }
 
@@ -142,6 +143,7 @@
     ulong g;
 
     s = _s;
+    h = 0;
     while (s && *s) {
         h = ((h << 4) + *s++);
 
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -34,10 +34,12 @@
     Bitset *s;
     int n;
 
-    if (a->cstrs)
+    /* 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 0;
+        return bscount(a->cstrs) == 0;
     /* if b->cstrs \ a->cstrs == 0, then all of
      * a's constraints are satisfied. */
     s = dupbs(b->cstrs);
--- a/parse/node.c
+++ b/parse/node.c
@@ -103,6 +103,7 @@
     f->func.args = args;
     f->func.nargs = nargs;
     f->func.body = body;
+    f->func.scope = mkstab(curscope);
 
     n = mknode(line, Nlit);
     n->lit.littype = Lfunc;
@@ -199,29 +200,6 @@
     return n->decl.sym->type;
 }
 
-void def(Stab *s, Node *n)
-{
-    assert(n->type == Ndecl);
-    slappend(&s->syms, &s->nsyms, n->decl.sym);
-}
-
-void deftype(int line, Stab *s, char *name, Type *ty)
-{
-    Sym *tysym;
-
-    tysym = mksym(line, mkname(line, name), ty);
-    slappend(&s->types, &s->ntypes, tysym);
-}
-
-Stab *mkstab(Stab *super)
-{
-    Stab *st;
-
-    st = zalloc(sizeof(Stab));
-    st->super = super;
-    return st;
-}
-
 void setns(Node *n, char *name)
 {
     int i;
@@ -244,17 +222,6 @@
     return n;
 }
 
-Sym *mksym(int line, Node *name, Type *ty)
-{
-    Sym *sym;
-
-    sym = zalloc(sizeof(Sym));
-    sym->name = name;
-    sym->type = ty;
-    sym->line = line;
-    return sym;
-}
-
 void nlappend(Node ***nl, size_t *len, Node *n)
 {
     *nl = xrealloc(*nl, (*len + 1)*sizeof(Node*));
@@ -262,9 +229,3 @@
     (*len)++;
 }
 
-void slappend(Sym ***sl, size_t *len, Sym *s)
-{
-    *sl = xrealloc(*sl, (*len + 1)*sizeof(Node*));
-    (*sl)[*len] = s;
-    (*len)++;
-}
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -74,17 +74,15 @@
 
 struct Stab {
     Stab *super;
-    char *name;
+    Node *name;
 
     /* Contents of stab.
      * types and values are in separate namespaces. */
-    size_t ntypes;
-    Sym **types;
-    size_t nsyms;
-    Sym **syms;
+    Htab *ns;
+    Htab *dcl;
+    Htab *ty;
 };
 
-/* reused for both decls and types */
 struct Sym {
     int   line;
     Node *name;
@@ -94,8 +92,8 @@
 struct Type {
     Ty type;
     int tid;
-    size_t nsub;      /* For fnsub, tusub, sdecls, udecls, edecls. */
     Bitset *cstrs;    /* the type constraints matched on this type */
+    size_t nsub;      /* For fnsub, tusub, sdecls, udecls, edecls. */
     Type **sub;       /* sub-types; shared by all composite types */
     union {
         Node *name;    /* Tyname: unresolved name */
@@ -231,7 +229,7 @@
 int htput(Htab *ht, void *k, void *v);
 void *htget(Htab *ht, void *k);
 int hthas(Htab *ht, void *k);
-void **htkeys(Htab *ht);
+void **htkeys(Htab *ht, int *nkeys);
 /* useful key types */
 ulong strhash(void *str);
 int streq(void *s1, void *s2);
@@ -253,8 +251,15 @@
 
 /* stab creation */
 Stab *mkstab(Stab *super);
-Stab *stput(Sym *decl);
-Sym  *stget(char *name);
+
+void putns(Stab *st, Stab *scope);
+void puttype(Stab *st, Node *n, Type *ty);
+void putdcl(Stab *st, Sym *s);
+
+Stab *getns(Stab *st, Node *n);
+Sym *getdcl(Stab *st, Node *n);
+Type *gettype(Stab *st, Node *n);
+
 Sym *mksym(int line, Node *name, Type *ty);
 
 /* type creation */
@@ -280,8 +285,6 @@
 int constrain(Type *t, Cstr *c);
 char *tyfmt(char *buf, size_t len, Type *t);
 char *tystr(Type *t);
-char *tyenc(Type *t);
-Type *tydec(char *s);
 
 void tlappend(Type ***tl, int *len, Type *t);
 
@@ -311,8 +314,6 @@
 Type *decltype(Node *n);
 void addstmt(Node *file, Node *stmt);
 void setns(Node *n, char *name);
-void def(Stab *s, Node *n);
-void deftype(int line, Stab *s, char *name, Type *t);
 
 /* usefiles */
 void readuse(Node *use, Stab *into);
@@ -335,7 +336,6 @@
 
 /* convenience func */
 void nlappend(Node ***nl, size_t *len, Node *n);
-void slappend(Sym ***sl, size_t *len, Sym *s);
 
 /* backend functions */
 void gen();
--- a/parse/pickle.c
+++ b/parse/pickle.c
@@ -52,7 +52,7 @@
         die("Unexpected EOF");
 }
 
-/*static*/ char rdbyte(FILE *fd)
+static char rdbyte(FILE *fd)
 {
     int c;
     c = fgetc(fd);
@@ -68,7 +68,7 @@
         die("Unexpected EOF");
 }
 
-/*static*/ int32_t rdint(FILE *fd)
+static int32_t rdint(FILE *fd)
 {
     uint32_t val;
 
@@ -137,7 +137,7 @@
     wrbyte(fd, val);
 }
 
-/*static*/ int rdbool(FILE *fd)
+static int rdbool(FILE *fd)
 {
     return rdbyte(fd);
 }
@@ -144,32 +144,63 @@
 
 static void wrstab(FILE *fd, Stab *val)
 {
-    int i;
+    int n, i;
+    void **keys;
 
-    wrstr(fd, val->name);
-    wrint(fd, val->ntypes);
-    for (i = 0; i < val->ntypes; i++)
-        wrsym(fd, val->types[i]);
-    wrint(fd, val->nsyms);
-    for (i = 0; i < val->nsyms; i++)
-        wrsym(fd, val->syms[i]);
+    pickle(val->name, fd);
+
+    /* write decls */
+    keys = htkeys(val->dcl, &n);
+    wrint(fd, n);
+    for (i = 0; i < n; i++)
+        wrsym(fd, htget(val->dcl, keys[i]));
+    free(keys);
+
+    /* write types */
+    keys = htkeys(val->ty, &n);
+    wrint(fd, n);
+    for (i = 0; i < n; i++) {
+        pickle(keys[i], fd); /* name */
+        wrtype(fd, htget(val->ty, keys[i])); /* type */
+    }
+    free(keys);
+
+    /* write stabs */
+    keys = htkeys(val->ns, &n);
+    wrint(fd, n);
+    for (i = 0; i < n; i++)
+        wrstab(fd, htget(val->ns, keys[i]));
+    free(keys);
 }
 
-/*static*/ Stab *rdstab(FILE *fd)
+static Stab *rdstab(FILE *fd)
 {
     Stab *st;
+    Type *ty;
+    Node *nm;
+    int n;
     int i;
 
+    /* read dcls */
     st = mkstab(NULL);
-    st->name = rdstr(fd);
-    st->ntypes = rdint(fd);
-    st->types = xalloc(sizeof(Sym*)*st->ntypes);
-    for (i = 0; i < st->ntypes; i++)
-        st->types[i] = rdsym(fd);
-    st->nsyms = rdint(fd);
-    st->syms = xalloc(sizeof(Sym*)*st->nsyms);
-    for (i = 0; i < st->nsyms; i++)
-        st->syms[i] = rdsym(fd);
+    st->name = unpickle(fd);
+    n = rdint(fd);
+    for (i = 0; i < n; i++)
+         putdcl(st, rdsym(fd));
+
+    /* read types */
+    n = rdint(fd);
+    for (i = 0; i < n; i++) {
+        nm = unpickle(fd);
+        ty = rdtype(fd);
+        puttype(st, nm, ty);
+    }
+
+    /* read stabs */
+    n = rdint(fd);
+    for (i = 0; i < n; i++)
+        putns(st, rdstab(fd));
+
     return st;
 }
 
@@ -180,7 +211,7 @@
     wrtype(fd, val->type);
 }
 
-/*static*/ Sym *rdsym(FILE *fd)
+static Sym *rdsym(FILE *fd)
 {
     int line;
     Node *name;
@@ -193,24 +224,90 @@
 }
 
 
-static void wrtype(FILE *fd, Type *t)
+static void wrtype(FILE *fd, Type *ty)
 {
-    char *enc;
+    int i;
 
-    enc = tyenc(t);
-    wrstr(fd, enc);
-    free(enc);
+    if (!ty) {
+        wrbyte(fd, Tybad);
+        return;
+    }
+    wrbyte(fd, ty->type);
+    /* tid is generated; don't write */
+    /* cstrs are left out for now: FIXME */
+    wrint(fd, ty->nsub);
+    switch (ty->type) {
+        case Tyname:
+            pickle(ty->name, fd);
+            break;
+        case Typaram:   
+            wrstr(fd, ty->pname);
+            break;
+        case Tystruct: 
+            for (i = 0; i < ty->nsub; i++)
+                pickle(ty->sdecls[i], fd);
+            break;
+        case Tyunion: 
+            for (i = 0; i < ty->nsub; i++)
+                pickle(ty->udecls[i], fd);
+            break;
+        case Tyenum: 
+            for (i = 0; i < ty->nsub; i++)
+                pickle(ty->edecls[i], fd);
+            break;
+        case Tyarray:
+            wrtype(fd, ty->sub[0]);
+            pickle(ty->asize, fd);
+            break;
+        default:
+            for (i = 0; i < ty->nsub; i++)
+                wrtype(fd, ty->sub[i]);
+            break;
+    }
 }
 
-/*static*/ Type *rdtype(FILE *fd)
+static Type *rdtype(FILE *fd)
 {
-    Type *t;
-    char *s;
+    Type *ty;
+    Ty t;
+    int i;
 
-    s = rdstr(fd);
-    t = tydec(s);
-    free(s);
-    return t;
+    t = rdbyte(fd);
+    if (t == Tybad)
+        return NULL;
+    ty = mkty(-1, t);
+    /* tid is generated; don't write */
+    /* cstrs are left out for now: FIXME */
+    ty->nsub = rdint(fd);
+    switch (ty->type) {
+        case Tyname:
+            ty->name = unpickle(fd);
+            break;
+        case Typaram:   
+            ty->pname = rdstr(fd);
+            break;
+        case Tystruct: 
+            for (i = 0; i < ty->nsub; i++)
+                ty->sdecls[i] = unpickle(fd);
+            break;
+        case Tyunion: 
+            for (i = 0; i < ty->nsub; i++)
+                ty->udecls[i] = unpickle(fd);
+            break;
+        case Tyenum: 
+            for (i = 0; i < ty->nsub; i++)
+                ty->edecls[i] = unpickle(fd);
+            break;
+        case Tyarray:
+            ty->sub[0] = rdtype(fd);
+            ty->asize = unpickle(fd);
+            break;
+        default:
+            for (i = 0; i < ty->nsub; i++)
+                ty->sub[i] = rdtype(fd);
+            break;
+    }
+    return ty;
 }
 
 /* pickle format:
--- /dev/null
+++ b/parse/stab.c
@@ -1,0 +1,127 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "parse.h"
+
+typedef struct Tydefn Tydefn;
+struct Tydefn {
+    int line;
+    Node *name;
+    Type *type;
+};
+
+
+static char *name(Node *n)
+{
+    return n->name.parts[n->name.nparts - 1];
+}
+
+static ulong namehash(void *n)
+{
+    return strhash(name(n));
+}
+
+static int ptreq(void *a, void *b)
+{
+    return a == b;
+}
+
+Sym *mksym(int line, Node *name, Type *ty)
+{
+    Sym *sym;
+
+    sym = zalloc(sizeof(Sym));
+    sym->name = name;
+    sym->type = ty;
+    sym->line = line;
+    return sym;
+}
+
+Stab *mkstab(Stab *super)
+{
+    Stab *st;
+
+    st = zalloc(sizeof(Stab));
+    st->super = super;
+    st->ns = mkht(namehash, ptreq);
+    st->dcl = mkht(namehash, ptreq);
+    st->ty = mkht(namehash, ptreq);
+    return st;
+}
+
+/* FIXME: do namespaces */
+Sym *getdcl(Stab *st, Node *n)
+{
+    Sym *s;
+    do {
+        if ((s = htget(st->dcl, n)))
+            return s;
+    } while (st->super);
+    return NULL;
+}
+
+Type *gettype(Stab *st, Node *n)
+{
+    Tydefn *t;
+    
+    do {
+        if ((t = htget(st->ty, n)))
+            return t->type;
+    } while (st->super);
+    return NULL;
+}
+
+Stab *getstab(Stab *st, Node *n)
+{
+    Stab *s;
+    do {
+        if ((s = htget(st->ns, n)))
+            return s;
+    } while (st->super);
+    return NULL;
+}
+
+void putdcl(Stab *st, Sym *s)
+{
+    Sym *d;
+
+    d = getdcl(st, s->name);
+    if (d)
+        fatal(s->line, "%s already declared (line %d", name(s->name), d->line);
+    htput(st->dcl, s->name, s);
+}
+
+void puttype(Stab *st, Node *n, Type *t)
+{
+    Type *ty;
+    Tydefn *td;
+
+    ty = gettype(st, n);
+    if (ty)
+        fatal(n->line, "Type %s already defined", name(n));
+    td = xalloc(sizeof(Tydefn));
+    td->line = n->line;
+    td->name = n;
+    td->type = t;
+    htput(st->ty, td->name, td);
+}
+
+void putns(Stab *st, Stab *scope)
+{
+    Stab *s;
+
+    s = getstab(st, scope->name);
+    if (s)
+        fatal(scope->name->line, "Ns %s already defined", name(s->name));
+    htput(st->ns, scope->name, scope);
+}
+
--- a/parse/type.c
+++ b/parse/type.c
@@ -367,156 +367,6 @@
     return strdup(buf);
 }
 
-static struct {
-    char enc;    /* character to encode */
-    int special; /* 0 => atomic, 1 => unary, 2 => nary, -1 => special-cased */
-} enctab[] = {
-    [Tybad]     = {'\0',0},
-    [Tyvoid]    = {'z', 0},
-
-    [Tybool]    = {'t', 0},
-    [Tychar]    = {'c', 0},
-
-    [Tyint8]    = {'h', 0},
-    [Tyint16]   = {'s', 0},
-    [Tyint]     = {'i', 0},
-    [Tyint32]   = {'l', 0},
-    [Tyint64]   = {'q', 0},
-    [Tylong]    = {'v', 0},
-
-    [Tybyte]    = {'b', 0},
-    [Tyuint8]   = {'H', 0},
-    [Tyuint16]  = {'S', 0},
-    [Tyuint]    = {'I', 0},
-    [Tyuint32]  = {'L', 0},
-    [Tyuint64]  = {'Q', 0},
-    [Tyulong]   = {'V', 0},
-
-    [Tyfloat32] = {'f', 0},
-    [Tyfloat64] = {'F', 0},
-
-    [Tyvalist]  = {'.', 1},
-    [Typtr]     = {'*', 1},
-    [Tyslice]   = {':', 1},
-    [Tyarray]   = {'$', 1},
-    [Tyfunc]    = {'<', 2},
-    [Tytuple]   = {',', 2},
-    [Tyvar]     = {'#', -1},
-    [Typaram]   = {'@', -1},
-    [Tyname]    = {'%', -1},
-    [Tystruct]  = {'^', -1},
-    [Tyunion]   = {'!', -1},
-    [Tyenum]    = {'/', -1},
-    [Ntypes]    = {'\0', 0}
-};
-
-static int encbuf(Type *t, char *buf, size_t len)
-{
-    char *p;
-    char *end;
-    int i;
-
-    p = buf;
-    end = buf + len;
-
-    if (len <= 0)
-        return 0;
-    *p++ = enctab[t->type].enc;
-    if (enctab[t->type].special == 1) {
-        encbuf(t->sub[0], p, end - p);
-    } else if (enctab[t->type].special == 2) {
-        p += snprintf(p, end - p, "%zd", t->nsub);
-        for (i = 0; i < t->nsub; i++)
-            encbuf(t->sub[i], p, end - p);
-    } else if (enctab[t->type].special == -1) {
-        switch (t->type) {
-            case Tyname:  p += namefmt(p, end - p, t->name); break;
-            case Tyvar:   die("Tyvar is not encodable");  break;
-            case Typaram: p += snprintf(p, end - p, "%s;", t->pname); break;
-            case Tystruct:
-            case Tyunion:
-            case Tyenum:
-            default:
-                die("type %s should not be special", tystr(t));
-        }
-        /* all special forms end with ';' */
-        snprintf(p, end - p, ";");
-    } else {
-        die("Don't know how to encode %s", tystr(t));
-    }
-    return p - buf;
-}
-
-char *tyenc(Type *t)
-{
-    char buf[1024];
-
-    encbuf(t, buf, 1024);
-    return strdup(buf);
-}
-
-static Type *decname(char *p)
-{
-    char *name;
-    char *parts[16];
-    char *startp;
-    int i;
-    Node *n;
-
-    i = 0;
-    name = p;
-    startp = p;
-    while (1) {
-        if (*p == '.' || *p == ';') {
-            if (i == 16)
-                die("too many parts to name %s", name);
-            parts[i++] = strdupn(startp, p - startp);
-            startp = p;
-        }
-        if (!*p)
-            die("bad decoded name %s", name);
-        if (*p == ';')
-            break;
-        if (*p == '.')
-            p++;
-        p++;
-    }
-
-    n = mkname(-1, parts[i - 1]);
-    i--;
-    for (; i > 0; i--)
-        setns(n, parts[i - 1]);
-    return mktynamed(-1, n);
-}
-
-Type *tydec(char *p)
-{
-    Ty i;
-    Type *t;
-
-    for (i = 0; i < Ntypes; i++) {
-        if (enctab[i].enc == *p)
-            break;
-    }
-    p++;
-    if (enctab[i].special == 0) {
-        t = mkty(-1, i);
-    } else if (enctab[i].special == 1) {
-        t = mkty(-1, i);
-        t->nsub = 1;
-        t->sub = xalloc(sizeof(Type*));
-        t->sub[0] = tydec(p);
-    } else {
-        switch (i) {
-            case Tyname: t = decname(p); break;
-            default:
-                die("Unimplemented tydec for %s", p);
-                break;
-        }
-    }
-    return t;
-}
-
 void tyinit(void)
 {
     int i;