mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-31 11:50:07 +00:00
#import and #load
#import - imported entities will not get exported #load - loaded entities will get exported
This commit is contained in:
+19
-2
@@ -111,6 +111,7 @@ struct Scope {
|
||||
Scope *prev, *next;
|
||||
Scope *first_child, *last_child;
|
||||
Map<Entity *> elements; // Key: String
|
||||
Map<Entity *> implicit; // Key: String
|
||||
|
||||
gbArray(Scope *) shared;
|
||||
gbArray(Scope *) imported;
|
||||
@@ -216,6 +217,7 @@ struct CheckerInfo {
|
||||
Map<DeclInfo *> entities; // Key: Entity *
|
||||
Map<Entity *> foreign_procs; // Key: String
|
||||
Map<isize> type_info_map; // Key: Type *
|
||||
Map<AstFile *> files; // Key: String
|
||||
isize type_info_index;
|
||||
};
|
||||
|
||||
@@ -261,8 +263,10 @@ Scope *make_scope(Scope *parent, gbAllocator allocator) {
|
||||
Scope *s = gb_alloc_item(allocator, Scope);
|
||||
s->parent = parent;
|
||||
map_init(&s->elements, gb_heap_allocator());
|
||||
map_init(&s->implicit, gb_heap_allocator());
|
||||
gb_array_init(s->shared, gb_heap_allocator());
|
||||
gb_array_init(s->imported, gb_heap_allocator());
|
||||
|
||||
if (parent != NULL && parent != universal_scope) {
|
||||
DLIST_APPEND(parent->first_child, parent->last_child, s);
|
||||
}
|
||||
@@ -286,6 +290,7 @@ void destroy_scope(Scope *scope) {
|
||||
}
|
||||
|
||||
map_destroy(&scope->elements);
|
||||
map_destroy(&scope->implicit);
|
||||
gb_array_free(scope->shared);
|
||||
gb_array_free(scope->imported);
|
||||
|
||||
@@ -397,8 +402,9 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) {
|
||||
if (found)
|
||||
return *found;
|
||||
map_set(&s->elements, key, entity);
|
||||
if (entity->scope == NULL)
|
||||
if (entity->scope == NULL) {
|
||||
entity->scope = s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -506,6 +512,7 @@ void init_checker_info(CheckerInfo *i) {
|
||||
map_init(&i->untyped, a);
|
||||
map_init(&i->foreign_procs, a);
|
||||
map_init(&i->type_info_map, a);
|
||||
map_init(&i->files, a);
|
||||
i->type_info_index = 0;
|
||||
|
||||
}
|
||||
@@ -519,6 +526,8 @@ void destroy_checker_info(CheckerInfo *i) {
|
||||
map_destroy(&i->untyped);
|
||||
map_destroy(&i->foreign_procs);
|
||||
map_destroy(&i->type_info_map);
|
||||
map_destroy(&i->files);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -889,6 +898,7 @@ void check_parsed_files(Checker *c) {
|
||||
f->scope = scope;
|
||||
HashKey key = hash_string(f->tokenizer.fullpath);
|
||||
map_set(&file_scopes, key, scope);
|
||||
map_set(&c->info.files, key, f);
|
||||
}
|
||||
|
||||
// Collect Entities
|
||||
@@ -1032,10 +1042,17 @@ void check_parsed_files(Checker *c) {
|
||||
// NOTE(bill): Add imported entities to this file's scope
|
||||
gb_for_array(elem_index, scope->elements.entries) {
|
||||
Entity *e = scope->elements.entries[elem_index].value;
|
||||
if (e->scope == file_scope) {
|
||||
continue;
|
||||
}
|
||||
// NOTE(bill): Do not add other imported entities
|
||||
if (e->scope == scope && e->kind != Entity_ImportName) {
|
||||
if (e->kind != Entity_ImportName) {
|
||||
if (is_entity_exported(e)) {
|
||||
add_entity(c, file_scope, NULL, e);
|
||||
if (!id->is_load) {
|
||||
HashKey key = hash_string(e->token.string);
|
||||
map_set(&file_scope->implicit, key, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-6
@@ -2000,19 +2000,28 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
|
||||
Entity *e = scope_lookup_entity(c->context.scope, name);
|
||||
add_entity_use(&c->info, op_expr, e);
|
||||
if (e != NULL && e->kind == Entity_ImportName) {
|
||||
String sel_name = selector->Ident.string;
|
||||
check_op_expr = false;
|
||||
entity = scope_lookup_entity(e->ImportName.scope, selector->Ident.string);
|
||||
entity = scope_lookup_entity(e->ImportName.scope, sel_name);
|
||||
if (entity == NULL) {
|
||||
gbString sel_str = expr_to_string(selector);
|
||||
defer (gb_string_free(sel_str));
|
||||
error(&c->error_collector, ast_node_token(op_expr), "`%s` is not declared by `%.*s`", sel_str, LIT(name));
|
||||
error(&c->error_collector, ast_node_token(op_expr), "`%.*s` is not declared by `%.*s`", LIT(sel_name), LIT(name));
|
||||
goto error;
|
||||
}
|
||||
if (entity->type == NULL) { // Not setup yet
|
||||
check_entity_decl(c, entity, NULL, NULL);
|
||||
}
|
||||
GB_ASSERT(entity->type != NULL);
|
||||
if (!is_entity_exported(entity)) {
|
||||
// if (!is_entity_exported(entity)) {
|
||||
b32 is_not_exported = !((e->ImportName.scope == entity->scope) && (entity->kind != Entity_ImportName));
|
||||
|
||||
if (is_not_exported) {
|
||||
auto found = map_get(&e->ImportName.scope->implicit, hash_string(sel_name));
|
||||
if (!found) {
|
||||
is_not_exported = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_not_exported) {
|
||||
gbString sel_str = expr_to_string(selector);
|
||||
defer (gb_string_free(sel_str));
|
||||
error(&c->error_collector, ast_node_token(op_expr), "`%s` is not exported by `%.*s`", sel_str, LIT(name));
|
||||
@@ -3044,8 +3053,8 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
|
||||
case_ast_node(pl, ProcLit, node);
|
||||
check_open_scope(c, pl->type);
|
||||
c->context.decl = make_declaration_info(c->allocator, c->context.scope);
|
||||
defer (check_close_scope(c));
|
||||
c->context.decl = make_declaration_info(c->allocator, c->context.scope);
|
||||
Type *proc_type = check_type(c, pl->type);
|
||||
if (proc_type != NULL) {
|
||||
check_proc_body(c, empty_token, c->context.decl, proc_type, pl->body);
|
||||
|
||||
Reference in New Issue
Block a user