feat: ADR-024/025/021 — string concat, try/catch/throw, nullable akış-analizi #115
|
|
@ -72,4 +72,19 @@ foreach(SQT_FILE ${ALL_GOLDEN_SQT})
|
||||||
-P "${GOLDEN_SCRIPT}"
|
-P "${GOLDEN_SCRIPT}"
|
||||||
)
|
)
|
||||||
endif()
|
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()
|
endforeach()
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,8 @@ inline int cmdIr(const CliArgs& args) {
|
||||||
OptimizationManager mgr(cfg, optDiag);
|
OptimizationManager mgr(cfg, optDiag);
|
||||||
optimizedAst = mgr.optimize(ast, &symbolTable);
|
optimizedAst = mgr.optimize(ast, &symbolTable);
|
||||||
activeAst = optimizedAst;
|
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;
|
IRGenerator irGenerator;
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,11 @@
|
||||||
// saQut CLI — run komutu
|
// saQut CLI — run komutu
|
||||||
//
|
//
|
||||||
// Tam derleme + çalıştırma pipeline'ı:
|
// 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:
|
// --optimized bayrağı: orijinal AST klonlanır, constant folding + DCE uygulanır,
|
||||||
// build/saqut run file:examples/fibonacci.sqt
|
// optimize edilmiş klon IR generator'a verilir. Orijinal AST dokunulmadan kalır.
|
||||||
// → 55
|
// Aynı pattern ir.hpp'de de kullanılıyor — paralel değişikliklerde ikisine bak.
|
||||||
// → 55
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
#ifndef SAQUT_CLI_RUN
|
#ifndef SAQUT_CLI_RUN
|
||||||
|
|
@ -22,6 +21,8 @@
|
||||||
#include "semantic/type_checker.hpp"
|
#include "semantic/type_checker.hpp"
|
||||||
#include "semantic/structural_validator.hpp"
|
#include "semantic/structural_validator.hpp"
|
||||||
#include "diagnostic/diagnostic_engine.hpp"
|
#include "diagnostic/diagnostic_engine.hpp"
|
||||||
|
#include "core/config.hpp"
|
||||||
|
#include "opt/optimization_manager.hpp"
|
||||||
#include "ir/ir_generator.hpp"
|
#include "ir/ir_generator.hpp"
|
||||||
#include "vm/interpreter.hpp"
|
#include "vm/interpreter.hpp"
|
||||||
|
|
||||||
|
|
@ -43,7 +44,7 @@ inline int cmdRun(const CliArgs& args) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Aşama 3: Sembol toplama ───────────────────────────────────────────
|
// ── Aşama 3: Sembol toplama + semantik analiz ─────────────────────────
|
||||||
// Identifier'ların resolvedSymbol'ü doldurulur — IR generator buna ihtiyaç duyar.
|
// Identifier'ların resolvedSymbol'ü doldurulur — IR generator buna ihtiyaç duyar.
|
||||||
SymbolTable symbolTable;
|
SymbolTable symbolTable;
|
||||||
DiagnosticEngine diag;
|
DiagnosticEngine diag;
|
||||||
|
|
@ -59,11 +60,27 @@ inline int cmdRun(const CliArgs& args) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Aşama 4: IR üretimi ───────────────────────────────────────────────
|
// ── Aşama 4 (opsiyonel): Optimizasyon ────────────────────────────────
|
||||||
IRGenerator irGenerator;
|
// --optimized bayrağı verilmişse: orijinal AST'yi kopyala, klon üstünde
|
||||||
IRProgram program = irGenerator.generate(ast, symbolTable);
|
// 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;
|
int exitCode = 0;
|
||||||
try {
|
try {
|
||||||
Interpreter vm(program);
|
Interpreter vm(program);
|
||||||
|
|
@ -73,6 +90,7 @@ inline int cmdRun(const CliArgs& args) {
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete optimizedAst; // nullptr ise no-op; orijinal ast her durumda aşağıda silinir
|
||||||
delete ast;
|
delete ast;
|
||||||
for (auto* t : tokens) delete t;
|
for (auto* t : tokens) delete t;
|
||||||
return exitCode;
|
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