From: Brendan Hansen Date: Wed, 2 Jun 2021 04:44:27 +0000 (-0500) Subject: MAYBE BREAKING CHANGE; everything can defer right now so order doesn't matter X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=9daee52cf9f1579e08eebbbcc4c8db330a069b92;p=onyx.git MAYBE BREAKING CHANGE; everything can defer right now so order doesn't matter --- diff --git a/bin/onyx b/bin/onyx index 15f11343..407ea599 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 87c20fa2..a75694f1 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -229,6 +229,10 @@ typedef enum AstFlags { Ast_Flag_Incomplete_Body = BH_BIT(24), Ast_Flag_Array_Literal_Typed = BH_BIT(25), + + Ast_Flag_Has_Been_Symres = BH_BIT(26), + + Ast_Flag_Static_If_Resolved = BH_BIT(27), } AstFlags; typedef enum UnaryOp { @@ -924,8 +928,6 @@ typedef enum EntityState { Entity_State_Parse_Builtin, Entity_State_Introduce_Symbols, Entity_State_Parse, - Entity_State_Comptime_Resolve_Symbols, - Entity_State_Comptime_Check_Types, Entity_State_Resolve_Symbols, Entity_State_Check_Types, Entity_State_Code_Gen, diff --git a/src/onyx.c b/src/onyx.c index ea6a5e58..dd22f2d9 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -318,12 +318,8 @@ static b32 process_entity(Entity* ent) { ent->state = Entity_State_Finalized; break; - case Entity_State_Comptime_Resolve_Symbols: case Entity_State_Resolve_Symbols: symres_entity(ent); break; - - case Entity_State_Comptime_Check_Types: case Entity_State_Check_Types: check_entity(ent); break; - case Entity_State_Code_Gen: emit_entity(ent); break; } diff --git a/src/onyxastnodes.c b/src/onyxastnodes.c index 4db5c8f5..d185a243 100644 --- a/src/onyxastnodes.c +++ b/src/onyxastnodes.c @@ -111,8 +111,6 @@ const char* entity_state_strings[Entity_State_Count] = { "Parse Builtin", "Introduce Symbols", "Parse", - "Resolve Static Symbols", - "Check Static Types", "Resolve Symbols", "Check Types", "Code Gen", diff --git a/src/onyxchecker.c b/src/onyxchecker.c index deafb062..1725f282 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -16,6 +16,7 @@ typedef enum CheckStatus { Check_Complete, // The node is done processing Check_Errors_Start, + Check_Yield_Macro, Check_Error, // There was an error when checking the node } CheckStatus; @@ -130,6 +131,10 @@ CheckStatus check_if(AstIfWhile* ifnode) { if (ifnode->assignment != NULL) CHECK(statement, (AstNode **) &ifnode->assignment); if (ifnode->kind == Ast_Kind_Static_If) { + if ((ifnode->flags & Ast_Flag_Static_If_Resolved) == 0) { + return Check_Yield_Macro; + } + if (static_if_resolution(ifnode)) { if (ifnode->true_stmt != NULL) CHECK(statement, (AstNode **) &ifnode->true_stmt); @@ -1816,6 +1821,8 @@ CheckStatus check_static_if(AstIf* static_if) { return Check_Error; } + static_if->flags |= Ast_Flag_Static_If_Resolved; + b32 resolution = static_if_resolution(static_if); if (context.options->print_static_if_results) @@ -1908,7 +1915,7 @@ void check_entity(Entity* ent) { if (cs == Check_Success) ent->state = Entity_State_Code_Gen; if (cs == Check_Complete) ent->state = Entity_State_Finalized; - // else if (cs == Check_Yield) { - // ent->attempts++; - // } + else if (cs == Check_Yield_Macro) { + ent->macro_attempts++; + } } diff --git a/src/onyxentities.c b/src/onyxentities.c index 410d13ae..8020dfe5 100644 --- a/src/onyxentities.c +++ b/src/onyxentities.c @@ -4,7 +4,7 @@ static inline i32 entity_phase(Entity* e1) { if (e1->state <= Entity_State_Parse) return 1; - if (e1->state <= Entity_State_Comptime_Check_Types) return 2; + if (e1->state < Entity_State_Code_Gen) return 2; return 3; } @@ -13,17 +13,17 @@ static i32 entity_compare(Entity* e1, Entity* e2) { i32 phase1 = entity_phase(e1); i32 phase2 = entity_phase(e2); - if (phase1 != phase2 || phase1 != 2) { - if (e1->state != e2->state) - return (i32) e1->state - (i32) e2->state; - else if (e1->type != e2->type) - return (i32) e1->type - (i32) e2->type; - else - return (i32) (e1->micro_attempts - e2->micro_attempts); - - } else { + if (phase1 != phase2) + return phase1 - phase2; + else if (e1->macro_attempts != e2->macro_attempts) return (i32) e1->macro_attempts - (i32) e2->macro_attempts; - } + else if (e1->state != e2->state) + return (i32) e1->state - (i32) e2->state; + else if (e1->type != e2->type) + return (i32) e1->type - (i32) e2->type; + else + return (i32) (e1->micro_attempts - e2->micro_attempts); + } #define eh_parent(index) (((index) - 1) / 2) @@ -258,7 +258,7 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s case Ast_Kind_Use: { if (((AstUse *) node)->expr->kind == Ast_Kind_Package) { - ent.state = Entity_State_Comptime_Resolve_Symbols; + ent.state = Entity_State_Resolve_Symbols; ent.type = Entity_Type_Use_Package; } else { ent.type = Entity_Type_Use; @@ -288,7 +288,7 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s } case Ast_Kind_Static_If: { - ent.state = Entity_State_Comptime_Resolve_Symbols; + ent.state = Entity_State_Resolve_Symbols; ent.type = Entity_Type_Static_If; ent.static_if = (AstIf *) node; ENTITY_INSERT(ent); diff --git a/src/onyxsymres.c b/src/onyxsymres.c index fefc9295..eaed4488 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -499,6 +499,10 @@ static SymresStatus symres_if(AstIfWhile* ifnode) { } if (ifnode->kind == Ast_Kind_Static_If) { + if ((ifnode->flags & Ast_Flag_Static_If_Resolved) == 0) { + return Symres_Yield_Macro; + } + if (static_if_resolution(ifnode)) { if (ifnode->true_stmt != NULL) SYMRES(statement, (AstNode **) &ifnode->true_stmt, NULL); @@ -818,52 +822,56 @@ SymresStatus symres_function(AstFunction* func) { scope_enter(func->scope); - bh_arr_each(AstParam, param, func->params) { - symbol_introduce(curr_scope, param->local->token, (AstNode *) param->local); - - // CLEANUP: Currently, in order to 'use' parameters, the type must be completely - // resolved and built. This is excessive because all that should need to be known - // is the names of the members, since all that happens is implicit field accesses - // are placed in the scope. So instead, there should be a way to just query all the - // member names in the structure, without needing to know their type. This would be - // easy if it were not for 'use' statements in structs. It is made even more complicated - // by this situtation: - // - // Foo :: struct (T: type_expr) { - // use t : T; - // - // something_else := 5 + 6 * 8; - // } - // - // The 'use t : T' member requires completely knowing the type of T, to know which - // members should be brought in. At the moment, that requires completely building the - // type of Foo($T). - if (param->local->flags & Ast_Flag_Param_Use) { - if (param->local->type_node != NULL && param->local->type == NULL) { - param->local->type = type_build_from_ast(context.ast_alloc, param->local->type_node); - } - - if (type_is_struct(param->local->type)) { - Type* st; - if (param->local->type->kind == Type_Kind_Struct) { - st = param->local->type; - } else { - st = param->local->type->Pointer.elem; + if ((func->flags & Ast_Flag_Has_Been_Symres) == 0) { + func->flags |= Ast_Flag_Has_Been_Symres; + + bh_arr_each(AstParam, param, func->params) { + symbol_introduce(curr_scope, param->local->token, (AstNode *) param->local); + + // CLEANUP: Currently, in order to 'use' parameters, the type must be completely + // resolved and built. This is excessive because all that should need to be known + // is the names of the members, since all that happens is implicit field accesses + // are placed in the scope. So instead, there should be a way to just query all the + // member names in the structure, without needing to know their type. This would be + // easy if it were not for 'use' statements in structs. It is made even more complicated + // by this situtation: + // + // Foo :: struct (T: type_expr) { + // use t : T; + // + // something_else := 5 + 6 * 8; + // } + // + // The 'use t : T' member requires completely knowing the type of T, to know which + // members should be brought in. At the moment, that requires completely building the + // type of Foo($T). + if (param->local->flags & Ast_Flag_Param_Use) { + if (param->local->type_node != NULL && param->local->type == NULL) { + param->local->type = type_build_from_ast(context.ast_alloc, param->local->type_node); } - bh_table_each_start(StructMember, st->Struct.members); - AstFieldAccess* fa = make_field_access(context.ast_alloc, (AstTyped *) param->local, value.name); - symbol_raw_introduce(curr_scope, value.name, param->local->token->pos, (AstNode *) fa); - bh_table_each_end; + if (type_is_struct(param->local->type)) { + Type* st; + if (param->local->type->kind == Type_Kind_Struct) { + st = param->local->type; + } else { + st = param->local->type->Pointer.elem; + } - } else if (param->local->type != NULL) { - onyx_report_error(param->local->token->pos, "Can only 'use' structures or pointers to structures."); + bh_table_each_start(StructMember, st->Struct.members); + AstFieldAccess* fa = make_field_access(context.ast_alloc, (AstTyped *) param->local, value.name); + symbol_raw_introduce(curr_scope, value.name, param->local->token->pos, (AstNode *) fa); + bh_table_each_end; - } else { - // :ExplicitTyping - onyx_report_error(param->local->token->pos, "Cannot deduce type of parameter '%b'; Try adding it explicitly.", - param->local->token->text, - param->local->token->length); + } else if (param->local->type != NULL) { + onyx_report_error(param->local->token->pos, "Can only 'use' structures or pointers to structures."); + + } else { + // :ExplicitTyping + onyx_report_error(param->local->token->pos, "Cannot deduce type of parameter '%b'; Try adding it explicitly.", + param->local->token->text, + param->local->token->length); + } } } } @@ -1113,11 +1121,7 @@ void symres_entity(Entity* ent) { break; } - case Entity_Type_Static_If: { - ss = symres_static_if(ent->static_if); - next_state = Entity_State_Comptime_Check_Types; - break; - } + case Entity_Type_Static_If: ss = symres_static_if(ent->static_if); break; case Entity_Type_Foreign_Function_Header: case Entity_Type_Function_Header: ss = symres_function_header(ent->function); break; @@ -1151,9 +1155,13 @@ void symres_entity(Entity* ent) { default: break; } - if (ss == Symres_Success) ent->state = next_state; if (ss == Symres_Yield_Macro) ent->macro_attempts++; if (ss == Symres_Yield_Micro) ent->micro_attempts++; + if (ss == Symres_Success) { + ent->macro_attempts = 0; + ent->micro_attempts = 0; + ent->state = next_state; + } if (ent->scope) curr_scope = old_scope; } diff --git a/src/onyxutils.c b/src/onyxutils.c index 0c568207..321f4a4d 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -57,7 +57,8 @@ 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; + (*use_package)->state = Entity_State_Resolve_Symbols; + (*use_package)->macro_attempts = 0; entity_heap_insert_existing(&context.entities, *use_package); }