From: Brendan Hansen Date: Sat, 6 Feb 2021 21:51:45 +0000 (-0600) Subject: added basic cycle detection and breaking X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=4469c5a3d489b0005660cdc7f20d55333da5de03;p=onyx.git added basic cycle detection and breaking --- diff --git a/bin/onyx b/bin/onyx index 10cc0352..afcd5eb8 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index fa5c63f5..29c2ef97 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -1017,6 +1017,8 @@ struct Context { // NOTE: This is defined in onyxwasm.h struct OnyxWasmModule* wasm_module; + + b32 cycle_detected : 1; }; extern Context context; diff --git a/onyx.exe b/onyx.exe index 0aeaafc3..9b264008 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyx.c b/src/onyx.c index 959e8626..6019e3b5 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -136,6 +136,7 @@ static AstInclude* create_load(bh_allocator alloc, char* filename) { static void context_init(CompileOptions* opts) { context.options = opts; + context.cycle_detected = 0; context.global_scope = scope_create(global_heap_allocator, NULL, (OnyxFilePos) { 0 }); bh_table_init(global_heap_allocator, context.packages, 16); @@ -271,8 +272,6 @@ static void process_load_entity(Entity* ent) { } static b32 process_entity(Entity* ent) { - i32 changed = 1; - if (context.options->verbose_output == 3) { if (ent->expr && ent->expr->token) printf("%s | %s (%d) | %s:%i:%i\n", @@ -294,10 +293,12 @@ static b32 process_entity(Entity* ent) { // already been initialized. static b32 builtins_initialized = 0; - switch (ent->state) { + EntityState before_state = ent->state; + switch (before_state) { case Entity_State_Parse_Builtin: process_load_entity(ent); ent->state = Entity_State_Finalized; + break; case Entity_State_Introduce_Symbols: // Currently, introducing symbols is handled in the symbol resolution @@ -322,12 +323,9 @@ static b32 process_entity(Entity* ent) { case Entity_State_Check_Types: check_entity(ent); break; case Entity_State_Code_Gen: emit_entity(ent); break; - - default: - changed = 0; } - return changed; + return ent->state != before_state; } // Just having fun with some visual output - brendanfh 2020/12/14 @@ -373,9 +371,22 @@ static i32 onyx_compile() { b32 changed = process_entity(ent); + // NOTE: VERY VERY dumb cycle breaking. Basically, remember the first entity that did + // not change (i.e. did not make any progress). Then everytime an entity doesn't change, + // check if it is the same entity. If it is, it means all other entities that were processed + // between the two occurences didn't make any progress either, and there must be a cycle. + // - brendanfh 2021/02/06 + static Entity* first_no_change = NULL; + if (!changed) { + if (!first_no_change) first_no_change = ent; + else if (first_no_change == ent) context.cycle_detected = 1; + } else { + first_no_change = NULL; + } + if (onyx_has_errors()) return ONYX_COMPILER_PROGRESS_ERROR; - if (changed && ent->state != Entity_State_Finalized) + if (ent->state != Entity_State_Finalized) entity_heap_insert_existing(&context.entities, ent); } diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 933f112d..d4f9a428 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -1023,7 +1023,8 @@ void symres_entity(Entity* ent) { } report_unresolved_symbols = (context.entities.type_count[Entity_Type_Static_If] == 0 && - context.entities.type_count[Entity_Type_Use_Package] == 0); + context.entities.type_count[Entity_Type_Use_Package] == 0) + || context.cycle_detected; SymresStatus ss = Symres_Success; EntityState next_state = Entity_State_Check_Types;