feat(run): --optimized bayrağı — optimize edilmiş IR üzerinden VM çalıştırma
- 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
This commit is contained in:
parent
913b42026c
commit
ab47e42954
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
14
|
||||
1
|
||||
0
|
||||
25
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
14
|
||||
1
|
||||
0
|
||||
25
|
||||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue