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
}