test(opt): #104/#105 beyaz-kutu IR testleri — folding ve DCE doğru katmanda

- ir.hpp: --optimized bayrağı ile OptimizationManager entegrasyonu
- ir_generator.cpp: hasDirectValue/directIntValue okunuyor (katlanmış literal IR'da 0 veriyordu)
- run_golden.cmake: OPTIMIZED=1 parametresi ile --optimized desteği
- CMakeLists.txt: *.ir_opt.expected → saqut ir --optimized otomatik keşif
- opt/folding.ir_opt.expected: 2+3*4 → LOAD_CONST 14 (katlama kanıtı)
- opt/dce.ir_opt.expected: LOAD_CONST 99 + CALLHOST print silindi (DCE kanıtı)
- Yanıltıcı run-output testleri (folding.expected, dce.expected) kaldırıldı
This commit is contained in:
abdussamedulutas 2026-06-18 22:47:31 +03:00
parent ac96ad810c
commit 913b42026c
8 changed files with 106 additions and 25 deletions

View File

@ -33,24 +33,42 @@ add_test(
COMMAND bash "${CMAKE_SOURCE_DIR}/tests/run.sh"
)
# Golden testleri tests/golden/**/*.sqt + .expected çiftlerini otomatik keşfet
# Golden testleri tests/golden/**/*.sqt dosyalarını otomatik keşfet.
# Her .sqt için iki olası expected dosyası kontrol edilir:
# BASE.expected saqut run (siyah-kutu çıktı testi)
# BASE.ir_opt.expected saqut ir --optimized (beyaz-kutu IR testi)
file(GLOB_RECURSE ALL_GOLDEN_SQT CONFIGURE_DEPENDS
"${CMAKE_SOURCE_DIR}/tests/golden/*.sqt"
)
foreach(SQT_FILE ${ALL_GOLDEN_SQT})
# Göreli yoldan test adı üret: fibonacci/fib.sqt golden_fibonacci_fib
file(RELATIVE_PATH REL "${CMAKE_SOURCE_DIR}/tests/golden" "${SQT_FILE}")
string(REPLACE ".sqt" "" BASE "${REL}")
string(REPLACE "/" "_" TNAME "${BASE}")
set(EXPECTED_FILE "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.expected")
if(EXISTS "${EXPECTED_FILE}")
# Siyah-kutu: saqut run çıktısı
set(RUN_EXPECTED "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.expected")
if(EXISTS "${RUN_EXPECTED}")
add_test(
NAME "golden_${TNAME}"
COMMAND ${CMAKE_COMMAND}
-DBINARY=${SAQUT_BINARY}
-DSOURCE=${SQT_FILE}
-DEXPECTED=${EXPECTED_FILE}
-DEXPECTED=${RUN_EXPECTED}
-P "${GOLDEN_SCRIPT}"
)
endif()
# Beyaz-kutu: saqut ir --optimized çıktısı
set(IR_OPT_EXPECTED "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.ir_opt.expected")
if(EXISTS "${IR_OPT_EXPECTED}")
add_test(
NAME "golden_${TNAME}_ir_opt"
COMMAND ${CMAKE_COMMAND}
-DBINARY=${SAQUT_BINARY}
-DSOURCE=${SQT_FILE}
-DEXPECTED=${IR_OPT_EXPECTED}
-DCOMMAND=ir
-DOPTIMIZED=1
-P "${GOLDEN_SCRIPT}"
)
endif()

View File

@ -1,17 +1,23 @@
# run_golden.cmake tek bir golden test çalıştırır ve çıktıyı karşılaştırır.
#
# Kullanım (CMake add_test içinden):
# cmake -DBINARY=<saqut yolu> -DSOURCE=<.sqt yolu> -DEXPECTED=<.expected yolu>
# [-DCOMMAND=run] -P run_golden.cmake
#
# COMMAND varsayılanı "run". IR testleri için COMMAND=ir geçilir.
# Parametreler (cmake -D ile geçilir):
# BINARY saqut binary yolu
# SOURCE test .sqt dosyası (tam yol)
# EXPECTED beklenen çıktı dosyası (tam yol)
# COMMAND "run" (varsayılan) veya "ir"
# OPTIMIZED 1 ise --optimized bayrağı eklenir
if(NOT DEFINED COMMAND)
set(COMMAND "run")
endif()
set(EXTRA_FLAGS "")
if(OPTIMIZED)
list(APPEND EXTRA_FLAGS "--optimized")
endif()
execute_process(
COMMAND "${BINARY}" "${COMMAND}" "file:${SOURCE}"
COMMAND "${BINARY}" "${COMMAND}" ${EXTRA_FLAGS} "file:${SOURCE}"
OUTPUT_VARIABLE ACTUAL
ERROR_VARIABLE STDERR_OUT
RESULT_VARIABLE EXIT_CODE

View File

@ -11,6 +11,8 @@
#include "semantic/structural_validator.hpp"
#include "diagnostic/diagnostic_engine.hpp"
#include "ir/ir_generator.hpp"
#include "core/config.hpp"
#include "opt/optimization_manager.hpp"
inline int cmdIr(const CliArgs& args) {
std::string filePath = inputFilePath(args);
@ -41,11 +43,23 @@ inline int cmdIr(const CliArgs& args) {
return 1;
}
IRGenerator irGenerator;
IRProgram program = irGenerator.generate(ast, symbolTable);
// --optimized: optimize edilmiş AST klonu üzerinden IR üret
ASTNode* activeAst = ast;
ASTNode* optimizedAst = nullptr;
if (args.optimized) {
CompilerConfig cfg;
DiagnosticEngine optDiag;
OptimizationManager mgr(cfg, optDiag);
optimizedAst = mgr.optimize(ast, &symbolTable);
activeAst = optimizedAst;
optDiag.printAll(std::cerr); // W002 vb. uyarılar stderr'e
}
IRGenerator irGenerator;
IRProgram program = irGenerator.generate(activeAst, symbolTable);
program.dump();
delete optimizedAst; // nullptr ise no-op
delete ast;
for (auto* t : tokens) delete t;
return 0;

View File

@ -271,13 +271,19 @@ int IRGenerator::generateExpression(ASTNode* node) {
switch (lit->literalType) {
case LiteralType::INTEGER: {
int value = 0;
if (lit->parserToken.token)
if (lit->hasDirectValue)
value = lit->directIntValue;
else if (lit->parserToken.token)
value = std::stoi(lit->parserToken.token->token);
emitLoadConst(slot, value);
break;
}
case LiteralType::BOOLEAN: {
int value = (lit->parserToken.token &&
int value = 0;
if (lit->hasDirectValue)
value = lit->directIntValue ? 1 : 0;
else
value = (lit->parserToken.token &&
lit->parserToken.token->token == "true") ? 1 : 0;
emitLoadConst(slot, value);
break;

View File

@ -1,3 +0,0 @@
10
0
0

View File

@ -0,0 +1,26 @@
IR DUMP
NAME=hesapla PARAMS=1 SLOTS=6
0 LOAD_CONST s1 = 0
1 GREATER s2 = s0 > s1
2 JIF_FALSE !s2 → 6
3 LOAD_CONST s3 = 2
4 MUL s4 = s0 * s3
5 RETURN s4
6 LOAD_CONST s5 = 0
7 RETURN s5
NAME=main PARAMS=0 SLOTS=7
0 LOAD_CONST s0 = 5
1 CALL s1 = hesapla(s0)
2 CALLHOST print(s1)
3 LOAD_CONST s2 = 0
4 CALL s3 = hesapla(s2)
5 CALLHOST print(s3)
6 LOAD_CONST s4 = -3
7 CALL s5 = hesapla(s4)
8 CALLHOST print(s5)
9 LOAD_CONST s6 = 0
10 RETURN s6
END

View File

@ -1,7 +0,0 @@
14
3
1
0
1
0
0

View File

@ -0,0 +1,21 @@
IR DUMP
NAME=main PARAMS=0 SLOTS=8
0 LOAD_CONST s0 = 14
1 CALLHOST print(s0)
2 LOAD_CONST s1 = 3
3 CALLHOST print(s1)
4 LOAD_CONST s2 = 1
5 CALLHOST print(s2)
6 LOAD_CONST s3 = 0
7 CALLHOST print(s3)
8 LOAD_CONST s4 = 1
9 CALLHOST print(s4)
10 LOAD_CONST s5 = 0
11 CALLHOST print(s5)
12 LOAD_CONST s6 = 1
13 CALLHOST print(s6)
14 LOAD_CONST s7 = 0
15 RETURN s7
END