summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-06-27 10:47:41 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-06-27 10:47:41 -0400
commit7e47f52a21fb73dde9e59fe1f0b5957ec119ccfd (patch)
tree8954c988a19882f7c537f27d450b72ed10829a6f
parent8080bfbe4a757d7a7d895654da6424d789e6d33c (diff)
#init
-rw-r--r--cgen.c15
-rw-r--r--main.c4
-rw-r--r--parse.c7
-rw-r--r--test.toc17
-rw-r--r--tests/init.toc25
-rw-r--r--tests/init_expected18
-rw-r--r--tests/std/base.toc3
-rw-r--r--types.c12
-rw-r--r--types.h15
9 files changed, 77 insertions, 39 deletions
diff --git a/cgen.c b/cgen.c
index ede4604..bf2c9c7 100644
--- a/cgen.c
+++ b/cgen.c
@@ -2083,7 +2083,20 @@ static void cgen_file(CGenerator *g, ParsedFile *f, Typer *tr) {
}
cgen_write(g, "/* code */\n");
- cgen_write(g, "int main(void) {\n\tmain_();\n\treturn 0;\n}\n\n");
+ cgen_write(g, "int main(void) {\n");
+ g->indent_lvl = 1;
+ arr_foreach(f->inits, Initialization, init) {
+ Statement *s = &init->stmt;
+ if (s->kind == STMT_EXPR) { /* these wouldn't be generated otherwise */
+ cgen_expr(g, s->expr);
+ cgen_writeln(g, ";");
+ } else {
+ cgen_stmt(g, s);
+ }
+ }
+ cgen_nl(g);
+ cgen_write(g, "main_();\n\treturn 0;\n}\n\n");
+ g->indent_lvl = 0;
/* function definitions */
arr_foreach(tr->all_fns, FnWithCtx, fn_ctx) {
g->nms = fn_ctx->nms;
diff --git a/main.c b/main.c
index 30bea22..05a94fe 100644
--- a/main.c
+++ b/main.c
@@ -8,8 +8,6 @@
/*
@TODO:
-#includes during parsing
-initialization statements (maybe #init(-50), where -50 is the priority and <0 is reserved for standard library)
if we do #include "foo.toc", bar; and foo.toc fails, bar should be declared as TYPE_UNKNOWN (right now it's undeclared)
improve type_to_str:
Foo ::= struct(t::Type) {}
@@ -94,7 +92,7 @@ static void signal_handler(int num) {
}
fprintf(stderr, "Stack trace:\n");
- static void *addrs[30];
+ static void *addrs[300];
int naddrs = (int)(sizeof addrs / sizeof *addrs);
naddrs = backtrace(addrs, naddrs);
/* char **syms = backtrace_symbols(addrs, naddrs); */
diff --git a/parse.c b/parse.c
index e59c48c..a48fc6b 100644
--- a/parse.c
+++ b/parse.c
@@ -2589,10 +2589,11 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) {
success = false; goto nms_done;
}
goto nms_done;
+ } else {
+ inc_f = str_hash_table_insert(p->included_files, filename, filename_len);
+ inc_f->flags |= INC_FILE_INCLUDING;
+ inc_f->main_nms = p->nms;
}
- inc_f = str_hash_table_insert(p->included_files, filename, filename_len);
- inc_f->flags |= INC_FILE_INCLUDING;
- inc_f->main_nms = p->nms;
}
{
char *contents = read_file_contents(p->allocr, filename, s->where);
diff --git a/test.toc b/test.toc
index 54f7b2b..5a5a328 100644
--- a/test.toc
+++ b/test.toc
@@ -1,16 +1 @@
-#include "tests/std/io.toc", io;
-#include "tests/std/io.toc", foo;
-#include "tests/std/io.toc", bar;
-#include "tests/std/io.toc", baz;
-#include "tests/std/io.toc";
-#include "tests/included.toc", inc;
-
-main ::= fn() {
- puts("hello");
- io.puts("hello");
- foo.puts("hello");
- bar.puts("hello");
- baz.puts("hello");
- inc.puts("hello");
- inc.foo.puts("hello");
-}
+#include "tests/std/mem.toc";
diff --git a/tests/init.toc b/tests/init.toc
new file mode 100644
index 0000000..ac85058
--- /dev/null
+++ b/tests/init.toc
@@ -0,0 +1,25 @@
+#init(-10) init(10);
+#init(44) init(44);
+#init(22) init(22);
+#init(88) init(88);
+#init(1002389) for i := 89..100 {init(i);}
+#init(-20) init(0);
+
+
+#include "std/io.toc";
+
+total : int;
+
+init ::= fn(x: int) {
+ if #builtin("compiling") { return; }
+ writes("Initializing... ");
+ writei(x);
+ puts("% complete");
+ total += x;
+}
+
+
+main ::= fn() {
+ writes("hello from main. total is ");
+ puti(total);
+}
diff --git a/tests/init_expected b/tests/init_expected
new file mode 100644
index 0000000..23c8267
--- /dev/null
+++ b/tests/init_expected
@@ -0,0 +1,18 @@
+Initializing... 0% complete
+Initializing... 10% complete
+Initializing... 22% complete
+Initializing... 44% complete
+Initializing... 88% complete
+Initializing... 89% complete
+Initializing... 90% complete
+Initializing... 91% complete
+Initializing... 92% complete
+Initializing... 93% complete
+Initializing... 94% complete
+Initializing... 95% complete
+Initializing... 96% complete
+Initializing... 97% complete
+Initializing... 98% complete
+Initializing... 99% complete
+Initializing... 100% complete
+hello from main. total is 1298
diff --git a/tests/std/base.toc b/tests/std/base.toc
index bdb91e0..54d64d6 100644
--- a/tests/std/base.toc
+++ b/tests/std/base.toc
@@ -20,4 +20,7 @@ PLATFORM ::= #builtin("platform");
libc ::= "libc.so.6";
}
+PLATFORM_IS_UNIX :: bool = PLATFORM == PLATFORM_LINUX || PLATFORM == PLATFORM_OSX || PLATFORM == PLATFORM_FREEBSD
+ || PLATFORM == PLATFORM_OPENBSD || PLATFORM == PLATFORM_MISC_UNIX;
+
diff --git a/types.c b/types.c
index c01cac6..7ec7520 100644
--- a/types.c
+++ b/types.c
@@ -592,7 +592,6 @@ enum {
};
static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
-
if (f->flags & FN_EXPR_FOREIGN) {
/* we've already mostly determined the type in parse_expr */
if (!type_resolve(tr, &f->foreign.type, f->where))
@@ -3823,16 +3822,15 @@ static Status types_file(Typer *tr, ParsedFile *f) {
bool ret = true;
tr->parsed_file = f;
tr->uses = NULL;
- /* @TODO(eventually): better sorting algorithm - a radix sort, perhaps */
qsort(f->inits, arr_len(f->inits), sizeof *f->inits, compare_inits);
arr_foreach(f->inits, Initialization, init) {
- if (!types_stmt(tr, &init->stmt))
- return false;
- if (!eval_stmt(tr->evalr, &init->stmt))
+ Statement *s = &init->stmt;
+ if (!types_stmt(tr, s))
return false;
+ if (s->kind != STMT_EXPR) /* already evaluated in types_stmt */
+ if (!eval_stmt(tr->evalr, s))
+ return false;
}
- /* avoid accidentally using inits after they are run */
- f->inits = NULL;
arr_foreach(f->stmts, Statement, s) {
if (!types_stmt(tr, s)) {
ret = false;
diff --git a/types.h b/types.h
index 1abe7eb..e5c665b 100644
--- a/types.h
+++ b/types.h
@@ -654,14 +654,11 @@ typedef struct FnExpr {
struct {
Type type; /* type of this function */
CType *ctypes; /* ctypes[i] = CTYPE_NONE if this isn't a ctype, or the specified CType. don't use this as a dynamic array. */
- union {
- const char *name;
- struct Expression *name_expr; /* before typing */
- };
- union {
- const char *lib;
- struct Expression *lib_expr;
- };
+ const char *name;
+ /* name of foreign function and dynamic library file it comes from (dll/so) */
+ struct Expression *name_expr; /* STILL VALID even after running type_of_fn, because sometimes we run type_of_fn multiple times on a function */
+ const char *lib;
+ struct Expression *lib_expr; /* see name_expr */
FnPtr fn_ptr;
} foreign;
};
@@ -987,7 +984,7 @@ typedef struct ParsedFile {
Statement *stmts;
/*
statements run before any typing happens
- after they are run, inits is set to NULL to avoid accidental usage
+ after typing, these will be in sorted order (for cgen)
*/
Initialization *inits;
} ParsedFile;