diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-25 23:42:27 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-25 23:42:27 -0400 |
commit | 67c33cc90c737aa15f9b7214f9838c17253298c4 (patch) | |
tree | ceac521dfc3877508628aedb2d6745b865956094 | |
parent | 1949636463f53675f04e1315ad84ecc87def57cb (diff) | |
parent | 65d502fca7400ebcbe3134d730bf8570f7756c42 (diff) |
cleaning up a few struct things
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | test.toc | 17 | ||||
-rw-r--r-- | types.c | 61 | ||||
-rw-r--r-- | types.h | 1 |
4 files changed, 53 insertions, 29 deletions
@@ -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"); @@ -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; } @@ -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; @@ -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 { |