diff options
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | test.toc | 10 | ||||
-rw-r--r-- | types.c | 36 |
3 files changed, 30 insertions, 19 deletions
@@ -8,8 +8,7 @@ /* @TODO: -i think what we need to do is put all of the standalone statements (like main();) and all of the constant decls into an array, - and iterate over all of them after everything is typed, and after all the initializations are run. +#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: @@ -1,21 +1,19 @@ -init(3); #include "tests/std/io.toc"; -/* #init(-50) init(1); #init(30) init(2); #init(-7) init(3); #init(-42) init(4); -*/ -x: int; init ::= fn(a: int) { - writes("Initializing... #"); - writei(a); + //writes("Initializing... #"); + //writei(a); x = 5; } +x: int; + main ::= fn() { writes("Main's value of x is: "); puti(x); @@ -36,6 +36,17 @@ static inline void typer_block_enter(Typer *tr, Block *b) { tr->block = b; } +static inline bool block_is_at_top_level(Block *b) { + for (Block *bb = b; bb; bb = bb->parent) + if (bb->kind != BLOCK_NMS) + return false; + return true; +} + +static bool is_at_top_level(Typer *tr) { + return block_is_at_top_level(tr->block); +} + static size_t compiler_sizeof_builtin(BuiltinType b) { switch (b) { case BUILTIN_I8: return sizeof(I8); @@ -834,9 +845,21 @@ top:; free(s); return false; } - if ((d->flags & DECL_IS_CONST) && (tr->block == NULL)) { - /* let's type the declaration, and redo this (for evaling future constants) */ + Block *decl_block = i->idents->scope; + if (block_is_at_top_level(decl_block)) { + /* + let's type the declaration, and redo this (for calling future functions at compile time) + this makes sure the error is right for: + foo(); + bar : int; + foo ::= fn() { bar = 6; } + (it should be that you can't access non-constant bar at compile time, not that you're using before declaring) + This isn't needed if bar's block is non-NULL because functions can't capture variables + */ + Block *prev_block = tr->block; + tr->block = decl_block; if (!types_decl(tr, d)) return false; + tr->block = prev_block; goto top; } else { char *s = ident_to_str(i); @@ -2982,15 +3005,6 @@ static Status types_block(Typer *tr, Block *b) { return success; } -static bool is_at_top_level(Typer *tr) { - for (Block *b = tr->block; b; b = b->parent) { - if (b && b->kind != BLOCK_NMS) { - return false; - } - } - return true; -} - static Status types_decl(Typer *tr, Declaration *d) { Type *dtype = &d->type; if (d->flags & DECL_FOUND_TYPE) return true; |