diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-09-14 22:58:24 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-09-14 22:58:24 +0100 |
| commit | bd365e5176f3bc5f5e249d1a0763520e2973c2ec (patch) | |
| tree | 0fe2d3f44fd478d4f5c1afc688c8d41f84be3a29 /src | |
| parent | 79f575ae8e7dda58a842dda3690b691e942ea86e (diff) | |
Fix namespacing issues for #import; allow using ImportName
Diffstat (limited to 'src')
| -rw-r--r-- | src/checker/checker.cpp | 16 | ||||
| -rw-r--r-- | src/checker/expr.cpp | 32 | ||||
| -rw-r--r-- | src/checker/stmt.cpp | 57 | ||||
| -rw-r--r-- | src/parser.cpp | 9 |
4 files changed, 73 insertions, 41 deletions
diff --git a/src/checker/checker.cpp b/src/checker/checker.cpp index 6de9858eb..c95403e3c 100644 --- a/src/checker/checker.cpp +++ b/src/checker/checker.cpp @@ -118,6 +118,7 @@ struct Scope { b32 is_global; b32 is_file; b32 is_init; + AstFile *file; }; enum ExprKind { @@ -635,6 +636,10 @@ void add_entity_use(CheckerInfo *i, AstNode *identifier, Entity *entity) { GB_ASSERT(identifier->kind == AstNode_Ident); HashKey key = hash_pointer(identifier); map_set(&i->uses, key, entity); + + if (entity != NULL && entity->kind == Entity_ImportName) { + entity->ImportName.used = true; + } } @@ -820,8 +825,10 @@ void check_parsed_files(Checker *c) { scope = make_scope(c->global_scope, c->allocator); scope->is_global = f->is_global_scope; scope->is_file = true; + scope->file = f; if (i == 0) { // NOTE(bill): First file is always the initial file + // thus it must contain main scope->is_init = true; } @@ -830,7 +837,8 @@ void check_parsed_files(Checker *c) { } f->scope = scope; - map_set(&file_scopes, hash_string(f->tokenizer.fullpath), scope); + HashKey key = hash_string(f->tokenizer.fullpath); + map_set(&file_scopes, key, scope); } // Collect Entities @@ -980,6 +988,7 @@ void check_parsed_files(Checker *c) { } } } else { + GB_ASSERT(id->import_name.string.len > 0); Entity *e = make_entity_import_name(c->allocator, file_scope, id->import_name, t_invalid, id->fullpath, id->import_name.string, scope); @@ -995,10 +1004,11 @@ void check_parsed_files(Checker *c) { if (e->kind == kind) { DeclInfo *d = entry->value; + add_curr_ast_file(c, d->scope->file); + Scope *prev_scope = c->context.scope; c->context.scope = d->scope; - defer (c->context.scope = prev_scope); - + GB_ASSERT(d->scope == e->scope); check_entity_decl(c, e, d, NULL); } } diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index 0d113af23..982c28942 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -287,7 +287,6 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, Entity *e = make_entity_type_name(c->allocator, c->context.scope, name_token, NULL); add_entity(c, c->context.scope, td->name, e); - gb_printf("%.*s\n", LIT(e->token.string)); check_type_decl(c, e, td->type, NULL, NULL); HashKey key = hash_string(name_token.string); @@ -734,8 +733,25 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl if (are_strings_equal(n->Ident.string, make_string("_"))) { error(&c->error_collector, n->Ident, "`_` cannot be used as a value type"); } else { + auto *entries = c->context.scope->elements.entries; + // gb_for_array(i, entries) { + // Entity *elem = entries[i].value; + // if (i > 0) { + // gb_printf(", "); + // } + // gb_printf("%.*s", LIT(elem->token.string)); + // } + // for (Scope *s = c->context.scope; s != NULL; s = s->parent) { + // Entity *elem = s->elements.entries[0].value; + // if (elem == NULL) continue; + // gb_printf("%.*s\n", LIT(elem->token.pos.file)); + // } + // gb_printf("\n"); + + + // Entity *e = scope_lookup_entity(c->context.scope, n->Ident.string); error(&c->error_collector, n->Ident, - "Undeclared named: `%.*s`", LIT(n->Ident.string)); + "Undeclared name: %.*s", LIT(n->Ident.string)); } return; } @@ -915,11 +931,9 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c type = make_type_array(c->allocator, check_type(c, at->elem, NULL, cycle_checker), check_array_count(c, at->count)); - type->flags |= e->type_flags; set_base_type(named_type, type); } else { type = make_type_slice(c->allocator, check_type(c, at->elem)); - type->flags |= e->type_flags; set_base_type(named_type, type); } goto end; @@ -935,7 +949,6 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c error(&c->error_collector, ast_node_token(vt->elem), "Vector element type must be numerical or a boolean. Got `%s`", err_str); } type = make_type_vector(c->allocator, elem, count); - type->flags |= e->type_flags; set_base_type(named_type, type); goto end; case_end; @@ -947,7 +960,6 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c check_struct_type(c, type, e, cycle_checker); check_close_scope(c); type->Record.node = e; - type->flags |= e->type_flags; goto end; case_end; @@ -958,7 +970,6 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c check_union_type(c, type, e, cycle_checker); check_close_scope(c); type->Record.node = e; - type->flags |= e->type_flags; goto end; case_end; @@ -969,7 +980,6 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c check_raw_union_type(c, type, e, cycle_checker); check_close_scope(c); type->Record.node = e; - type->flags |= e->type_flags; goto end; case_end; @@ -978,22 +988,21 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c set_base_type(named_type, type); check_enum_type(c, type, named_type, e); type->Record.node = e; - type->flags |= e->type_flags; goto end; case_end; case_ast_node(pt, PointerType, e); type = make_type_pointer(c->allocator, check_type(c, pt->type)); - type->flags |= e->type_flags; set_base_type(named_type, type); goto end; case_end; case_ast_node(pt, ProcType, e); type = alloc_type(c->allocator, Type_Proc); - type->flags |= e->type_flags; set_base_type(named_type, type); + check_open_scope(c, e); check_procedure_type(c, type, e); + check_close_scope(c); goto end; case_end; @@ -1003,7 +1012,6 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c check_expr_or_type(c, &o, e); if (o.mode == Addressing_Type) { type = o.type; - type->flags |= e->type_flags; goto end; } } diff --git a/src/checker/stmt.cpp b/src/checker/stmt.cpp index d97b68d14..aedf4eec9 100644 --- a/src/checker/stmt.cpp +++ b/src/checker/stmt.cpp @@ -446,7 +446,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d, b32 check_body_later) { // add_proc_entity(c, d->scope, pd->name, e); if (d->scope->is_proc) { // Nested procedures - add_entity(c, d->scope, pd->name, e); + add_entity(c, d->scope->parent, pd->name, e); } @@ -562,11 +562,7 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, CycleChecker *cycle_checker) { if (e->type != NULL) { - if (e->type->kind == Type_Named && e->type->Named.base == NULL) { - // NOTE(bill): Some weird declaration error from Entity_ImportName - } else { - return; - } + return; } if (d == NULL) { @@ -578,26 +574,42 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, Cyc } } + c->context.decl = d; + + if (e->kind == Entity_Procedure) { + check_proc_decl(c, e, d, true); + return; + } + + + switch (e->kind) { case Entity_Constant: { Scope *prev = c->context.scope; c->context.scope = d->scope; - c->context.decl = d; + defer (c->context.scope = prev); check_const_decl(c, e, d->type_expr, d->init_expr); - - c->context.scope = prev; } break; + case Entity_Variable: { Scope *prev = c->context.scope; c->context.scope = d->scope; - c->context.decl = d; + defer (c->context.scope = prev); check_var_decl(c, e, d->entities, d->entity_count, d->type_expr, d->init_expr); + } break; - c->context.scope = prev; + case Entity_Procedure: { + check_proc_decl(c, e, d, true); } break; + + case Entity_TypeName: { + Scope *prev = c->context.scope; + c->context.scope = d->scope; + defer (c->context.scope = prev); + CycleChecker local_cycle_checker = {}; if (cycle_checker == NULL) { cycle_checker = &local_cycle_checker; @@ -608,11 +620,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, Cyc gb_array_free(local_cycle_checker.path); } } break; - case Entity_Procedure: - check_proc_decl(c, e, d, true); - break; } - } @@ -1309,7 +1317,14 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { Entity *decl = scope->elements.entries[i].value; Entity *found = scope_insert_entity(c->context.scope, decl); if (found != NULL) { - error(&c->error_collector, us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string)); + error(&c->error_collector, us->token, + "Namespace collision while `using` `%s` of: %.*s\n" + "\tat %.*s(%td:%td)\n" + "\tat %.*s(%td:%td)", + expr_str, LIT(found->token.string), + LIT(found->token.pos.file), found->token.pos.line, found->token.pos.column, + LIT(decl->token.pos.file), decl->token.pos.line, decl->token.pos.column + ); return; } } @@ -1406,13 +1421,11 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { case_ast_node(pd, ProcDecl, node); ast_node(name, Ident, pd->name); Entity *e = make_entity_procedure(c->allocator, c->context.scope, *name, NULL); - // add_proc_entity(c, c->context.scope, pd->name, e); + add_entity(c, c->context.scope, pd->name, e); - DeclInfo decl = {}; - init_declaration_info(&decl, e->scope); - decl.proc_decl = node; - check_proc_decl(c, e, &decl, false); - destroy_declaration_info(&decl); + DeclInfo *decl = make_declaration_info(c->allocator, e->scope); + decl->proc_decl = node; + check_proc_decl(c, e, decl, false); case_end; case_ast_node(td, TypeDecl, node); diff --git a/src/parser.cpp b/src/parser.cpp index 57f5f8eff..c13fc774c 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2539,18 +2539,19 @@ AstNode *parse_stmt(AstFile *f) { case Token_Hash: { s = parse_tag_stmt(f, NULL); String tag = s->TagStmt.name.string; - if (are_strings_equal(tag, make_string("global_scope"))) { + if (are_strings_equal(tag, make_string("shared_global_scope"))) { if (f->curr_proc == NULL) { f->is_global_scope = true; return make_empty_stmt(f, f->cursor[0]); } - ast_file_err(f, token, "You cannot use #global_scope within a procedure. This must be done at the file scope."); + ast_file_err(f, token, "You cannot use #shared_global_scope within a procedure. This must be done at the file scope."); return make_bad_decl(f, token, f->cursor[0]); } else if (are_strings_equal(tag, make_string("import"))) { // TODO(bill): better error messages + Token import_name; Token file_path = expect_token(f, Token_String); - Token as = expect_token(f, Token_as); - Token import_name = expect_token(f, Token_Identifier); + expect_token(f, Token_as); + import_name = expect_token(f, Token_Identifier); if (f->curr_proc == NULL) { return make_import_decl(f, s->TagStmt.token, file_path, import_name); |