From ab47e42954b91a019d5488fa783f303c64515455 Mon Sep 17 00:00:00 2001 From: abdussamedulutas Date: Thu, 18 Jun 2026 23:04:57 +0300 Subject: [PATCH] =?UTF-8?q?feat(run):=20--optimized=20bayra=C4=9F=C4=B1=20?= =?UTF-8?q?=E2=80=94=20optimize=20edilmi=C5=9F=20IR=20=C3=BCzerinden=20VM?= =?UTF-8?q?=20=C3=A7al=C4=B1=C5=9Ft=C4=B1rma?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - run.hpp: args.optimized ise OptimizationManager klonu üretip IR generator'a verir - ir.hpp + run.hpp: optDiag.printAll sadece gerçek mesaj varsa çağrılıyor (boş özet gürültüsü giderildi) - tests/golden/opt/run_opt.sqt: constant folding + DCE tetikleyen golden fixture - run_opt.expected: ham run doğruluk testi (test #9) - run_opt.run_opt.expected: optimize run doğruluk testi (test #10) → "optimizasyon oldu" değil "optimize IR doğru sonuç verdi" regresyon kalkanı - CMakeLists.txt: *.run_opt.expected → saqut run --optimized otomatik keşif 11/11 ctest geçti --- CMakeLists.txt | 15 +++++++++ src/cli/commands/ir.hpp | 3 +- src/cli/commands/run.hpp | 38 +++++++++++++++++------ tests/golden/opt/run_opt.expected | 4 +++ tests/golden/opt/run_opt.run_opt.expected | 4 +++ tests/golden/opt/run_opt.sqt | 31 ++++++++++++++++++ 6 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 tests/golden/opt/run_opt.expected create mode 100644 tests/golden/opt/run_opt.run_opt.expected create mode 100644 tests/golden/opt/run_opt.sqt diff --git a/CMakeLists.txt b/CMakeLists.txt index 0dd02c6..8b48e77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,4 +72,19 @@ foreach(SQT_FILE ${ALL_GOLDEN_SQT}) -P "${GOLDEN_SCRIPT}" ) endif() + + # Doğruluk kalkanı: saqut run --optimized çıktısı == beklenen golden değer + # "Optimizasyon oldu" değil, "optimize IR doğru sonuç verdi" testleri. + set(RUN_OPT_EXPECTED "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.run_opt.expected") + if(EXISTS "${RUN_OPT_EXPECTED}") + add_test( + NAME "golden_${TNAME}_run_opt" + COMMAND ${CMAKE_COMMAND} + -DBINARY=${SAQUT_BINARY} + -DSOURCE=${SQT_FILE} + -DEXPECTED=${RUN_OPT_EXPECTED} + -DOPTIMIZED=1 + -P "${GOLDEN_SCRIPT}" + ) + endif() endforeach() diff --git a/src/cli/commands/ir.hpp b/src/cli/commands/ir.hpp index 1e05614..31b44c4 100644 --- a/src/cli/commands/ir.hpp +++ b/src/cli/commands/ir.hpp @@ -52,7 +52,8 @@ inline int cmdIr(const CliArgs& args) { OptimizationManager mgr(cfg, optDiag); optimizedAst = mgr.optimize(ast, &symbolTable); activeAst = optimizedAst; - optDiag.printAll(std::cerr); // W002 vb. uyarılar stderr'e + if (optDiag.errorCount() + optDiag.warningCount() > 0) + optDiag.printAll(std::cerr); // W002 vb. uyarılar stderr'e } IRGenerator irGenerator; diff --git a/src/cli/commands/run.hpp b/src/cli/commands/run.hpp index 565a729..3d6a13a 100644 --- a/src/cli/commands/run.hpp +++ b/src/cli/commands/run.hpp @@ -2,12 +2,11 @@ // saQut CLI — run komutu // // Tam derleme + çalıştırma pipeline'ı: -// tokenize → parse → sembol topla → IR üret → VM çalıştır +// tokenize → parse → sembol topla → [opsiyonel: optimize] → IR üret → VM çalıştır // -// Başarı kriteri: -// build/saqut run file:examples/fibonacci.sqt -// → 55 -// → 55 +// --optimized bayrağı: orijinal AST klonlanır, constant folding + DCE uygulanır, +// optimize edilmiş klon IR generator'a verilir. Orijinal AST dokunulmadan kalır. +// Aynı pattern ir.hpp'de de kullanılıyor — paralel değişikliklerde ikisine bak. // ============================================================================ #ifndef SAQUT_CLI_RUN @@ -22,6 +21,8 @@ #include "semantic/type_checker.hpp" #include "semantic/structural_validator.hpp" #include "diagnostic/diagnostic_engine.hpp" +#include "core/config.hpp" +#include "opt/optimization_manager.hpp" #include "ir/ir_generator.hpp" #include "vm/interpreter.hpp" @@ -43,7 +44,7 @@ inline int cmdRun(const CliArgs& args) { return 1; } - // ── Aşama 3: Sembol toplama ─────────────────────────────────────────── + // ── Aşama 3: Sembol toplama + semantik analiz ───────────────────────── // Identifier'ların resolvedSymbol'ü doldurulur — IR generator buna ihtiyaç duyar. SymbolTable symbolTable; DiagnosticEngine diag; @@ -59,11 +60,27 @@ inline int cmdRun(const CliArgs& args) { return 1; } - // ── Aşama 4: IR üretimi ─────────────────────────────────────────────── - IRGenerator irGenerator; - IRProgram program = irGenerator.generate(ast, symbolTable); + // ── Aşama 4 (opsiyonel): Optimizasyon ──────────────────────────────── + // --optimized bayrağı verilmişse: orijinal AST'yi kopyala, klon üstünde + // constant folding + DCE uygula. IR generator klonu kullanır; orijinal + // bu scope'ta silinir. Bayrak yoksa sıfır maliyet — klonlama olmaz. + ASTNode* activeAst = ast; + ASTNode* optimizedAst = nullptr; + if (args.optimized) { + CompilerConfig cfg; + DiagnosticEngine optDiag; + OptimizationManager mgr(cfg, optDiag); + optimizedAst = mgr.optimize(ast, &symbolTable); + activeAst = optimizedAst; + if (optDiag.errorCount() + optDiag.warningCount() > 0) + optDiag.printAll(std::cerr); // W002 (derleme zamanı sıfıra bölme) vb. + } - // ── Aşama 5: VM çalıştırma ──────────────────────────────────────────── + // ── Aşama 5: IR üretimi ─────────────────────────────────────────────── + IRGenerator irGenerator; + IRProgram program = irGenerator.generate(activeAst, symbolTable); + + // ── Aşama 6: VM çalıştırma ──────────────────────────────────────────── int exitCode = 0; try { Interpreter vm(program); @@ -73,6 +90,7 @@ inline int cmdRun(const CliArgs& args) { exitCode = 1; } + delete optimizedAst; // nullptr ise no-op; orijinal ast her durumda aşağıda silinir delete ast; for (auto* t : tokens) delete t; return exitCode; diff --git a/tests/golden/opt/run_opt.expected b/tests/golden/opt/run_opt.expected new file mode 100644 index 0000000..ed4da39 --- /dev/null +++ b/tests/golden/opt/run_opt.expected @@ -0,0 +1,4 @@ +14 +1 +0 +25 diff --git a/tests/golden/opt/run_opt.run_opt.expected b/tests/golden/opt/run_opt.run_opt.expected new file mode 100644 index 0000000..ed4da39 --- /dev/null +++ b/tests/golden/opt/run_opt.run_opt.expected @@ -0,0 +1,4 @@ +14 +1 +0 +25 diff --git a/tests/golden/opt/run_opt.sqt b/tests/golden/opt/run_opt.sqt new file mode 100644 index 0000000..e97e6e3 --- /dev/null +++ b/tests/golden/opt/run_opt.sqt @@ -0,0 +1,31 @@ +// Optimize edilmiş çalıştırmanın doğruluğunu kanıtlayan golden test. +// +// Tetiklenen optimizasyonlar: +// - Constant folding: 100 - 6*15 + 4, 3*3 + 4*4 derleme zamanında hesaplanır +// - DCE: return sonrası print(999) ve print(888) silinir +// - Folding zincirleme: iç fonksiyon çağrısı olmaksızın tüm sabit ifadeler katlanır +// +// saqut run ve saqut run --optimized AYNI çıktıyı vermeli. +// Eğer optimizasyon bir değeri yanlış katlarsa veya canlı kodu silerse bu test kırılır. + +int compute() { + int result = 100 - 6 * 15 + 4; + return result; + print(999); +} + +int classify(int n) { + if (n > 0) { + return 1; + print(888); + } + return 0; +} + +int main() { + print(compute()); + print(classify(5)); + print(classify(-3)); + print(3 * 3 + 4 * 4); + return 0; +}