shithub: mc

Download patch

ref: 938c3a42a7fb23c70b01e0fa0cdbc8b819b1e55b
parent: df7166675776274c295fa623b4801565f4c3a4e1
author: Ori Bernstein <[email protected]>
date: Sun Jun 17 02:40:07 EDT 2012

Add support for export-only symbols.

    Useful for defining APIs from another language (eg, asm,
    or C if I make the calling convention permit it)

--- a/parse/gram.y
+++ b/parse/gram.y
@@ -96,7 +96,6 @@
 %token<tok> Texport  /* export */
 %token<tok> Tprotect /* protect */
 
-
 %token<tok> Tellipsis        /* ... */
 %token<tok> Tendln           /* ; or \n */
 %token<tok> Tendblk  /* ;; */
@@ -149,7 +148,6 @@
     Type *ty;
 }
 
-
 %%
 
 module  : file
@@ -205,7 +203,6 @@
             }
         ;
 
-
 pkgbody : pkgitem
         | pkgbody pkgitem
         ;
@@ -222,7 +219,6 @@
         | Tprotect Tcolon
         ;
 
-
 declbody: declcore Tasn expr
             {$$ = $1; $1->decl.init = $3;}
         | declcore
@@ -255,6 +251,7 @@
         | enumdef
         | compoundtype
         | generictype
+        | Tellipsis {$$ = mkty($1->line, Tyvalist);}
         ;
 
 generictype
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -45,7 +45,7 @@
     t->resolved = 1;
 }
 
-/* find the most accurate type mapping we have */
+/* fixd the most accurate type mapping we have */
 static Type *tf(Type *t)
 {
     Type *lu;
@@ -55,7 +55,7 @@
     while (1) {
         if (!tytab[t->tid] && t->type == Tyname) {
             if (!(lu = gettype(curstab(), t->name)))
-                fatal(t->name->line, "Could not find type %s", namestr(t->name));
+                fatal(t->name->line, "Could not fixd type %s", namestr(t->name));
             tytab[t->tid] = lu;
         }
 
@@ -119,7 +119,6 @@
     return NULL;
 }
 
-
 static Type *type(Node *n)
 {
     Type *t;
@@ -440,12 +439,10 @@
 
     k = htkeys(s->ty, &n);
     for (i = 0; i < n; i++) {
-        t = gettype(s, k[i]);
-        if (!t)
-            t = gettype(file->file.globls, k[i]);
-        t = tf(t);
+        t = tf(gettype(s, k[i]));
         updatetype(s, k[i], t);
     }
+    free(k);
 }
 
 static void infernode(Node *n, Type *ret, int *sawret)
@@ -460,15 +457,17 @@
         return;
     switch (n->type) {
         case Nfile:
+            pushstab(n->file.globls);
+            /* exports allow us to specify types later in the body, so we
+             * need to patch the types in. */
             k = htkeys(file->file.exports->ty, &nk);
             for (i = 0; i < nk; i++) {
                 ty = gettype(file->file.globls, k[i]);
                 if (!ty) 
                     fatal(((Node*)k[i])->line, "Exported type %s not declared", namestr(k[i]));
-                updatetype(file->file.exports, k[i], ty);
+                updatetype(file->file.exports, k[i], tf(ty));
             }
             free(k);
-            pushstab(n->file.globls);
             inferstab(n->file.globls);
             inferstab(n->file.exports);
 	    for (i = 0; i < n->file.nstmts; i++) {
@@ -531,9 +530,9 @@
 {
 }
 
-/* returns the final type for t, after all unifications
+/* returns the fixal type for t, after all unifications
  * and default constraint selections */
-static Type *tyfin(Node *ctx, Type *t)
+static Type *tyfix(Node *ctx, Type *t)
 {
     static Type *tyint;
     size_t i;
@@ -550,7 +549,7 @@
         if (t->type == Tyarray)
             typesub(t->asize);
         for (i = 0; i < t->nsub; i++)
-            t->sub[i] = tyfin(ctx, t->sub[i]);
+            t->sub[i] = tyfix(ctx, t->sub[i]);
     }
     if (t->type == Tyvar) {
         fatal(t->line, "underconstrained type %s near %s", tyfmt(buf, 1024, t), ctxstr(ctx));
@@ -601,7 +600,7 @@
     k = htkeys(s->dcl, &n);
     for (i = 0; i < n; i++) {
 	d = getdcl(s, k[i]);
-	d->type = tyfin(d->name, d->type);
+	d->type = tyfix(d->name, d->type);
     }
     free(k);
 }
@@ -614,19 +613,23 @@
         return;
     switch (n->type) {
         case Nfile:
+            pushstab(n->file.globls);
 	    stabsub(n->file.globls);
 	    stabsub(n->file.exports);
             for (i = 0; i < n->file.nstmts; i++)
                 typesub(n->file.stmts[i]);
+            popstab();
             break;
         case Ndecl:
-            settype(n, tyfin(n, type(n)));
+            settype(n, tyfix(n, type(n)));
             if (n->decl.init)
                 typesub(n->decl.init);
             break;
         case Nblock:
+            pushstab(n->block.scope);
             for (i = 0; i < n->block.nstmts; i++)
                 typesub(n->block.stmts[i]);
+            popstab();
             break;
         case Nifstmt:
             typesub(n->ifstmt.cond);
@@ -640,18 +643,20 @@
             typesub(n->loopstmt.body);
             break;
         case Nexpr:
-            settype(n, tyfin(n, type(n)));
+            settype(n, tyfix(n, type(n)));
             for (i = 0; i < n->expr.nargs; i++)
                 typesub(n->expr.args[i]);
             break;
         case Nfunc:
-            settype(n, tyfin(n, n->func.type));
+            pushstab(n->func.scope);
+            settype(n, tyfix(n, n->func.type));
             for (i = 0; i < n->func.nargs; i++)
                 typesub(n->func.args[i]);
             typesub(n->func.body);
+            popstab();
             break;
         case Nlit:
-            settype(n, tyfin(n, type(n)));
+            settype(n, tyfix(n, type(n)));
             switch (n->lit.littype) {
                 case Lfunc:     typesub(n->lit.fnval); break;
                 case Larray:    typesub(n->lit.arrval); break;
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -16,7 +16,6 @@
 typedef struct Type Type;
 typedef struct Cstr Cstr;
 
-
 typedef enum {
 #define O(op, pure) op,
 #include "ops.def"