summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-03-23 00:39:58 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-03-23 00:39:58 -0400
commit65d502fca7400ebcbe3134d730bf8570f7756c42 (patch)
tree69f204da572731df1493f36df96acbeebffd9b53
parent8e5951cefcffcd74674233637c07137c6f60ecc1 (diff)
more use
-rw-r--r--main.c2
-rw-r--r--test.toc13
-rw-r--r--types.c61
-rw-r--r--types.h1
4 files changed, 49 insertions, 28 deletions
diff --git a/main.c b/main.c
index 86916d1..1b863ad 100644
--- a/main.c
+++ b/main.c
@@ -179,7 +179,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..40e787f 100644
--- a/test.toc
+++ b/test.toc
@@ -1,13 +1,8 @@
-Point ::= struct {
- x, y: int;
-}
-
-mkpoint ::= fn(x, y: int) p: Point {
- p.x = x;
- p.y = y;
+n ::= nms {
+ a := 17;
}
main ::= fn() {
- p: Point;
- use p;
+ use n;
+ x := a;
}
diff --git a/types.c b/types.c
index a669bf7..be5879e 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->scope != 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->scope);
- abort();
- }
-#else
- assert(i->idents->scope == 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->scope);
@@ -3504,13 +3528,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 710faf8..b75ba71 100644
--- a/types.h
+++ b/types.h
@@ -1057,6 +1057,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 {