diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-23 00:39:58 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-23 00:39:58 -0400 |
commit | 65d502fca7400ebcbe3134d730bf8570f7756c42 (patch) | |
tree | 69f204da572731df1493f36df96acbeebffd9b53 | |
parent | 8e5951cefcffcd74674233637c07137c6f60ecc1 (diff) |
more use
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | test.toc | 13 | ||||
-rw-r--r-- | types.c | 61 | ||||
-rw-r--r-- | types.h | 1 |
4 files changed, 49 insertions, 28 deletions
@@ -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"); @@ -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; } @@ -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; @@ -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 { |