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);
+}
+