diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-06-27 10:47:41 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-06-27 10:47:41 -0400 |
commit | 7e47f52a21fb73dde9e59fe1f0b5957ec119ccfd (patch) | |
tree | 8954c988a19882f7c537f27d450b72ed10829a6f | |
parent | 8080bfbe4a757d7a7d895654da6424d789e6d33c (diff) |
#init
-rw-r--r-- | cgen.c | 15 | ||||
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | parse.c | 7 | ||||
-rw-r--r-- | test.toc | 17 | ||||
-rw-r--r-- | tests/init.toc | 25 | ||||
-rw-r--r-- | tests/init_expected | 18 | ||||
-rw-r--r-- | tests/std/base.toc | 3 | ||||
-rw-r--r-- | types.c | 12 | ||||
-rw-r--r-- | types.h | 15 |
9 files changed, 77 insertions, 39 deletions
@@ -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; @@ -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); */ @@ -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); @@ -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; + @@ -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; @@ -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; |