shithub: mc

Download patch

ref: 82782ab0efcb28ec8263a56e59d560aec49bdc66
parent: 507aaa9c4ded77834703eec0961757f8e535de2e
author: Ori Bernstein <[email protected]>
date: Tue Jan 3 20:06:04 EST 2012

Implement symtabs.

--- 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
         ;
--- 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/node.c
+++ b/parse/node.c
@@ -199,29 +199,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 +221,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 +228,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;
@@ -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 */
@@ -309,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);
@@ -333,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;
@@ -231,7 +262,7 @@
     }
 }
 
-/*static*/ Type *rdtype(FILE *fd)
+static Type *rdtype(FILE *fd)
 {
     Type *ty;
     Ty t;
--- /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);
+}
+