ref: f16265cf009101ef36cc0d0fcf32490ebaf13b6e
parent: 6d015a6a58987f8fbc79f183bc401d9597231f2b
author: Ori Bernstein <[email protected]>
date: Wed Sep 17 09:48:46 EDT 2014
Add support for 'pkglocal' keyword. pkglocal makes the export only available within the package.
--- a/6/main.c
+++ b/6/main.c
@@ -135,6 +135,7 @@
if (debugopt['T'])
dump(file, stdout);
infer(file);
+ tagexports(file->file.exports, 0);
/* after all type inference */
if (debugopt['t'])
dump(file, stdout);
--- a/6/simp.c
+++ b/6/simp.c
@@ -36,7 +36,7 @@
/* pre/postinc handling */
Node **incqueue;
size_t nqueue;
-
+
/* break/continue handling */
Node **loopstep;
size_t nloopstep;
--- a/libstd/fltfmt.myr
+++ b/libstd/fltfmt.myr
@@ -8,9 +8,8 @@
use "die.use"
pkg std =
-
- const flt64bfmt : (buf : byte[:], val : flt64, mode : int, precision : int -> size)
- const flt32bfmt : (buf : byte[:], val : flt32, mode : int, precision : int -> size)
+ pkglocal const flt64bfmt : (buf : byte[:], val : flt64, mode : int, precision : int -> size)
+ pkglocal const flt32bfmt : (buf : byte[:], val : flt32, mode : int, precision : int -> size)
;;
const Dblbias = 1023
--- a/muse/muse.c
+++ b/muse/muse.c
@@ -59,6 +59,7 @@
yyparse();
infer(file);
+ tagexports(file->file.exports, 0);
if (outfile) {
p = outfile;
} else {
@@ -131,6 +132,7 @@
for (i = optind; i < argc; i++)
mergeuse(argv[i]);
infer(file);
+ tagexports(file->file.exports, 1);
f = fopen(outfile, "w");
writeuse(f, file);
fclose(f);
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -118,6 +118,7 @@
%token<tok> Tret /* -> */
%token<tok> Tuse /* use */
%token<tok> Tpkg /* pkg */
+%token<tok> Tpkglocal/* pkglocal */
%token<tok> Tsizeof /* sizeof */
%token<tok> Tident
@@ -132,7 +133,7 @@
%type <tok> asnop cmpop addop mulop shiftop optident
-%type <tydef> tydef typeid
+%type <tydef> tydef pkgtydef typeid
%type <trait> traitdef
%type <node> exprln retexpr goto continue break expr atomicexpr
@@ -150,7 +151,7 @@
%type <nodelist> arglist argdefs params matches
%type <nodelist> structbody structelts arrayelts
%type <nodelist> tupbody tuprest
-%type <nodelist> decl decllist
+%type <nodelist> decl pkgdecl decllist
%type <nodelist> traitbody implbody
%type <uconlist> unionbody
@@ -280,7 +281,7 @@
| pkgbody Tendln pkgitem
;
-pkgitem : decl {
+pkgitem : pkgdecl {
size_t i;
for (i = 0; i < $1.nn; i++) {
putdcl(file->file.exports, $1.nl[i]);
@@ -288,7 +289,7 @@
lappend(&file->file.stmts, &file->file.nstmts, $1.nl[i]);
}
}
- | tydef {
+ | pkgtydef {
puttype(file->file.exports, mkname($1.line, $1.name), $1.type);
installucons(file->file.exports, $1.type);
}
@@ -305,6 +306,22 @@
}
| visdef {die("Unimplemented visdef");}
| /* empty */
+ ;
+
+pkgdecl : Tpkglocal decl {
+ size_t i;
+ $$ = $2;
+ for (i = 0; i < $$.nn; i++)
+ $$.nl[i]->decl.ispkglocal = 1;
+ }
+ | decl {$$ = $1;}
+ ;
+
+pkgtydef: Tpkglocal tydef {
+ $$ = $2;
+ $$.type->ispkglocal = 1;
+ }
+ | tydef {$$ = $1;}
;
visdef : Texport Tcolon
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -960,6 +960,7 @@
fatal(nx->line, "Export %s double-defined on line %d", ctxstr(st, nx), ng->line);
if (nx->decl.isgeneric != ng->decl.isgeneric)
fatal(nx->line, "Export %s defined with different genericness on line %d", ctxstr(st, nx), ng->line);
+ ng->decl.ispkglocal = nx->decl.ispkglocal;
unify(st, nx, type(st, ng), type(st, nx));
} else {
if (!nx->decl.isextern && !nx->decl.isimport && !nx->decl.trait)
@@ -1129,22 +1130,22 @@
case Olit:
case Omemb:
infernode(st, n, NULL, NULL); break;
- /* arithmetic expressions just need to be constant */
- case Oneg:
- case Oadd:
- case Osub:
- case Omul:
- case Odiv:
- case Obsl:
- case Obsr:
- case Oband:
- case Obor:
- case Obxor:
- case Obnot:
+ /* arithmetic expressions just need to be constant */
+ case Oneg:
+ case Oadd:
+ case Osub:
+ case Omul:
+ case Odiv:
+ case Obsl:
+ case Obsr:
+ case Oband:
+ case Obor:
+ case Obxor:
+ case Obnot:
infernode(st, n, NULL, NULL);
- if (!n->expr.isconst)
- fatal(n->line, "matching against non-constant expression");
- break;
+ if (!n->expr.isconst)
+ fatal(n->line, "matching against non-constant expression");
+ break;
case Oucon: inferucon(st, n, &n->expr.isconst); break;
case Ovar:
s = getdcl(curstab(), args[0]);
@@ -2000,7 +2001,7 @@
}
}
-static void nodetag(Stab *st, Node *n, int ingeneric)
+static void nodetag(Stab *st, Node *n, int ingeneric, int hidelocal)
{
size_t i;
Node *d;
@@ -2010,38 +2011,38 @@
switch (n->type) {
case Nblock:
for (i = 0; i < n->block.nstmts; i++)
- nodetag(st, n->block.stmts[i], ingeneric);
+ nodetag(st, n->block.stmts[i], ingeneric, hidelocal);
break;
case Nifstmt:
- nodetag(st, n->ifstmt.cond, ingeneric);
- nodetag(st, n->ifstmt.iftrue, ingeneric);
- nodetag(st, n->ifstmt.iffalse, ingeneric);
+ nodetag(st, n->ifstmt.cond, ingeneric, hidelocal);
+ nodetag(st, n->ifstmt.iftrue, ingeneric, hidelocal);
+ nodetag(st, n->ifstmt.iffalse, ingeneric, hidelocal);
break;
case Nloopstmt:
- nodetag(st, n->loopstmt.init, ingeneric);
- nodetag(st, n->loopstmt.cond, ingeneric);
- nodetag(st, n->loopstmt.step, ingeneric);
- nodetag(st, n->loopstmt.body, ingeneric);
+ nodetag(st, n->loopstmt.init, ingeneric, hidelocal);
+ nodetag(st, n->loopstmt.cond, ingeneric, hidelocal);
+ nodetag(st, n->loopstmt.step, ingeneric, hidelocal);
+ nodetag(st, n->loopstmt.body, ingeneric, hidelocal);
break;
case Niterstmt:
- nodetag(st, n->iterstmt.elt, ingeneric);
- nodetag(st, n->iterstmt.seq, ingeneric);
- nodetag(st, n->iterstmt.body, ingeneric);
+ nodetag(st, n->iterstmt.elt, ingeneric, hidelocal);
+ nodetag(st, n->iterstmt.seq, ingeneric, hidelocal);
+ nodetag(st, n->iterstmt.body, ingeneric, hidelocal);
break;
case Nmatchstmt:
- nodetag(st, n->matchstmt.val, ingeneric);
+ nodetag(st, n->matchstmt.val, ingeneric, hidelocal);
for (i = 0; i < n->matchstmt.nmatches; i++)
- nodetag(st, n->matchstmt.matches[i], ingeneric);
+ nodetag(st, n->matchstmt.matches[i], ingeneric, hidelocal);
break;
case Nmatch:
- nodetag(st, n->match.pat, ingeneric);
- nodetag(st, n->match.block, ingeneric);
+ nodetag(st, n->match.pat, ingeneric, hidelocal);
+ nodetag(st, n->match.block, ingeneric, hidelocal);
break;
case Nexpr:
- nodetag(st, n->expr.idx, ingeneric);
+ nodetag(st, n->expr.idx, ingeneric, hidelocal);
taghidden(n->expr.type);
for (i = 0; i < n->expr.nargs; i++)
- nodetag(st, n->expr.args[i], ingeneric);
+ nodetag(st, n->expr.args[i], ingeneric, hidelocal);
/* generics need to have the decls they refer to exported. */
if (ingeneric && exprop(n) == Ovar) {
d = decls[n->expr.did];
@@ -2048,7 +2049,7 @@
if (d->decl.isglobl && d->decl.vis == Visintern) {
d->decl.vis = Vishidden;
putdcl(st, d);
- nodetag(st, d, ingeneric);
+ nodetag(st, d, ingeneric, hidelocal);
}
}
break;
@@ -2055,24 +2056,26 @@
case Nlit:
taghidden(n->lit.type);
if (n->lit.littype == Lfunc)
- nodetag(st, n->lit.fnval, ingeneric);
+ nodetag(st, n->lit.fnval, ingeneric, hidelocal);
break;
case Ndecl:
taghidden(n->decl.type);
+ if (hidelocal && n->decl.ispkglocal)
+ n->decl.vis = Vishidden;
/* generics export their body. */
if (n->decl.isgeneric)
- nodetag(st, n->decl.init, n->decl.isgeneric);
+ nodetag(st, n->decl.init, n->decl.isgeneric, hidelocal);
break;
case Nfunc:
taghidden(n->func.type);
for (i = 0; i < n->func.nargs; i++)
- nodetag(st, n->func.args[i], ingeneric);
- nodetag(st, n->func.body, ingeneric);
+ nodetag(st, n->func.args[i], ingeneric, hidelocal);
+ nodetag(st, n->func.body, ingeneric, hidelocal);
break;
case Nimpl:
for (i = 0; i < n->impl.ndecls; i++) {
n->impl.decls[i]->decl.vis = Vishidden;
- nodetag(st, n->impl.decls[i], 0);
+ nodetag(st, n->impl.decls[i], 0, hidelocal);
}
break;
case Nuse: case Nname:
@@ -2083,7 +2086,7 @@
}
}
-void tagexports(Stab *st)
+void tagexports(Stab *st, int hidelocal)
{
void **k;
Node *s;
@@ -2093,12 +2096,12 @@
k = htkeys(st->dcl, &n);
for (i = 0; i < n; i++) {
s = getdcl(st, k[i]);
- nodetag(st, s, 0);
+ nodetag(st, s, 0, hidelocal);
}
free(k);
for (i = 0; i < nexportimpls; i++) {
- nodetag(st, exportimpls[i], 0);
+ nodetag(st, exportimpls[i], 0, hidelocal);
}
/* get the explicitly exported symbols */
@@ -2105,7 +2108,10 @@
k = htkeys(st->ty, &n);
for (i = 0; i < n; i++) {
t = gettype(st, k[i]);
- t->vis = Visexport;
+ if (hidelocal && t->ispkglocal)
+ t->vis = Vishidden;
+ else
+ t->vis = Visexport;
taghidden(t);
for (j = 0; j < t->nsub; j++)
taghidden(t->sub[j]);
@@ -2179,5 +2185,4 @@
/* and replace type vars with actual types */
typesub(&st, file);
specialize(&st, file);
- tagexports(file->file.exports);
}
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -118,8 +118,6 @@
Node **traitlist; /* The names of the constraints on the type. Used to fill the bitset */
size_t ntraitlist; /* The length of the constraint list above */
- int issynth; /* Tyname: whether this is synthesized or not */
- int ishidden; /* Tyname: whether this is hidden or not */
Type **param; /* Tyname: type parameters that match the type args */
size_t nparam; /* Tyname: count of type parameters */
Type **arg; /* Tyname: type arguments instantiated */
@@ -137,6 +135,9 @@
Node **sdecls; /* Tystruct: decls in struct */
Ucon **udecls; /* Tyunion: decls in union */
};
+ char issynth; /* Tyname: whether this is synthesized or not */
+ char ishidden; /* Tyname: whether this is hidden or not */
+ char ispkglocal; /* Tyname: whether this is package local or not */
};
struct Ucon {
@@ -267,6 +268,7 @@
char isconst;
char isgeneric;
char isextern;
+ char ispkglocal;
char ishidden;
char isimport;
} decl;
@@ -499,7 +501,7 @@
int loaduse(FILE *f, Stab *into);
void readuse(Node *use, Stab *into);
void writeuse(FILE *fd, Node *file);
-void tagexports(Stab *st);
+void tagexports(Stab *st, int hidelocal);
/* typechecking/inference */
void infer(Node *file);
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -180,6 +180,7 @@
{"in", Tin},
{"match", Tmatch},
{"pkg", Tpkg},
+ {"pkglocal", Tpkglocal},
{"protect", Tprotect},
{"sizeof", Tsizeof},
{"struct", Tstruct},
--- a/parse/use.c
+++ b/parse/use.c
@@ -146,6 +146,7 @@
wrbool(fd, val->decl.isconst);
wrbool(fd, val->decl.isgeneric);
wrbool(fd, val->decl.isextern);
+ wrbool(fd, val->decl.ispkglocal);
if (val->decl.isgeneric && !val->decl.trait)
pickle(fd, val->decl.init);
@@ -168,6 +169,7 @@
n->decl.isconst = rdbool(fd);
n->decl.isgeneric = rdbool(fd);
n->decl.isextern = rdbool(fd);
+ n->decl.ispkglocal = rdbool(fd);
n->decl.isimport = 1;
if (n->decl.isgeneric && !ctx)