ref: 4c9035bc17893e3e88b65b5c7d928670e2b5ae38
parent: 462ab9093119c6eaefabcca6767216df31df2e82
author: Ori Bernstein <[email protected]>
date: Sun Nov 20 19:10:29 EST 2011
Parse into symtabs. We can also dump them now.
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -18,7 +18,7 @@
fprintf(fd, " ");
}
-static void dumpsym(Sym *s, FILE *fd, int depth)
+static void outsym(Sym *s, FILE *fd, int depth)
{
int i;
char buf[1024];
@@ -33,11 +33,43 @@
fprintf(fd, " : %s\n", tyfmt(buf, 1024, s->type));
}
-static void dumpnode(Node *n, FILE *fd, int depth)
+void dumpsym(Sym *s, FILE *fd)
{
+ outsym(s, fd, 0);
+}
+
+static void outstab(Stab *st, FILE *fd, int depth)
+{
int i;
+ 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++) {
+ indent(fd, depth + 1);
+ fprintf(fd, "T ");
+ /* already indented */
+ outsym(st->types[i], fd, 0);
+ }
+ for (i = 0; i < st->nsyms; i++) {
+ indent(fd, depth + 1);
+ fprintf(fd, "V ");
+ /* already indented */
+ outsym(st->syms[i], fd, 0);
+ }
+}
+void dumpstab(Stab *st, FILE *fd)
+{
+ outstab(st, fd, 0);
+}
+
+static void outnode(Node *n, FILE *fd, int depth)
+{
+ int i;
+
+
indent(fd, depth);
if (!n) {
fprintf(fd, "Nil\n");
@@ -47,32 +79,39 @@
switch(n->type) {
case Nfile:
fprintf(fd, "(name = %s)\n", n->file.name);
+ indent(fd, depth + 1);
+ fprintf(fd, "Globls:\n");
+ outstab(n->file.globls, fd, depth + 2);
+ indent(fd, depth + 1);
+ fprintf(fd, "Exports:\n");
+ outstab(n->file.exports, fd, depth + 2);
for (i = 0; i < n->file.nuses; i++)
- dumpnode(n->file.uses[i], fd, depth + 1);
+ outnode(n->file.uses[i], fd, depth + 1);
for (i = 0; i < n->file.nstmts; i++)
- dumpnode(n->file.stmts[i], fd, depth + 1);
+ outnode(n->file.stmts[i], fd, depth + 1);
break;
case Ndecl:
fprintf(fd, "\n");
- dumpsym(n->decl.sym, fd, depth + 1);
- dumpnode(n->decl.init, fd, depth + 1);
+ outsym(n->decl.sym, fd, depth + 1);
+ outnode(n->decl.init, fd, depth + 1);
break;
case Nblock:
fprintf(fd, "\n");
+ outstab(n->block.scope, fd, depth + 1);
for (i = 0; i < n->block.nstmts; i++)
- dumpnode(n->block.stmts[i], fd, depth+1);
+ outnode(n->block.stmts[i], fd, depth+1);
break;
case Nifstmt:
fprintf(fd, "\n");
- dumpnode(n->ifstmt.cond, fd, depth+1);
- dumpnode(n->ifstmt.iftrue, fd, depth+1);
- dumpnode(n->ifstmt.iffalse, fd, depth+1);
+ outnode(n->ifstmt.cond, fd, depth+1);
+ outnode(n->ifstmt.iftrue, fd, depth+1);
+ outnode(n->ifstmt.iffalse, fd, depth+1);
break;
case Nloopstmt:
- dumpnode(n->loopstmt.init, fd, depth+1);
- dumpnode(n->loopstmt.cond, fd, depth+1);
- dumpnode(n->loopstmt.step, fd, depth+1);
- dumpnode(n->loopstmt.body, fd, depth+1);
+ outnode(n->loopstmt.init, fd, depth+1);
+ outnode(n->loopstmt.cond, fd, depth+1);
+ outnode(n->loopstmt.step, fd, depth+1);
+ outnode(n->loopstmt.body, fd, depth+1);
break;
case Nuse:
fprintf(fd, " (name = %s, islocal = %d)\n", n->use.name, n->use.islocal);
@@ -80,7 +119,7 @@
case Nexpr:
fprintf(fd, " (op = %s, flags = %d)\n", opstr(n->expr.op), n->expr.isconst);
for (i = 0; i < n->expr.nargs; i++)
- dumpnode(n->expr.args[i], fd, depth+1);
+ outnode(n->expr.args[i], fd, depth+1);
break;
case Nlit:
switch (n->lit.littype) {
@@ -90,11 +129,11 @@
case Lflt: fprintf(fd, " Lflt %lf\n", n->lit.fltval); break;
case Lfunc:
fprintf(fd, " Lfunc\n");
- dumpnode(n->lit.fnval, fd, depth+1);
+ outnode(n->lit.fnval, fd, depth+1);
break;
case Larray:
fprintf(fd, " Larray\n");
- dumpnode(n->lit.arrval, fd, depth+1);
+ outnode(n->lit.arrval, fd, depth+1);
break;
default: die("Bad literal type"); break;
}
@@ -101,11 +140,12 @@
break;
case Nfunc:
fprintf(fd, " (args =\n");
+ outstab(n->func.scope, fd, depth + 1);
for (i = 0; i < n->func.nargs; i++)
- dumpnode(n->func.args[i], fd, depth+1);
+ outnode(n->func.args[i], fd, depth+1);
indent(fd, depth);
fprintf(fd, ")\n");
- dumpnode(n->func.body, fd, depth+1);
+ outnode(n->func.body, fd, depth+1);
case Nname:
fprintf(fd, "(");
for (i = 0; i < n->name.nparts; i++) {
@@ -120,5 +160,5 @@
void dump(Node *n, FILE *fd)
{
- dumpnode(n, fd, 0);
+ outnode(n, fd, 0);
}
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -194,8 +194,8 @@
| pkgbody pkgitem
;
-pkgitem : decl {def(file->file.globls, $1);}
- | tydef {deftype(file->file.globls, $1.name, $1.type);}
+pkgitem : decl {def(file->file.exports, $1);}
+ | tydef {deftype($1.line, file->file.exports, $1.name, $1.type);}
| visdef {die("Unimplemented visdef");}
| TEndln
;
--- a/parse/node.c
+++ b/parse/node.c
@@ -201,11 +201,15 @@
void def(Stab *s, Node *n)
{
assert(n->type == Ndecl);
+ slappend(&s->syms, &s->nsyms, n->decl.sym);
}
-void deftype(Stab *s, char *name, Type *ty)
+void deftype(int line, Stab *s, char *name, Type *ty)
{
- assert(name != NULL);
+ Sym *tysym;
+
+ tysym = mksym(line, mkname(line, name), ty);
+ slappend(&s->types, &s->ntypes, tysym);
}
Stab *mkstab(Stab *super)
@@ -254,5 +258,12 @@
{
*nl = xrealloc(*nl, (*len + 1)*sizeof(Node*));
(*nl)[*len] = n;
+ (*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
@@ -53,12 +53,13 @@
/* Contents of stab.
* Types and values are in separate namespaces. */
- int ntypes;
- Type **types;
- int nsyms;
+ size_t ntypes;
+ Sym **types;
+ size_t nsyms;
Sym **syms;
};
+/* reused for both decls and types */
struct Sym {
int line;
Node *name;
@@ -256,7 +257,7 @@
void addstmt(Node *file, Node *stmt);
void setns(Node *n, char *name);
void def(Stab *s, Node *n);
-void deftype(Stab *s, char *name, Type *t);
+void deftype(int line, Stab *s, char *name, Type *t);
/* usefiles */
void readuse(Node *use, Stab *into);
@@ -266,6 +267,7 @@
/* debug */
void dump(Node *t, FILE *fd);
+void dumpsym(Sym *s, FILE *fd);
char *opstr(Op o);
char *nodestr(Ntype nt);
char *litstr(Littype lt);
@@ -273,6 +275,7 @@
/* 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/type.c
+++ b/parse/type.c
@@ -170,6 +170,10 @@
p = buf;
end = p + len;
+ if (!t) {
+ p += snprintf(p, end - p, "tynil");
+ return end - p;
+ }
switch (t->type) {
case Tybad: p += snprintf(p, end - p, "BAD"); break;
case Tyvoid: p += snprintf(p, end - p, "void"); break;