aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-09-14 22:58:24 +0100
committerGinger Bill <bill@gingerbill.org>2016-09-14 22:58:24 +0100
commitbd365e5176f3bc5f5e249d1a0763520e2973c2ec (patch)
tree0fe2d3f44fd478d4f5c1afc688c8d41f84be3a29 /src
parent79f575ae8e7dda58a842dda3690b691e942ea86e (diff)
Fix namespacing issues for #import; allow using ImportName
Diffstat (limited to 'src')
-rw-r--r--src/checker/checker.cpp16
-rw-r--r--src/checker/expr.cpp32
-rw-r--r--src/checker/stmt.cpp57
-rw-r--r--src/parser.cpp9
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);