shithub: mc

Download patch

ref: 2d65d0a17fc82b22730254ad1fa05c1913452c9e
parent: e1bc2dfb1c4a93d4d6def1a2a24a08165040a4b8
author: Ori Bernstein <[email protected]>
date: Mon Aug 12 07:36:27 EDT 2013

Fix exported union constructors.

    Union constructors declared in the package declaration section
    of the file can now be used in the body, since the global and
    export symbol tables now get merged.

--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -4,10 +4,10 @@
     blat.myr \
     chartype.myr \
     die.myr \
+    error.myr \
     extremum.myr \
     fmt.myr \
     intparse.myr \
-    maybe.myr \
     optparse.myr \
     rand.myr \
     slappend.myr \
--- /dev/null
+++ b/libstd/error.myr
@@ -1,0 +1,19 @@
+pkg std =
+	type error(@a, @b)
+
+	generic try	: (val : error(@a, byte[:]) -> void)
+;;
+
+type error(@a, @b) = union
+	`Success	@a
+	`Failure	@b
+;;
+
+generic try = {val
+	/*
+	match val
+		`Success v:	-> v;;
+		`Failure msg:	die(msg);;
+	;;
+	*/
+}
--- a/libstd/maybe.myr
+++ /dev/null
@@ -1,6 +1,0 @@
-pkg std =
-	type maybe(@a) = union
-		`Val	@a
-		`Nil
-	;;
-;;
--- a/myrtypes/myrtypes.c
+++ b/myrtypes/myrtypes.c
@@ -112,8 +112,17 @@
     }
 }
 
-void dumpusetypes(Stab *st, int indent)
+void dumpucon(Ucon *uc, int indent)
 {
+    printindent(indent);
+    printf("`");
+    if (uc->name->name.ns)
+        printf("%s.", uc->name->name.ns);
+    printf("%s\n", uc->name->name.name);
+}
+
+void dumpsyms(Stab *st, int indent)
+{
     size_t i, n;
     void **k;
 
@@ -124,13 +133,20 @@
     }
     free(k);
 
+    /* union constructors */
+    k = htkeys(st->uc, &n);
+    for (i = 0; i < n; i++)
+        dumpucon(getucon(st, k[i]), indent + 1);
+
+
     /* sub-namespaces */
     k = htkeys(st->ns, &n);
     for (i = 0; i < n; i++) {
         printindent(indent + 1);
         printf("namespace %s:\n", (char*)k[i]);
-        dumpusetypes(getns_str(st, k[i]), indent + 2);
+        dumpsyms(getns_str(st, k[i]), indent + 2);
     }
+
     free(k);
 }
 
@@ -184,13 +200,13 @@
             if (!f)
                 die("Unable to open usefile %s\n", argv[i]);
             loaduse(f, file->file.globls);
-            dumpusetypes(file->file.globls, 0);
+            dumpsyms(file->file.globls, 1);
         } else {
             tyinit(file->file.globls);
             tokinit(argv[i]);
             yyparse();
             infer(file);
-            dumptypes(file, 1);
+            dumpsyms(file->file.globls, 1);
         }
     }
 
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -240,7 +240,8 @@
             {putdcl(file->file.exports, $1);
              if ($1->decl.init)
                  lappend(&file->file.stmts, &file->file.nstmts, $1);}
-        | tydef {puttype(file->file.exports, mkname($1.line, $1.name), $1.type);}
+        | tydef {puttype(file->file.exports, mkname($1.line, $1.name), $1.type);
+             installucons(file->file.exports, $1.type);}
         | visdef {die("Unimplemented visdef");}
         | /* empty */
         ;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -660,9 +660,10 @@
     Stab *exports, *globls;
     size_t i, nk;
     void **k;
-    /* local, global version */
-    Node *nl, *ng;
-    Type *tl, *tg;
+    /* export, global version */
+    Node *nx, *ng;
+    Type *tx, *tg;
+    Ucon *ux, *ug;
 
     exports = file->file.exports;
     globls = file->file.globls;
@@ -670,20 +671,20 @@
     pushstab(globls);
     k = htkeys(exports->ty, &nk);
     for (i = 0; i < nk; i++) {
-        tl = gettype(exports, k[i]);
-        nl = k[i];
-        if (tl) {
-            tg = gettype(globls, nl);
+        tx = gettype(exports, k[i]);
+        nx = k[i];
+        if (tx) {
+            tg = gettype(globls, nx);
             if (!tg)
-                puttype(globls, nl, tl);
+                puttype(globls, nx, tx);
             else
-                fatal(nl->line, "Exported type %s already declared on line %d", namestr(nl), tg->line);
+                fatal(nx->line, "Exported type %s already declared on line %d", namestr(nx), tg->line);
         } else {
-            tg = gettype(globls, nl);
+            tg = gettype(globls, nx);
             if (tg)
-                updatetype(exports, nl, tf(st, tg));
+                updatetype(exports, nx, tf(st, tg));
             else
-                fatal(nl->line, "Exported type %s not declared", namestr(nl));
+                fatal(nx->line, "Exported type %s not declared", namestr(nx));
         }
     }
     free(k);
@@ -690,18 +691,35 @@
 
     k = htkeys(exports->dcl, &nk);
     for (i = 0; i < nk; i++) {
-        nl = getdcl(exports, k[i]);
+        nx = getdcl(exports, k[i]);
         ng = getdcl(globls, k[i]);
         /* if an export has an initializer, it shouldn't be declared in the
          * body */
-        if (nl->decl.init && ng)
-            fatal(nl->line, "Export %s double-defined on line %d", ctxstr(st, nl), ng->line);
+        if (nx->decl.init && ng)
+            fatal(nx->line, "Export %s double-defined on line %d", ctxstr(st, nx), ng->line);
         if (!ng)
-            putdcl(globls, nl);
+            putdcl(globls, nx);
         else
-            unify(st, nl, type(st, ng), type(st, nl));
+            unify(st, nx, type(st, ng), type(st, nx));
     }
     free(k);
+
+
+    k = htkeys(exports->uc, &nk);
+    for (i = 0; i < nk; i++) {
+        ux = getucon(exports, k[i]);
+        ug = getucon(globls, k[i]);
+        /* if an export has an initializer, it shouldn't be declared in the
+         * body */
+        if (ux && ug)
+            fatal(ux->line, "Union constructor double defined on %d", ng->line);
+        else if (!ug)
+          putucon(globls, ux);
+        else
+            putucon(exports, ug);
+    }
+    free(k);
+
     popstab();
 }