summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c3
-rw-r--r--test.toc17
-rw-r--r--types.c61
-rw-r--r--types.h1
4 files changed, 53 insertions, 29 deletions
diff --git a/main.c b/main.c
index 30558f3..0551ed9 100644
--- a/main.c
+++ b/main.c
@@ -11,6 +11,7 @@ TODO:
make sure that struct["member"] still works
use
- use with a decl, e.g. use p : Point;
+local structs should not be named in C
simplify eval macros with val_to_u/i64
&&, ||
start making a standard library... (printf; stringbuilder would be nice to have)
@@ -180,7 +181,7 @@ int main(int argc, char **argv) {
Typer tr;
Evaluator ev;
evalr_create(&ev, &tr, &main_allocr);
- typer_create(&tr, &ev, &err_ctx, &main_allocr, &globals);
+ typer_create(&tr, &ev, &file, &err_ctx, &main_allocr, &globals);
if (!types_file(&tr, &f)) {
err_text_important(&err_ctx, "Errors occured while determining types.\n");
diff --git a/test.toc b/test.toc
index 2b44207..1323f3f 100644
--- a/test.toc
+++ b/test.toc
@@ -1,13 +1,10 @@
-Point ::= struct {
- x, y: int;
-}
-
-mkpoint ::= fn(x, y: int) p: Point {
- p.x = x;
- p.y = y;
-}
-
main ::= fn() {
+ Point ::= struct {
+ x: int;
+ y, z: int;
+ }
p: Point;
- use p;
+ p.x = 6;
+ p.y = 13;
+ p.z = 43902;
}
diff --git a/types.c b/types.c
index 4686e4d..d210754 100644
--- a/types.c
+++ b/types.c
@@ -579,27 +579,51 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t) {
t->flags = 0;
Identifier i = *ident;
-#if 0
-#ifdef TOC_DEBUG
- if (i->idents->body != tr->block) {
- printf("Ident declaration mismatch for this ident:\n");
- print_location(where);
- printf("Typer is typing:\n");
- print_block_location(tr->block);
- printf("But the identifier's scope is:\n");
- print_block_location(i->idents->body);
- abort();
- }
-#else
- assert(i->idents->body == tr->block);
-#endif
-#endif
Block *b = tr->block;
bool undeclared = false;
- while (1) {
+ UsedExpr *used = arr_last(tr->used);
+ while (1) { /* for each block we are inside... */
/* OPTIM: only hash once */
Identifier translated = ident_translate(i, b ? &b->idents : tr->globals);
- if (translated && translated->decl_kind != IDECL_NONE) {
+ if (translated && translated->decl_kind == IDECL_NONE)
+ translated = NULL;
+ Statement *translated_is_from_use_stmt = NULL;
+ while (used && used->scope == b) {
+ /* look up identifier in this used thing. */
+ Statement *stmt = used->stmt;
+ Expression *expr = &stmt->use;
+ Type *type = &expr->type;
+ if (type->kind == TYPE_STRUCT) {
+ /* TODO */
+ } else {
+ assert(type_is_builtin(type, BUILTIN_NMS));
+ assert(expr->kind == EXPR_VAL);
+ Identifier nms_ident = ident_translate(i, &expr->val.nms->body.idents);
+ if (nms_ident && nms_ident->decl_kind != IDECL_NONE) {
+ if (translated) {
+ /* ambiguous ident reference */
+ char *s = ident_to_str(nms_ident);
+ err_print(where, "Ambiguous reference to identifier %s.", s);
+ info_print(stmt->where, "%s was imported from this use statement.", s);
+ info_print(ident_decl_location(tr->file, nms_ident), "Specifically, it was declared here.");
+ /*
+ we should have given an error about the use statement if it conflicted with a non-used ident,
+ so translated must be from another use stmt.
+ */
+ assert(translated_is_from_use_stmt);
+ info_print(translated_is_from_use_stmt->where, "...and also imported from *this* use statement.");
+ info_print(ident_decl_location(tr->file, translated), "Specifically, it was also declared here.");
+ }
+ translated = nms_ident;
+ translated_is_from_use_stmt = stmt;
+ }
+ }
+ if (used > tr->used)
+ --used;
+ else
+ used = NULL;
+ }
+ if (translated) {
#if 0
printf("translated %s from\n", ident_to_str(i));
print_block_location(i->idents->body);
@@ -3520,13 +3544,14 @@ static Status types_stmt(Typer *tr, Statement *s) {
return true;
}
-static void typer_create(Typer *tr, Evaluator *ev, ErrCtx *err_ctx, Allocator *allocr, Identifiers *idents) {
+static void typer_create(Typer *tr, Evaluator *ev, File *file, ErrCtx *err_ctx, Allocator *allocr, Identifiers *idents) {
tr->used = NULL;
tr->block = NULL;
tr->blocks = NULL;
tr->fn = NULL;
tr->nms = NULL;
tr->evalr = ev;
+ tr->file = file;
tr->err_ctx = err_ctx;
tr->in_decls = NULL;
tr->in_fors = NULL;
diff --git a/types.h b/types.h
index a3a211a..c71b5fd 100644
--- a/types.h
+++ b/types.h
@@ -1063,6 +1063,7 @@ typedef struct Typer {
Namespace *nms;
StrHashTable included_files; /* maps to IncludedFile */
UsedExpr *used; /* things which are currently being `use`d. dynamic array NOT on the allocator. */
+ File *file;
} Typer;
typedef struct CGenerator {