From: Brendan Hansen Date: Sun, 7 Feb 2021 13:56:11 +0000 (-0600) Subject: static ifs are very powerful now X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=8fdb45157f33780d3faf24a07490586ff2be7f16;p=onyx.git static ifs are very powerful now --- diff --git a/bin/onyx b/bin/onyx index afcd5eb8..680972bd 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 29c2ef97..274b97c0 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -703,8 +703,12 @@ struct AstInclude { AstNode_base; char* name; }; struct AstUsePackage { AstNode_base; - AstPackage *package; + OnyxToken *package_name; + Package *package; + OnyxToken *alias; + AstPackage *alias_node; + bh_arr(AstAlias *) only; }; struct AstAlias { @@ -924,7 +928,9 @@ extern const char* entity_type_strings[Entity_Type_Count]; typedef struct Entity { EntityType type; EntityState state; - u64 attempts; + u32 attempts; + + b32 entered_in_queue : 1; Package *package; Scope *scope; @@ -976,6 +982,11 @@ struct Package { 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; @@ -1053,7 +1064,7 @@ extern AstBasicType basic_type_v128; // :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; diff --git a/include/onyxutils.h b/include/onyxutils.h index 90963f3f..37fa8d64 100644 --- a/include/onyxutils.h +++ b/include/onyxutils.h @@ -12,6 +12,8 @@ const char* onyx_ast_node_kind_string(AstKind kind); 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); diff --git a/onyx.exe b/onyx.exe index 9b264008..262152ee 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyxbuiltins.c b/src/onyxbuiltins.c index 4ce2a256..d036182d 100644 --- a/src/onyxbuiltins.c +++ b/src/onyxbuiltins.c @@ -30,8 +30,7 @@ AstBasicType basic_type_f32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, "f32x4", 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 } }; diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 59f2d0c7..bcd96fc6 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -1501,6 +1501,7 @@ CheckStatus check_expression(AstTyped** pexpr) { default: retval = Check_Error; + onyx_report_error(expr->token->pos, "UNEXPECTED INTERNAL COMPILER ERROR"); DEBUG_HERE; break; } @@ -1808,6 +1809,11 @@ CheckStatus check_static_if(AstStaticIf* static_if) { 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? diff --git a/src/onyxentities.c b/src/onyxentities.c index 17ec1a50..ed849d5b 100644 --- a/src/onyxentities.c +++ b/src/onyxentities.c @@ -73,17 +73,21 @@ Entity* entity_heap_register(EntityHeap* entities, Entity e) { 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]++; @@ -115,6 +119,7 @@ void entity_heap_change_top(EntityHeap* entities, Entity* new_top) { 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); diff --git a/src/onyxparser.c b/src/onyxparser.c index bb140cb2..7248fef3 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -1156,25 +1156,24 @@ static AstNode* parse_use_stmt(OnyxParser* parser) { 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); @@ -2427,7 +2426,7 @@ void onyx_parse(OnyxParser *parser) { 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) { diff --git a/src/onyxsymres.c b/src/onyxsymres.c index d4f9a428..e02cd155 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -854,13 +854,17 @@ static SymresStatus symres_overloaded_function(AstOverloadedFunction* ofunc) { } 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; @@ -870,11 +874,13 @@ static SymresStatus symres_use_package(AstUsePackage* package) { 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) { @@ -901,6 +907,7 @@ static SymresStatus symres_use_package(AstUsePackage* package) { scope_include(curr_scope, p->scope, pos); } + return Symres_Success; } @@ -1032,6 +1039,7 @@ void symres_entity(Entity* ent) { 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; } @@ -1050,6 +1058,7 @@ void symres_entity(Entity* ent) { 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; @@ -1074,4 +1083,5 @@ void symres_entity(Entity* ent) { if (ss == Symres_Yield) ent->attempts++; if (ent->scope) curr_scope = old_scope; + curr_package = NULL; } diff --git a/src/onyxutils.c b/src/onyxutils.c index c13a654e..ec76f05a 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -37,6 +37,7 @@ Package* package_lookup_or_create(char* package_name, Scope* parent_scope, bh_al 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); @@ -44,6 +45,25 @@ Package* package_lookup_or_create(char* package_name, Scope* parent_scope, bh_al } } +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 @@ -130,7 +150,7 @@ AstNode* symbol_resolve(Scope* start_scope, OnyxToken* tkn) { token_toggle_end(tkn); AstNode* res = symbol_raw_resolve(start_scope, tkn->text); token_toggle_end(tkn); - + return res; }