shithub: mc

Download patch

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