shithub: mc

Download patch

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)