ref: 9feb475b50b7fc4f35896a68a00d71dc19b086d8
parent: 7bbde87a61c0cb326328dce7f797875779446782
author: Ori Bernstein <[email protected]>
date: Sat Jun 16 23:51:42 EDT 2012
Change the way names are represented. Instead of a vari-length size, just the name and the namespace. There's only one level anyways.
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -69,22 +69,20 @@
static char *asmname(Node *n)
{
- size_t i;
char *s;
- char *sep;
int len;
len = strlen(Fprefix);
- for (i = 0; i < n->name.nparts; i++)
- len += strlen(n->name.parts[i]) + 1;
+ if (n->name.ns)
+ len += strlen(n->name.ns);
+ len += strlen(n->name.name);
s = xalloc(len);
s[0] = '\0';
- sep = Fprefix;
- for (i = 0; i < n->name.nparts; i++) {
- sprintf(s, "%s%s", sep, n->name.parts[i]);
- sep = "$";
- }
+ sprintf(s, "%s", Fprefix);
+ if (n->name.ns)
+ sprintf(s, "%s%s$", s, n->name.ns);
+ sprintf(s, "%s%s", s, n->name.name);
return s;
}
@@ -671,13 +669,35 @@
fprintf(fd, "\n");
}
+void fillglobls(Stab *st, Htab *globls)
+{
+ void **k;
+ size_t i, nk;
+ Stab *stab;
+ Sym *s;
+
+ k = htkeys(st->dcl, &nk);
+ for (i = 0; i < nk; i++) {
+ s = htget(st->dcl, k[i]);
+ htput(globls, (void*)s->id, asmname(s->name));
+ }
+ free(k);
+
+ k = htkeys(st->ns, &nk);
+ for (i = 0; i < nk; i++) {
+ stab = htget(st->ns, k[i]);
+ fillglobls(stab, globls);
+ }
+ free(k);
+}
+
void gen(Node *file, char *out)
{
+ Htab *globls;
+ size_t nn, i;
+ char *name;
FILE *fd;
Node **n;
- int nn, i;
- char *name;
- Htab *globls;
Sym *s;
/* declrae useful constants */
@@ -689,9 +709,7 @@
globls = mkht(ptrhash, ptreq);
/* We need to define all global variables before use */
- for (i = 0; i < nn; i++)
- if (n[i]->type == Ndecl)
- htput(globls, (void*)n[i]->decl.sym->id, asmname(n[i]->decl.sym->name));
+ fillglobls(file->file.globls, globls);
fd = fopen(out, "w");
if (!fd)
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -20,14 +20,9 @@
static void outname(Node *n, FILE *fd)
{
- size_t i;
- char *sep;
-
- sep = "";
- for (i = 0; i < n->name.nparts; i++) {
- fprintf(fd, "%s%s", sep, n->name.parts[i]);
- sep = ".";
- }
+ if (n->name.ns)
+ fprintf(fd, "%s.", n->name.ns);
+ fprintf(fd, "%s", n->name.name);
}
static void outsym(Sym *s, FILE *fd, int depth)
@@ -185,11 +180,9 @@
break;
case Nname:
fprintf(fd, "(");
- for (i = 0; i < n->name.nparts; i++) {
- if (i != 0)
- fprintf(fd, ".");
- fprintf(fd, "%s", n->name.parts[i]);
- }
+ if (n->name.ns)
+ fprintf(fd, "%s.", n->name.ns);
+ fprintf(fd, "%s", n->name.name);
fprintf(fd, ")\n");
break;
case Nnone:
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -223,7 +223,6 @@
size_t i;
Type *ft;
- inferexpr(n->expr.args[0], NULL, NULL);
ft = type(n->expr.args[0]);
if (ft->type == Tyvar) {
/* the first arg is the function itself, so it shouldn't be counted */
@@ -237,21 +236,49 @@
settype(n, ft->sub[0]);
}
-static void inferexpr(Node *n, Type *ret, int *sawret)
+void checkns(Node *n, Node **ret)
{
+ Node *var, *name, *nsname;
Node **args;
+ Stab *st;
Sym *s;
+
+ args = n->expr.args;
+ if (exprop(args[0]) != Ovar)
+ return;
+ name = args[0]->expr.args[0];
+ st = getns(curstab(), name);
+ if (!st)
+ return;
+ nsname = mknsname(n->line, namestr(name), namestr(args[1]));
+ s = getdcl(st, args[1]);
+ var = mkexpr(n->line, Ovar, nsname, NULL);
+ var->expr.did = s->id;
+ settype(var, s->type);
+ *ret = var;
+}
+
+static void inferexpr(Node *n, Type *ret, int *sawret)
+{
+ Node **args;
int nargs;
Type *t;
+ Sym *s;
int i;
assert(n->type == Nexpr);
args = n->expr.args;
nargs = n->expr.nargs;
- for (i = 0; i < nargs; i++)
+ for (i = 0; i < nargs; i++) {
/* Nlit, Nvar, etc should not be inferred as exprs */
- if (args[i]->type == Nexpr)
+ if (args[i]->type == Nexpr) {
+ /* Omemb can sometimes resolve to a namespace. We have to check
+ * this. Icky. */
+ if (exprop(args[i]) == Omemb)
+ checkns(args[i], &args[i]);
inferexpr(args[i], ret, sawret);
+ }
+ }
switch (exprop(n)) {
/* all operands are same type */
case Oadd: /* @a + @a -> @a */
@@ -351,6 +378,8 @@
settype(n, mkty(-1, Tyvoid));
break;
case Ovar: /* a:@a -> @a */
+ if (n->expr.type)
+ return;
s = getdcl(curstab(), args[0]);
if (!s)
fatal(n->line, "Undeclared var %s", ctxstr(args[0]));
--- a/parse/node.c
+++ b/parse/node.c
@@ -191,13 +191,22 @@
Node *n;
n = mknode(line, Nname);
- n->name.nparts = 1;
- n->name.parts = xalloc(sizeof(char*));
- n->name.parts[0] = strdup(name);
+ n->name.name = strdup(name);
return n;
}
+Node *mknsname(int line, char *ns, char *name)
+{
+ Node *n;
+
+ n = mknode(line, Nname);
+ n->name.ns = strdup(ns);
+ n->name.name = strdup(name);
+
+ return n;
+}
+
Node *mkdecl(int line, Sym *sym)
{
Node *n;
@@ -223,7 +232,7 @@
Node *name;
assert(n->type == Ndecl);
name = n->decl.sym->name;
- return name->name.parts[name->name.nparts - 1];
+ return name->name.name;
}
Type *decltype(Node *n)
@@ -249,15 +258,9 @@
return NULL;
}
-void setns(Node *n, char *name)
+void setns(Node *n, char *ns)
{
- int i;
-
- n->name.nparts++;
- n->name.parts = xrealloc(n->name.parts, n->name.nparts);
- for (i = n->name.nparts - 1; i > 0; i++)
- n->name.parts[i] = n->name.parts[i-1];
- n->name.parts[0] = strdup(name);
+ n->name.ns = strdup(ns);
}
Op exprop(Node *e)
@@ -283,5 +286,5 @@
if (!name)
return "";
assert(name->type == Nname);
- return name->name.parts[0];
+ return name->name.name;
}
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -148,8 +148,8 @@
} expr;
struct {
- size_t nparts;
- char **parts;
+ char *ns;
+ char *name;
} name;
struct {
@@ -334,6 +334,7 @@
Node *mkfunc(int line, Node **args, size_t nargs, Type *ret, Node *body);
Node *mkarray(int line, Node **vals);
Node *mkname(int line, char *name);
+Node *mknsname(int line, char *ns, char *name);
Node *mkdecl(int line, Sym *sym);
Node *mklbl(int line, char *lbl);
Node *mkslice(int line, Node *base, Node *off);
@@ -345,7 +346,7 @@
Type *exprtype(Node *n);
Type *nodetype(Node *n);
void addstmt(Node *file, Node *stmt);
-void setns(Node *n, char *name);
+void setns(Node *n, char *ns);
Op exprop(Node *n);
Node **aggrmemb(Type *t, size_t *n);
--- a/parse/pickle.c
+++ b/parse/pickle.c
@@ -263,9 +263,11 @@
pickle(n->expr.args[i], fd);
break;
case Nname:
- wrint(fd, n->name.nparts);
- for (i = 0; i < n->name.nparts; i++)
- wrstr(fd, n->name.parts[i]);
+ wrbool(fd, n->name.ns != NULL);
+ if (n->name.ns) {
+ wrstr(fd, n->name.ns);
+ }
+ wrstr(fd, n->name.name);
break;
case Nuse:
wrbool(fd, n->use.islocal);
@@ -358,10 +360,9 @@
n->expr.args[i] = unpickle(fd);
break;
case Nname:
- n->name.nparts = rdint(fd);
- n->name.parts = xalloc(sizeof(Node *)*n->name.nparts);
- for (i = 0; i < n->name.nparts; i++)
- n->name.parts[i] = rdstr(fd);
+ if (rdbool(fd))
+ n->name.ns = rdstr(fd);
+ n->name.name = rdstr(fd);
break;
case Nuse:
n->use.islocal = rdbool(fd);
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -37,20 +37,14 @@
stabstkoff--;
}
-
-static char *name(Node *n)
-{
- return n->name.parts[n->name.nparts - 1];
-}
-
static ulong namehash(void *n)
{
- return strhash(name(n));
+ return strhash(namestr(n));
}
static int nameeq(void *a, void *b)
{
- return a == b || !strcmp(name(a), name(b));
+ return a == b || !strcmp(namestr(a), namestr(b));
}
Sym *mksym(int line, Node *name, Type *ty)
@@ -127,7 +121,9 @@
d = getdcl(st, s->name);
if (d)
- fatal(s->line, "%s already declared (line %d", name(s->name), d->line);
+ fatal(s->line, "%s already declared (line %d", namestr(s->name), d->line);
+ if (st->name)
+ setns(s->name, namestr(st->name));
htput(st->dcl, s->name, s);
}
@@ -137,7 +133,7 @@
td = htget(st->ty, n);
if (!td)
- die("No type %s to update", name(n));
+ die("No type %s to update", namestr(n));
td->type = t;
}
@@ -149,7 +145,7 @@
assert(t != NULL);
ty = gettype(st, n);
if (ty)
- fatal(n->line, "Type %s already defined", name(n));
+ fatal(n->line, "Type %s already defined", namestr(n));
td = xalloc(sizeof(Tydefn));
td->line = n->line;
td->name = n;
@@ -163,6 +159,6 @@
s = getns(st, scope->name);
if (s)
- fatal(scope->name->line, "Ns %s already defined", name(s->name));
+ fatal(scope->name->line, "Ns %s already defined", namestr(s->name));
htput(st->ns, scope->name, scope);
}
--- a/parse/type.c
+++ b/parse/type.c
@@ -198,20 +198,16 @@
}
}
-static int namefmt(char *buf, size_t len, Node *name)
+static int namefmt(char *buf, size_t len, Node *n)
{
- size_t i;
char *p;
char *end;
- char *sep;
p = buf;
end = p + len;
- sep = "";
- for (i = 0; i < name->name.nparts; i++) {
- p += snprintf(p, end - p, "%s%s", sep, name->name.parts[i]);
- sep = ".";
- }
+ if (n->name.ns)
+ p += snprintf(p, end - p, "%s.", n->name.ns);
+ p += snprintf(p, end - p, "%s", n->name.name);
return len - (end - p);
}