diff --git a/build.bat b/build.bat index d7b0ada..eb6f823 100644 --- a/build.bat +++ b/build.bat @@ -8,4 +8,4 @@ if not exist build\bld.exe ( ) rem ubuntu run ./build.sh -build\bld.exe --tests text_editor +build\bld.exe diff --git a/examples/add_instrumentation/build.cpp b/examples/add_instrumentation/build.cpp index 22a0bc3..598121d 100644 --- a/examples/add_instrumentation/build.cpp +++ b/examples/add_instrumentation/build.cpp @@ -37,12 +37,12 @@ bool add_instrumentation() { } LC_String code = LC_GenerateUnityBuild(); - LC_LangEnd(lang); S8_String path = "examples/add_instrumentation/add_instrumentation.c"; OS_MakeDir("examples"); OS_MakeDir("examples/add_instrumentation"); OS_WriteFile(path, code); + LC_LangEnd(lang); if (!UseCL) return true; S8_String cmd = Fmt("cl %.*s -Zi -std:c11 -nologo -FC -Fd:examples/add_instrumentation/a.pdb -Fe:examples/add_instrumentation/add_instrumentation.exe %.*s", S8_Expand(path), S8_Expand(RaylibLIB)); diff --git a/examples/add_source_location_macro/build.cpp b/examples/add_source_location_macro/build.cpp index 00bf9da..34e5cf1 100644 --- a/examples/add_source_location_macro/build.cpp +++ b/examples/add_source_location_macro/build.cpp @@ -34,10 +34,9 @@ bool add_source_location_macro() { } LC_String code = LC_GenerateUnityBuild(); - LC_LangEnd(lang); - OS_MakeDir("examples/add_source_location_macro"); OS_WriteFile("examples/add_source_location_macro/add_source_location_macro.c", code); + LC_LangEnd(lang); return true; } \ No newline at end of file diff --git a/examples/hello_world/build.cpp b/examples/hello_world/build.cpp index a67b7ce..800ba3f 100644 --- a/examples/hello_world/build.cpp +++ b/examples/hello_world/build.cpp @@ -16,10 +16,10 @@ bool hello_world() { OS_MakeDir("examples/hello_world"); LC_ParseAndResolve(name); LC_String code = LC_GenerateUnityBuild(); - LC_LangEnd(lang); S8_String path = "examples/hello_world/hello_world.c"; OS_WriteFile(path, code); + LC_LangEnd(lang); if (UseCL) { S8_String cmd = Fmt("cl %.*s -nologo -FC -Fd:examples/hello_world/hello_world.pdb -Fe:examples/hello_world/hello_world.exe", S8_Expand(path)); if (Run(cmd) != 0) return false; diff --git a/examples/text_editor/build.cpp b/examples/text_editor/build.cpp index 1c1c068..ac82c79 100644 --- a/examples/text_editor/build.cpp +++ b/examples/text_editor/build.cpp @@ -6,9 +6,9 @@ bool text_editor() { defer { LC_LangEnd(lang); }; LC_RegisterPackageDir("../pkgs"); - LC_RegisterPackageDir("../examples"); + LC_RegisterPackageDir("../examples/text_editor"); - LC_Intern name = LC_ILit("text_editor"); + LC_Intern name = LC_ILit("entry_point"); LC_ParseAndResolve(name); if (L->errors) return false; diff --git a/examples/text_editor/basic.lc b/examples/text_editor/core/basic.lc similarity index 94% rename from examples/text_editor/basic.lc rename to examples/text_editor/core/basic.lc index 6059bfe..c74081c 100644 --- a/examples/text_editor/basic.lc +++ b/examples/text_editor/core/basic.lc @@ -1,3 +1,6 @@ +import "raylib"; +import "std_types"; + ClampInt :: proc(val: int, min: int, max: int): int { result := val; if (val < min) result = min; diff --git a/examples/text_editor/rect2p.lc b/examples/text_editor/core/rect2p.lc similarity index 100% rename from examples/text_editor/rect2p.lc rename to examples/text_editor/core/rect2p.lc diff --git a/examples/text_editor/unicode.lc b/examples/text_editor/core/unicode.lc similarity index 100% rename from examples/text_editor/unicode.lc rename to examples/text_editor/core/unicode.lc diff --git a/examples/text_editor/main.lc b/examples/text_editor/entry_point/main.lc similarity index 95% rename from examples/text_editor/main.lc rename to examples/text_editor/entry_point/main.lc index 6691b1e..3c2ac20 100644 --- a/examples/text_editor/main.lc +++ b/examples/text_editor/entry_point/main.lc @@ -12,6 +12,9 @@ import "raylib"; import "std_types"; import "libc"; +import "core"; +import TE "text_editor"; + InvalidCodepath :: proc() { assert(:*char("invalid codepath") == :*char("")); } @@ -81,12 +84,13 @@ main :: proc(): int { ClearBackground(RAYWHITE); if sandbox_chosen == SANDBOX_TEXT_EDITOR { - UpdateTextEditor(screen_rect, font, font_size, font_spacing); + TE.UpdateTextEditor(screen_rect, font, font_size, font_spacing); } else if sandbox_chosen == SANDBOX_PROTOTYPE { UpdatePrototype(screen_rect); } - DrawRect(top_bar_original, LIGHTGRAY); + + TE.DrawRect(top_bar_original, LIGHTGRAY); DrawRectangleRoundedLines(Rect2PToRectangle(button1), 0.3, 12, 2, BLACK); if button1_hover DrawRectangleRounded(Rect2PToRectangle(button1), 0.3, 12, WHITE); @@ -101,4 +105,5 @@ main :: proc(): int { } CloseWindow(); return 0; -} \ No newline at end of file +} + diff --git a/examples/text_editor/prototype.lc b/examples/text_editor/entry_point/prototype.lc similarity index 100% rename from examples/text_editor/prototype.lc rename to examples/text_editor/entry_point/prototype.lc diff --git a/examples/text_editor/buffer.lc b/examples/text_editor/text_editor/buffer.lc similarity index 100% rename from examples/text_editor/buffer.lc rename to examples/text_editor/text_editor/buffer.lc diff --git a/examples/text_editor/buffer_iter.lc b/examples/text_editor/text_editor/buffer_iter.lc similarity index 100% rename from examples/text_editor/buffer_iter.lc rename to examples/text_editor/text_editor/buffer_iter.lc diff --git a/examples/text_editor/text_editor.lc b/examples/text_editor/text_editor/text_editor.lc similarity index 99% rename from examples/text_editor/text_editor.lc rename to examples/text_editor/text_editor/text_editor.lc index 0d6dff8..4118a84 100644 --- a/examples/text_editor/text_editor.lc +++ b/examples/text_editor/text_editor/text_editor.lc @@ -1,3 +1,9 @@ +import "std_types"; +import "raylib"; +import "libc"; + +import "core"; + TeInited := false; TeFontSize: float = 14; TeFontSpacing: float = 1; @@ -91,7 +97,6 @@ UpdateAndDrawWindow :: proc(w: *Window, font: Font, font_size: float) { } } - if w == FocusedWindow { if IsKeyPressed(KEY_LEFT) || IsKeyPressedRepeat(KEY_LEFT) { if IsKeyDown(KEY_LEFT_SHIFT) { diff --git a/examples/text_editor/visual_pos.lc b/examples/text_editor/text_editor/visual_pos.lc similarity index 100% rename from examples/text_editor/visual_pos.lc rename to examples/text_editor/text_editor/visual_pos.lc diff --git a/lib_compiler.h b/lib_compiler.h index 7f80074..b3ff6d6 100644 --- a/lib_compiler.h +++ b/lib_compiler.h @@ -1045,9 +1045,9 @@ LC_FUNCTION void LC_ResolveProcBodiesPass(void); // The Parse an LC_FUNCTION void LC_FindUnusedLocalsAndRemoveUnusedGlobalDeclsPass(void); // Extended pass that you can execute once you have resolved all packages // These three functions are used to implement LC_FindUnusedLocalsAndRemoveUnusedGlobalDeclsPass -LC_FUNCTION LC_Map LC_CountDeclRefs(LC_Arena *arena); -LC_FUNCTION void LC_RemoveUnreferencedGlobalDeclsPass(LC_Map *map_of_visits); -LC_FUNCTION void LC_ErrorOnUnreferencedLocalsPass(LC_Map *map_of_visits); +LC_FUNCTION void LC_CountDeclRefs(LC_Arena *arena, LC_Map *map, LC_AST *ast); +LC_FUNCTION LC_Decl *LC_RemoveUnreferencedGlobalDeclsPass(LC_Map *map_of_visits); +LC_FUNCTION void LC_ErrorOnUnreferencedLocalsPass(LC_Map *map_of_visits); // Notes LC_FUNCTION void LC_DeclareNote(LC_Intern intern); @@ -9891,20 +9891,16 @@ LC_FUNCTION void WalkAndCountDeclRefs(LC_ASTWalker *ctx, LC_AST *n) { } } -LC_FUNCTION LC_Map LC_CountDeclRefs(LC_Arena *arena) { - LC_Map map = {arena}; - LC_MapReserve(&map, 512); - - LC_AST *package = LC_GetPackageByName(L->first_package); - LC_ASTWalker walker = LC_GetDefaultWalker(arena, WalkAndCountDeclRefs); - walker.user_data = (void *)↦ - walker.visit_notes = true; - LC_WalkAST(&walker, package); - - return map; +LC_FUNCTION void LC_CountDeclRefs(LC_Arena *arena, LC_Map *map, LC_AST *ast) { + LC_ASTWalker walker = LC_GetDefaultWalker(arena, WalkAndCountDeclRefs); + walker.user_data = (void *)map; + walker.visit_notes = true; + LC_WalkAST(&walker, ast); } -LC_FUNCTION void LC_RemoveUnreferencedGlobalDeclsPass(LC_Map *map_of_visits) { +LC_FUNCTION LC_Decl *LC_RemoveUnreferencedGlobalDeclsPass(LC_Map *map_of_visits) { + LC_Decl *first_removed_decl = NULL; + LC_Decl *last_removed_decl = NULL; for (LC_ASTRef *it = L->ordered_packages.first; it; it = it->next) { for (LC_Decl *decl = it->ast->apackage.ext->first_ordered; decl;) { intptr_t ref_count = (intptr_t)LC_MapGetP(map_of_visits, decl); @@ -9913,9 +9909,11 @@ LC_FUNCTION void LC_RemoveUnreferencedGlobalDeclsPass(LC_Map *map_of_visits) { decl = decl->next; if (ref_count == 0 && remove->foreign_name != LC_ILit("main")) { LC_DLLRemove(it->ast->apackage.ext->first_ordered, it->ast->apackage.ext->last_ordered, remove); + LC_DLLAdd(first_removed_decl, last_removed_decl, remove); } } } + return first_removed_decl; } LC_FUNCTION void LC_ErrorOnUnreferencedLocalsPass(LC_Map *map_of_visits) { @@ -9939,9 +9937,16 @@ LC_FUNCTION void LC_FindUnusedLocalsAndRemoveUnusedGlobalDeclsPass(void) { if (L->errors) return; LC_TempArena check = LC_BeginTemp(L->arena); - LC_Map map = LC_CountDeclRefs(check.arena); + LC_AST *package = LC_GetPackageByName(L->first_package); + LC_Map map = {check.arena}; + LC_MapReserve(&map, 512); + + LC_CountDeclRefs(check.arena, &map, package); + LC_Decl *first_removed_decl = LC_RemoveUnreferencedGlobalDeclsPass(&map); + for (LC_Decl *it = first_removed_decl; it; it = it->next) { + LC_CountDeclRefs(check.arena, &map, it->ast); + } LC_ErrorOnUnreferencedLocalsPass(&map); - LC_RemoveUnreferencedGlobalDeclsPass(&map); LC_EndTemp(check); } diff --git a/src/compiler/extended_passes.c b/src/compiler/extended_passes.c index e7466cd..a710f51 100644 --- a/src/compiler/extended_passes.c +++ b/src/compiler/extended_passes.c @@ -16,20 +16,16 @@ LC_FUNCTION void WalkAndCountDeclRefs(LC_ASTWalker *ctx, LC_AST *n) { } } -LC_FUNCTION LC_Map LC_CountDeclRefs(LC_Arena *arena) { - LC_Map map = {arena}; - LC_MapReserve(&map, 512); - - LC_AST *package = LC_GetPackageByName(L->first_package); - LC_ASTWalker walker = LC_GetDefaultWalker(arena, WalkAndCountDeclRefs); - walker.user_data = (void *)↦ - walker.visit_notes = true; - LC_WalkAST(&walker, package); - - return map; +LC_FUNCTION void LC_CountDeclRefs(LC_Arena *arena, LC_Map *map, LC_AST *ast) { + LC_ASTWalker walker = LC_GetDefaultWalker(arena, WalkAndCountDeclRefs); + walker.user_data = (void *)map; + walker.visit_notes = true; + LC_WalkAST(&walker, ast); } -LC_FUNCTION void LC_RemoveUnreferencedGlobalDeclsPass(LC_Map *map_of_visits) { +LC_FUNCTION LC_Decl *LC_RemoveUnreferencedGlobalDeclsPass(LC_Map *map_of_visits) { + LC_Decl *first_removed_decl = NULL; + LC_Decl *last_removed_decl = NULL; for (LC_ASTRef *it = L->ordered_packages.first; it; it = it->next) { for (LC_Decl *decl = it->ast->apackage.ext->first_ordered; decl;) { intptr_t ref_count = (intptr_t)LC_MapGetP(map_of_visits, decl); @@ -38,9 +34,11 @@ LC_FUNCTION void LC_RemoveUnreferencedGlobalDeclsPass(LC_Map *map_of_visits) { decl = decl->next; if (ref_count == 0 && remove->foreign_name != LC_ILit("main")) { LC_DLLRemove(it->ast->apackage.ext->first_ordered, it->ast->apackage.ext->last_ordered, remove); + LC_DLLAdd(first_removed_decl, last_removed_decl, remove); } } } + return first_removed_decl; } LC_FUNCTION void LC_ErrorOnUnreferencedLocalsPass(LC_Map *map_of_visits) { @@ -64,9 +62,16 @@ LC_FUNCTION void LC_FindUnusedLocalsAndRemoveUnusedGlobalDeclsPass(void) { if (L->errors) return; LC_TempArena check = LC_BeginTemp(L->arena); - LC_Map map = LC_CountDeclRefs(check.arena); + LC_AST *package = LC_GetPackageByName(L->first_package); + LC_Map map = {check.arena}; + LC_MapReserve(&map, 512); + + LC_CountDeclRefs(check.arena, &map, package); + LC_Decl *first_removed_decl = LC_RemoveUnreferencedGlobalDeclsPass(&map); + for (LC_Decl *it = first_removed_decl; it; it = it->next) { + LC_CountDeclRefs(check.arena, &map, it->ast); + } LC_ErrorOnUnreferencedLocalsPass(&map); - LC_RemoveUnreferencedGlobalDeclsPass(&map); LC_EndTemp(check); } \ No newline at end of file diff --git a/src/compiler/lib_compiler.h b/src/compiler/lib_compiler.h index aad69d0..7f6e036 100644 --- a/src/compiler/lib_compiler.h +++ b/src/compiler/lib_compiler.h @@ -1001,9 +1001,9 @@ LC_FUNCTION void LC_ResolveProcBodiesPass(void); // The Parse an LC_FUNCTION void LC_FindUnusedLocalsAndRemoveUnusedGlobalDeclsPass(void); // Extended pass that you can execute once you have resolved all packages // These three functions are used to implement LC_FindUnusedLocalsAndRemoveUnusedGlobalDeclsPass -LC_FUNCTION LC_Map LC_CountDeclRefs(LC_Arena *arena); -LC_FUNCTION void LC_RemoveUnreferencedGlobalDeclsPass(LC_Map *map_of_visits); -LC_FUNCTION void LC_ErrorOnUnreferencedLocalsPass(LC_Map *map_of_visits); +LC_FUNCTION void LC_CountDeclRefs(LC_Arena *arena, LC_Map *map, LC_AST *ast); +LC_FUNCTION LC_Decl *LC_RemoveUnreferencedGlobalDeclsPass(LC_Map *map_of_visits); +LC_FUNCTION void LC_ErrorOnUnreferencedLocalsPass(LC_Map *map_of_visits); // Notes LC_FUNCTION void LC_DeclareNote(LC_Intern intern); diff --git a/tests/compilation/test_compile_packed.c b/tests/compilation/test_compile_packed.c index 86b8f30..bbcce18 100644 --- a/tests/compilation/test_compile_packed.c +++ b/tests/compilation/test_compile_packed.c @@ -31,10 +31,10 @@ int main(int argc, char **argv) { LC_RegisterPackageDir(it->string.str); } - LC_Intern name = LC_InternStrLen(package.str, (int)package.len); - LC_ASTRefList packages = LC_ParseAndResolve(name); + LC_Intern name = LC_InternStrLen(package.str, (int)package.len); + LC_ParseAndResolve(name); if (lang->errors) return 1; - LC_String code = LC_GenerateUnityBuild(packages); + LC_String code = LC_GenerateUnityBuild(); (void)code; } \ No newline at end of file diff --git a/tests/compilation/test_compile_packed_cpp.c b/tests/compilation/test_compile_packed_cpp.c index 86b8f30..bbcce18 100644 --- a/tests/compilation/test_compile_packed_cpp.c +++ b/tests/compilation/test_compile_packed_cpp.c @@ -31,10 +31,10 @@ int main(int argc, char **argv) { LC_RegisterPackageDir(it->string.str); } - LC_Intern name = LC_InternStrLen(package.str, (int)package.len); - LC_ASTRefList packages = LC_ParseAndResolve(name); + LC_Intern name = LC_InternStrLen(package.str, (int)package.len); + LC_ParseAndResolve(name); if (lang->errors) return 1; - LC_String code = LC_GenerateUnityBuild(packages); + LC_String code = LC_GenerateUnityBuild(); (void)code; } \ No newline at end of file diff --git a/tests/test_unused_locals_when_across_modules_and_not_called/main/test_unused.lc b/tests/test_unused_locals_when_across_modules_and_not_called/main/test_unused.lc new file mode 100644 index 0000000..404b43f --- /dev/null +++ b/tests/test_unused_locals_when_across_modules_and_not_called/main/test_unused.lc @@ -0,0 +1,5 @@ +import b "second"; + +main :: proc(): int { + return 0; +} \ No newline at end of file diff --git a/tests/test_unused_locals_when_across_modules_and_not_called/second/second.lc b/tests/test_unused_locals_when_across_modules_and_not_called/second/second.lc new file mode 100644 index 0000000..5c375a7 --- /dev/null +++ b/tests/test_unused_locals_when_across_modules_and_not_called/second/second.lc @@ -0,0 +1,5 @@ + +other_thing :: proc(): int { + a := 0; + return a; +} \ No newline at end of file diff --git a/tools/lcompile.c b/tools/lcompile.c index 055d734..ce395f8 100644 --- a/tools/lcompile.c +++ b/tools/lcompile.c @@ -41,10 +41,10 @@ int main(int argc, char **argv) { LC_RegisterPackageDir(path_to_package.str); S8_For(it, dirs) { LC_RegisterPackageDir(it->string.str); } - LC_Intern name = LC_InternStrLen(package.str, (int)package.len); - LC_ASTRefList packages = LC_ParseAndResolve(name); + LC_Intern name = LC_InternStrLen(package.str, (int)package.len); + LC_ParseAndResolve(name); if (lang->errors) return 1; - S8_String code = LC_GenerateUnityBuild(packages); + S8_String code = LC_GenerateUnityBuild(); OS_WriteFile(S8_Lit("output.c"), code); } \ No newline at end of file