struct AstUsePackage {
AstNode_base;
- AstPackage *package;
+ OnyxToken *package_name;
+ Package *package;
+
OnyxToken *alias;
+ AstPackage *alias_node;
+
bh_arr(AstAlias *) only;
};
struct AstAlias {
typedef struct Entity {
EntityType type;
EntityState state;
- u64 attempts;
+ u32 attempts;
+
+ b32 entered_in_queue : 1;
Package *package;
Scope *scope;
Scope *scope;
Scope *private_scope;
+
+ // NOTE: This tracks all of the 'use package' statements of this package throughout
+ // the code base. This is used when a static if clears and new symbols are introduced.
+ // 'use package' statements have to be reevaluated to pull in the new symbols.
+ bh_arr(Entity *) use_package_entities;
};
typedef enum CompileAction CompileAction;
// :TypeExprHack
extern AstNode type_expr_symbol;
-extern AstNode builtin_package_node;
+extern OnyxToken builtin_package_token;
extern AstNumLit builtin_heap_start;
extern AstGlobal builtin_stack_top;
extern AstType *builtin_string_type;
Package* package_lookup(char* package_name);
Package* package_lookup_or_create(char* package_name, Scope* parent_scope, bh_allocator alloc);
+void package_track_use_package(Package* package, Entity* entity);
+void package_reinsert_use_packages(Package* package);
void scope_include(Scope* target, Scope* source, OnyxFilePos pos);
b32 symbol_introduce(Scope* scope, OnyxToken* tkn, AstNode* symbol);
AstBasicType basic_type_f64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, "f64x2", &basic_types[Basic_Kind_F64X2] };
AstBasicType basic_type_v128 = { Ast_Kind_Basic_Type, 0, &simd_token, "v128", &basic_types[Basic_Kind_V128] };
-static OnyxToken builtin_package_token = { Token_Type_Symbol, 7, "builtin ", { 0 } };
-AstNode builtin_package_node = { Ast_Kind_Symbol, Ast_Flag_No_Clone, &builtin_package_token, NULL };
+OnyxToken builtin_package_token = { Token_Type_Symbol, 7, "builtin ", { 0 } };
static OnyxToken builtin_heap_start_token = { Token_Type_Symbol, 12, "__heap_start ", { 0 } };
static OnyxToken builtin_stack_top_token = { Token_Type_Symbol, 11, "__stack_top ", { 0 } };
default:
retval = Check_Error;
+ onyx_report_error(expr->token->pos, "UNEXPECTED INTERNAL COMPILER ERROR");
DEBUG_HERE;
break;
}
return Check_Error;
}
+ if (!type_is_bool(static_if->cond->type)) {
+ onyx_report_error(static_if->token->pos, "Expected this condition to be a boolean value.");
+ return Check_Error;
+ }
+
AstNumLit* condition_value = (AstNumLit *) static_if->cond;
assert(condition_value->kind == Ast_Kind_NumLit); // This should be right, right?
Entity* entity = bh_alloc_item(alloc, Entity);
*entity = e;
entity->attempts = 0;
+ entity->entered_in_queue = 0;
return entity;
}
void entity_heap_insert_existing(EntityHeap* entities, Entity* e) {
+ if (e->entered_in_queue) return;
+
if (entities->entities == NULL) {
bh_arr_new(global_heap_allocator, entities->entities, 128);
- }
+ }
bh_arr_push(entities->entities, e);
eh_shift_up(entities, bh_arr_length(entities->entities) - 1);
+ e->entered_in_queue = 1;
entities->state_count[e->state]++;
entities->type_count[e->type]++;
void entity_heap_remove_top(EntityHeap* entities) {
entities->state_count[entities->entities[0]->state]--;
entities->type_count[entities->entities[0]->type]--;
+ entities->entities[0]->entered_in_queue = 0;
entities->entities[0] = entities->entities[bh_arr_length(entities->entities) - 1];
bh_arr_pop(entities->entities);
AstUsePackage* upack = make_node(AstUsePackage, Ast_Kind_Use_Package);
upack->token = use_token;
- AstNode* pack_symbol = make_node(AstNode, Ast_Kind_Symbol);
- pack_symbol->token = expect_token(parser, Token_Type_Symbol);
+ OnyxToken* package_name = expect_token(parser, Token_Type_Symbol);
// CLEANUP: This is just gross.
if (consume_token_if_next(parser, '.')) {
- pack_symbol->token->length += 1;
+ package_name->length += 1;
while (1) {
if (parser->hit_unexpected_token) break;
OnyxToken* symbol = expect_token(parser, Token_Type_Symbol);
- pack_symbol->token->length += symbol->length;
+ package_name->length += symbol->length;
- if (consume_token_if_next(parser, '.')) pack_symbol->token->length += 1;
+ if (consume_token_if_next(parser, '.')) package_name->length += 1;
else break;
}
}
- upack->package = (AstPackage *) pack_symbol;
+ upack->package_name = package_name;
if (consume_token_if_next(parser, Token_Type_Keyword_As))
upack->alias = expect_token(parser, Token_Type_Symbol);
bh_arr_push(parser->scope_stack, parser->file_scope);
AstUsePackage* implicit_use_builtin = make_node(AstUsePackage, Ast_Kind_Use_Package);
- implicit_use_builtin->package = (AstPackage *) &builtin_package_node;
+ implicit_use_builtin->package_name = &builtin_package_token;
ENTITY_SUBMIT(implicit_use_builtin);
while (parser->curr->type != Token_Type_End_Stream) {
}
static SymresStatus symres_use_package(AstUsePackage* package) {
- token_toggle_end(package->package->token);
- Package* p = package_lookup(package->package->token->text);
- token_toggle_end(package->package->token);
+ if (package->package == NULL) {
+ token_toggle_end(package->package_name);
+ package->package = package_lookup(package->package_name->text);
+ token_toggle_end(package->package_name);
+ }
+
+ Package* p = package->package;
if (p == NULL) { // :SymresStall
if (report_unresolved_symbols) {
- onyx_report_error(package->token->pos, "package not found in included source files");
+ onyx_report_error(package->package_name->pos, "package not found in included source files");
return Symres_Error;
} else {
return Symres_Yield;
if (p->scope == curr_scope) return Symres_Success;
if (package->alias != NULL) {
- AstPackage *pac_node = onyx_ast_node_new(context.ast_alloc, sizeof(AstPackage), Ast_Kind_Package);
- pac_node->package = p;
- pac_node->token = package->alias;
+ if (!package->alias_node) {
+ package->alias_node = onyx_ast_node_new(context.ast_alloc, sizeof(AstPackage), Ast_Kind_Package);
+ package->alias_node->package = p;
+ package->alias_node->token = package->alias;
+ }
- symbol_introduce(curr_scope, package->alias, (AstNode *) pac_node);
+ symbol_introduce(curr_scope, package->alias, (AstNode *) package->alias_node);
}
if (package->only != NULL) {
scope_include(curr_scope, p->scope, pos);
}
+
return Symres_Success;
}
switch (ent->type) {
case Entity_Type_Binding: {
symbol_introduce(curr_scope, ent->binding->token, ent->binding->node);
+ package_reinsert_use_packages(curr_package);
next_state = Entity_State_Finalized;
break;
}
case Entity_Type_Global_Header: ss = symres_global(ent->global); break;
case Entity_Type_Use_Package: ss = symres_use_package(ent->use_package);
+ if (ent->use_package->package) package_track_use_package(ent->use_package->package, ent);
next_state = Entity_State_Finalized;
break;
if (ss == Symres_Yield) ent->attempts++;
if (ent->scope) curr_scope = old_scope;
+ curr_package = NULL;
}
package->name = pac_name;
package->scope = scope_create(alloc, parent_scope, (OnyxFilePos) { 0 });
package->private_scope = scope_create(alloc, package->scope, (OnyxFilePos) { 0 });
+ package->use_package_entities = NULL;
bh_table_put(Package *, context.packages, pac_name, package);
}
}
+void package_track_use_package(Package* package, Entity* entity) {
+ if (package->use_package_entities == NULL) {
+ bh_arr_new(global_heap_allocator, package->use_package_entities, 4);
+ }
+
+ bh_arr_push(package->use_package_entities, entity);
+}
+
+void package_reinsert_use_packages(Package* package) {
+ if (!package->use_package_entities) return;
+
+ bh_arr_each(Entity *, use_package, package->use_package_entities) {
+ (*use_package)->state = Entity_State_Comptime_Resolve_Symbols;
+ entity_heap_insert_existing(&context.entities, *use_package);
+ }
+
+ bh_arr_set_length(package->use_package_entities, 0);
+}
+
//
// Scoping
token_toggle_end(tkn);
AstNode* res = symbol_raw_resolve(start_scope, tkn->text);
token_toggle_end(tkn);
-
+
return res;
}