shithub: mc

Download patch

ref: dd1dcc663ada21c70e41003564e5c57d671981ac
parent: 53bc10145695df7160e374bca21f4a9510e3fd7d
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Sep 24 18:39:28 EDT 2015

Put the closure at the function level.

--- a/6/main.c
+++ b/6/main.c
@@ -211,7 +211,7 @@
         outfile = NULL;
 
     for (i = 0; i < ctx.nargs; i++) {
-        globls = mkstab();
+        globls = mkstab(0);
         tyinit(globls);
         tokinit(ctx.args[i]);
         file = mkfile(ctx.args[i]);
--- a/muse/muse.c
+++ b/muse/muse.c
@@ -86,7 +86,7 @@
     }
 
     file = mkfile("internal");
-    file->file.globls = mkstab();
+    file->file.globls = mkstab(0);
     updatens(file->file.globls, outfile);
     tyinit(file->file.globls);
     for (i = 0; i < ctx.nargs; i++)
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -52,11 +52,15 @@
 static void outstab(Stab *st, FILE *fd, int depth)
 {
     size_t i, n;
+    char *name;
     void **k;
     char *ty;
     Type *t;
 
-    findentf(fd, depth, "Stab %p (super = %p, name=\"%s\")\n", st, st->super, st->name);
+    name = "";
+    if (st->name)
+        name = st->name;
+    findentf(fd, depth, "Stab %p (super = %p, name=\"%s\")\n", st, st->super, name);
     if (!st)
         return;
 
@@ -86,12 +90,12 @@
     free(k);
 
     /* dump closure */
-    if (st->closure) {
-        k = htkeys(st->closure, &n);
+    if (st->env) {
+        k = htkeys(st->env, &n);
         for (i = 0; i < n; i++) {
             findentf(fd, depth + 1, "U ");
             /* already indented */
-            outsym(getdcl(st, k[i]), fd, 0);
+            outsym(getclosed(st, k[i]), fd, 0);
         }
         free(k);
     }
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -908,7 +908,7 @@
                 size_t i;
                 Node *n, *d, *u;
 
-                $$ = mkblock($1.loc, mkstab());
+                $$ = mkblock($1.loc, mkstab(0));
                 for (i = 0; i < $1.nn; i++) {
                     d = $1.nl[i];
                     putdcl($$->block.scope, d);
@@ -922,7 +922,7 @@
                 }
             }
         | stmt {
-                $$ = mkblock(curloc, mkstab());
+                $$ = mkblock(curloc, mkstab(0));
                 if ($1)
                     lappend(&$$->block.stmts, &$$->block.nstmts, $1);
             }
--- a/parse/node.c
+++ b/parse/node.c
@@ -146,7 +146,7 @@
     n->loopstmt.cond = cond;
     n->loopstmt.step = incr;
     n->loopstmt.body = body;
-    n->loopstmt.scope = mkstab();
+    n->loopstmt.scope = mkstab(0);
 
     return n;
 }
@@ -194,7 +194,7 @@
     f->func.args = args;
     f->func.nargs = nargs;
     f->func.body = body;
-    f->func.scope = mkstab();
+    f->func.scope = mkstab(1);
     f->func.type = mktyfunc(loc, args, nargs, ret);
 
     for (i = 0; i < nargs; i++)
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -131,11 +131,12 @@
 struct Stab {
     Stab *super;
     char *name;
+    char isfunc;
 
     /* Contents of stab.
      * types and values are in separate namespaces. */
     Htab *dcl;
-    Htab *closure;      /* the syms we close over */
+    Htab *env;          /* the syms we close over, if we're a function */
     Htab *ty;           /* types */
     Htab *tr;           /* traits */
     Htab *uc;           /* union constructors */
@@ -473,7 +474,7 @@
 int yyparse(void);
 
 /* stab creation */
-Stab *mkstab(void);
+Stab *mkstab(int isfunc);
 
 void putns(Stab *st, Stab *scope);
 void puttype(Stab *st, Node *n, Type *ty);
@@ -486,7 +487,7 @@
 
 Stab *getns(Node *file, char *n);
 Node *getdcl(Stab *st, Node *n);
-Node *getcapture(Stab *st, Node *n);
+Node *getclosed(Stab *st, Node *n);
 Type *gettype_l(Stab *st, Node *n);
 Type *gettype(Stab *st, Node *n);
 Node *getimpl(Stab *st, Node *impl);
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -292,7 +292,7 @@
             r->ifstmt.iffalse = specializenode(n->ifstmt.iffalse, tsmap);
             break;
         case Nloopstmt:
-            r->loopstmt.scope = mkstab();
+            r->loopstmt.scope = mkstab(0);
             r->loopstmt.scope->super = curstab();
             pushstab(r->loopstmt.scope);
             r->loopstmt.init = specializenode(n->loopstmt.init, tsmap);
@@ -318,7 +318,7 @@
             r->match.block = specializenode(n->match.block, tsmap);
             break;
         case Nblock:
-            r->block.scope = mkstab();
+            r->block.scope = mkstab(0);
             r->block.scope->super = curstab();
             pushstab(r->block.scope);
             r->block.nstmts = n->block.nstmts;
@@ -346,7 +346,7 @@
             lappend(&decls, &ndecls, r);
             break;
         case Nfunc:
-            r->func.scope = mkstab();
+            r->func.scope = mkstab(0);
             r->func.scope->super = curstab();
             pushstab(r->func.scope);
             r->func.type = tysubst(n->func.type, tsmap);
@@ -490,7 +490,7 @@
 
     name = mkname(Zloc, "__init__");
     decl = mkdecl(Zloc, name, mktyvar(Zloc));
-    block = mkblock(Zloc, mkstab());
+    block = mkblock(Zloc, mkstab(0));
     block->block.scope->super = file->file.globls;
     tyvoid = mktype(Zloc, Tyvoid);
     tyvoidfn = mktyfunc(Zloc, NULL, 0, tyvoid);
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -85,7 +85,7 @@
     return 0;
 }
 
-Stab *mkstab()
+Stab *mkstab(int isfunc)
 {
     Stab *st;
 
@@ -94,15 +94,19 @@
     st->ty = mkht(nsnamehash, nsnameeq);
     st->tr = mkht(nsnamehash, nsnameeq);
     st->uc = mkht(nsnamehash, nsnameeq);
+    if (isfunc)
+        st->env = mkht(nsnamehash, nsnameeq);
     st->impl = mkht(implhash, impleq);
     return st;
 }
 
-Node *getcapture(Stab *st, Node *n)
+Node *getclosed(Stab *st, Node *n)
 {
-    if (!st->closure)
-        return NULL;
-    return htget(st->closure, n);
+    while (st && !st->env)
+        st = st->super;
+    if (st)
+        return htget(st->env, n);
+    return NULL;
 }
 
 /* 
@@ -118,17 +122,17 @@
 Node *getdcl(Stab *st, Node *n)
 {
     Node *s;
-    Stab *orig;
+    Stab *fn;
 
-    orig = st;
+    fn = NULL;
     do {
         s = htget(st->dcl, n);
+        if (!fn && st->env)
+            fn = st;
         if (s) {
             /* record that this is in the closure of this scope */
-            if (!orig->closure)
-                orig->closure = mkht(nsnamehash, nsnameeq);
-            if (st != orig && !n->decl.isglobl)
-                htput(orig->closure, s->decl.name, s);
+            if (fn && !n->decl.isglobl)
+                htput(fn->env, s->decl.name, s);
             return s;
         }
         st = st->super;
@@ -261,7 +265,7 @@
     if (name->name.ns) {
         ns = getns(file, name->name.ns);
         if (!ns) {
-            ns = mkstab();
+            ns = mkstab(0);
             updatens(ns, name->name.ns);
             putns(file->file.globls, ns);
         }
--- a/parse/use.c
+++ b/parse/use.c
@@ -15,7 +15,7 @@
 static void wrtype(FILE *fd, Type *val);
 static void rdtype(FILE *fd, Type **dest);
 static void wrstab(FILE *fd, Stab *val);
-static Stab *rdstab(FILE *fd);
+static Stab *rdstab(FILE *fd, int isfunc);
 static void wrsym(FILE *fd, Node *val);
 static Node *rdsym(FILE *fd, Trait *ctx);
 static void pickle(FILE *fd, Node *n);
@@ -71,7 +71,7 @@
 
 /* Reads a symbol table from file. The converse
  * of wrstab. */
-static Stab *rdstab(FILE *fd)
+static Stab *rdstab(FILE *fd, int isfunc)
 {
     Stab *st;
     Type *ty;
@@ -80,7 +80,7 @@
     int i;
 
     /* read dcls */
-    st = mkstab();
+    st = mkstab(isfunc);
     st->name = rdstr(fd);
     n = rdint(fd);
     for (i = 0; i < n; i++)
@@ -572,7 +572,7 @@
             n->file.stmts = zalloc(sizeof(Node*)*n->file.nstmts);
             for (i = 0; i < n->file.nstmts; i++)
                 n->file.stmts[i] = unpickle(fd);
-            n->file.globls = rdstab(fd);
+            n->file.globls = rdstab(fd, 0);
             break;
 
         case Nexpr:
@@ -636,7 +636,7 @@
             n->ifstmt.iffalse = unpickle(fd);
             break;
         case Nblock:
-            n->block.scope = rdstab(fd);
+            n->block.scope = rdstab(fd, 0);
             n->block.nstmts = rdint(fd);
             n->block.stmts = zalloc(sizeof(Node *)*n->block.nstmts);
             n->block.scope->super = curstab();
@@ -664,7 +664,7 @@
             break;
         case Nfunc:
             rdtype(fd, &n->func.type);
-            n->func.scope = rdstab(fd);
+            n->func.scope = rdstab(fd, 1);
             n->func.nargs = rdint(fd);
             n->func.args = zalloc(sizeof(Node *)*n->func.nargs);
             n->func.scope->super = curstab();
@@ -704,7 +704,7 @@
 
     s = getns(file, pkg);
     if (!s) {
-        s = mkstab();
+        s = mkstab(0);
         s->name = strdup(pkg);
         putns(st, s);
     }