summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-04-25 14:09:30 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-04-25 14:09:30 -0400
commit7aa21a12d1b5505ba6258f2a74ce8716e72387c3 (patch)
treeb6067441f028cf42708cc065235920aefa25e980
parent342f08a7753495f51eb19dfee6d1b23bbddf344e (diff)
improved #include error handling
-rw-r--r--main.c2
-rw-r--r--test.toc23
-rw-r--r--types.c25
-rw-r--r--types.h5
4 files changed, 29 insertions, 26 deletions
diff --git a/main.c b/main.c
index c02fa6a..2d42a45 100644
--- a/main.c
+++ b/main.c
@@ -8,8 +8,6 @@
/*
@TODO:
-allow `use ???;` if an error has already occurred
-if something gets included into a namespace, and its typing fails, the namespace should still be of type namespace, not ???
make sure you can do a[i] where a is &[5]int or &[]char or something
do we consistently handle x := &some_array_or_slice; x.len
use
diff --git a/test.toc b/test.toc
index 2433499..2a171ed 100644
--- a/test.toc
+++ b/test.toc
@@ -1,23 +1,6 @@
-#include "std/io.toc";
-#include "std/mem.toc";
-
-generate_numbers ::= fn() []int {
- nums := news(int, 10);
- for n, i := &nums {
- *n = i*i;
- }
- nums
-}
-
-hw := "hello, world!";
-nums := generate_numbers();
+#include "std/io.toc", io;
+use io;
main ::= fn() {
- hw[0] = 'j';
- nums[5] = 183;
- puts(hw);
- for x := nums {
- puti(x);
- }
-
+ puts("hi");
}
diff --git a/types.c b/types.c
index 63b96c5..af52f60 100644
--- a/types.c
+++ b/types.c
@@ -1520,10 +1520,16 @@ static Status expr_must_usable_(Expression *e) {
return false;
}
-static Status expr_must_usable(Expression *e) {
+static Status expr_must_usable(Typer *tr, Expression *e) {
Type *t = &e->type;
if (t->kind != TYPE_STRUCT && !type_is_builtin(t, BUILTIN_NMS)) {
if (!(t->kind == TYPE_PTR && t->ptr->kind == TYPE_STRUCT)) {
+ if (t->kind == TYPE_UNKNOWN) {
+ if (tr->err_ctx->have_errored) {
+ /* silently fail; this could've been because of an earlier error */
+ return false;
+ }
+ }
char *str = type_to_str(&e->type);
err_print(e->where, "You cannot use something of type %s (only Namespaces and structs).", str);
free(str);
@@ -1548,7 +1554,7 @@ static Status use_ident(Typer *tr, Identifier i, Type *t, Location where) {
used->type = *t;
used->ident = i;
used->where = where;
- if (!expr_must_usable(used))
+ if (!expr_must_usable(tr, used))
return false;
return true;
}
@@ -3289,6 +3295,10 @@ static Status types_block(Typer *tr, Block *b) {
arr_foreach(b->stmts, Statement, s) {
if (!types_stmt(tr, s)) {
success = false;
+ if (tr->had_include_err) {
+ /* stop immediately; prevent too many "undeclared identifier" errors */
+ break;
+ }
continue;
}
if (s->kind == STMT_EXPR && (s->flags & STMT_EXPR_NO_SEMICOLON)) {
@@ -3579,8 +3589,10 @@ static Status types_stmt(Typer *tr, Statement *s) {
inc_f->main_nms = tr->nms;
}
char *contents = read_file_contents(tr->allocr, filename, s->where);
- if (!contents)
+ if (!contents) {
+ tr->had_include_err = true;
return false;
+ }
Tokenizer tokr;
tokr_create(&tokr, tr->err_ctx, tr->allocr);
@@ -3662,7 +3674,7 @@ static Status types_stmt(Typer *tr, Statement *s) {
Expression *e = &u->expr;
if (!types_expr(tr, e))
return false;
- if (!expr_must_usable(e)) {
+ if (!expr_must_usable(tr, e)) {
return false;
}
if (tr->block)
@@ -3684,6 +3696,7 @@ static void typer_create(Typer *tr, Evaluator *ev, File *file, ErrCtx *err_ctx,
tr->file = file;
tr->err_ctx = err_ctx;
tr->in_decls = NULL;
+ tr->had_include_err = false;
tr->allocr = allocr;
tr->globals = idents;
typer_arr_add(tr, tr->blocks, NULL);
@@ -3696,6 +3709,10 @@ static Status types_file(Typer *tr, ParsedFile *f) {
tr->uses = NULL;
arr_foreach(f->stmts, Statement, s) {
if (!types_stmt(tr, s)) {
+ if (tr->had_include_err) {
+ /* stop immediately; prevent too many "undeclared identifier" errors */
+ return false;
+ }
ret = false;
}
}
diff --git a/types.h b/types.h
index d3a4e35..9a19d5b 100644
--- a/types.h
+++ b/types.h
@@ -1037,6 +1037,11 @@ typedef struct Typer {
Namespace *nms;
StrHashTable included_files; /* maps to IncludedFile */
File *file;
+ /*
+ have we had an error because we couldn't find a file that was #include'd
+ (so that we can stop compiling immediately)
+ */
+ bool had_include_err;
} Typer;
typedef struct CGenerator {