summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c3
-rw-r--r--test.toc10
-rw-r--r--types.c36
3 files changed, 30 insertions, 19 deletions
diff --git a/main.c b/main.c
index cd61f6d..e54659d 100644
--- a/main.c
+++ b/main.c
@@ -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:
diff --git a/test.toc b/test.toc
index 532cc56..438efc3 100644
--- a/test.toc
+++ b/test.toc
@@ -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);
diff --git a/types.c b/types.c
index c30e9df..1ceec1b 100644
--- a/types.c
+++ b/types.c
@@ -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;