shithub: mc

Download patch

ref: 11dc97526dc9a7dcc30cb087b27f588c45266f03
parent: 8cc0e63c31208a10d245f3115bde2e7b886b2770
author: Ori Bernstein <[email protected]>
date: Sun Jun 14 10:16:41 EDT 2015

Start working on __init__, check types.

    This change both checks the types of main(), and
    of __init__.

    __init__ is not yet implemented.

--- a/6/gengas.c
+++ b/6/gengas.c
@@ -440,7 +440,7 @@
 {
     size_t i, j;
 
-    if (fn->isexport || !strcmp(fn->name, Symprefix "main"))
+    if (fn->isexport)
         fprintf(fd, ".globl %s\n", fn->name);
     fprintf(fd, "%s:\n", fn->name);
     for (j = 0; j < s->cfg->nbb; j++) {
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -448,7 +448,7 @@
     char *hidden;
 
     hidden = "";
-    if (fn->isexport || streq(fn->name, Symprefix "main"))
+    if (fn->isexport)
         hidden = "";
     /* we don't use the stack size directive: myrddin handles
      * the stack frobbing on its own */
--- a/6/simp.c
+++ b/6/simp.c
@@ -1658,16 +1658,29 @@
     append(s, s->endlbl);
 }
 
+static int isexport(Node *dcl)
+{
+    Node *n;
+
+    /* Vishidden should also be exported. */
+    if (dcl->decl.vis != Visintern)
+        return 1;
+    n = dcl->decl.name;
+    if (!n->name.ns && streq(n->name.name, "main"))
+        return 1;
+    if (streq(n->name.name, "__init__"))
+        return 1;
+    return 0;
+}
+
 static Func *simpfn(Simp *s, char *name, Node *dcl)
 {
     Node *n;
-    Vis vis;
     size_t i;
     Func *fn;
     Cfg *cfg;
 
     n = dcl->decl.init;
-    vis = dcl->decl.vis;
     if(debugopt['i'] || debugopt['F'] || debugopt['f'])
         printf("\n\nfunction %s\n", name);
 
@@ -1704,8 +1717,7 @@
 
     fn = zalloc(sizeof(Func));
     fn->name = strdup(name);
-    if (vis != Visintern)
-        fn->isexport = 1;
+    fn->isexport = isexport(dcl);
     fn->stksz = align(s->stksz, 8);
     fn->stkoff = s->stkoff;
     fn->ret = s->ret;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1952,6 +1952,37 @@
     }
 }
 
+static int initcompatible(Type *t)
+{
+    if (t->type != Tyfunc)
+        return 0;
+    if (t->nsub != 1)
+        return 0;
+    if (tybase(t->sub[0])->type != Tyvoid)
+        return 0;
+    return 1;
+}
+
+static int maincompatible(Type *t)
+{
+    if (t->nsub > 2)
+        return 0;
+    if (tybase(t->sub[0])->type != Tyvoid)
+        return 0;
+    if (t->nsub == 2) {
+        t = tybase(t->sub[1]);
+        if (t->type != Tyslice)
+            return 0;
+        t = tybase(t->sub[0]);
+        if (t->type != Tyslice)
+            return 0;
+        t = tybase(t->sub[0]);
+        if (t->type != Tybyte)
+            return 0;
+    }
+    return 1;
+}
+
 /* After type inference, replace all types
  * with the final computed type */
 static void typesub(Inferstate *st, Node *n)
@@ -1972,6 +2003,12 @@
             settype(st, n, tyfix(st, n, type(st, n), 0));
             if (n->decl.init)
                 typesub(st, n->decl.init);
+            if (streq(declname(n), "main"))
+                if (!maincompatible(tybase(decltype(n))))
+                    fatal(n, "main must be (->void) or (byte[:][:] -> void), got %s", tystr(decltype(n)));
+            if (streq(declname(n), "__init__"))
+                if (!initcompatible(tybase(decltype(n))))
+                    fatal(n, "__init__ must be (->void), got %s", tystr(decltype(n)));
             break;
         case Nblock:
             pushstab(n->block.scope);
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -211,15 +211,16 @@
     int nid;
     union {
         struct {
-            size_t nfiles;
+            size_t nfiles;      /* file names for location mapping */
             char  **files;
-            Node **uses;
+            Node **uses;        /* use files that we loaded */
             size_t nuses;
-            char **libdeps;
+            char **libdeps;     /* library dependencies */
             size_t nlibdeps;
-            Node **stmts;
+            Node **stmts;       /* all top level statements */
             size_t nstmts;
-            Stab  *globls;
+            Stab  *globls;      /* global symtab */
+            int hasinit;        /* did we declare __init__? */
         } file;
 
         struct {
--- a/parse/use.c
+++ b/parse/use.c
@@ -962,6 +962,8 @@
 
 /* Usefile format:
  * U<pkgname>
+ * L<liblist>
+ * I<initlist>
  * T<pickled-type>
  * D<picled-decl>
  * G<pickled-decl><pickled-initializer>
--- a/test/catfile.myr
+++ b/test/catfile.myr
@@ -9,6 +9,5 @@
 	| `std.Ok dat: 	std.write(1, dat)
 	| `std.Fail msg:	std.put("Failed to read file: {}\n", msg)
 	;;
-	-> 0
 }
 
--- a/test/chartest.myr
+++ b/test/chartest.myr
@@ -3,5 +3,4 @@
 const main = {
 	std.assert('a' == '\u{61}', "unicode char values invalid")
 	std.assert('Σ' == '\u{03a3}', "unicode char values invalid")
-	-> 0
 }