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