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" 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 file(GLOB_RECURSE ALL_GOLDEN_SQT CONFIGURE_DEPENDS
"${CMAKE_SOURCE_DIR}/tests/golden/*.sqt" "${CMAKE_SOURCE_DIR}/tests/golden/*.sqt"
) )
foreach(SQT_FILE ${ALL_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}") file(RELATIVE_PATH REL "${CMAKE_SOURCE_DIR}/tests/golden" "${SQT_FILE}")
string(REPLACE ".sqt" "" BASE "${REL}") string(REPLACE ".sqt" "" BASE "${REL}")
string(REPLACE "/" "_" TNAME "${BASE}") 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( add_test(
NAME "golden_${TNAME}" NAME "golden_${TNAME}"
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
-DBINARY=${SAQUT_BINARY} -DBINARY=${SAQUT_BINARY}
-DSOURCE=${SQT_FILE} -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}" -P "${GOLDEN_SCRIPT}"
) )
endif() 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. # 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): # Parametreler (cmake -D ile geçilir):
# cmake -DBINARY=<saqut yolu> -DSOURCE=<.sqt yolu> -DEXPECTED=<.expected yolu> # BINARY saqut binary yolu
# [-DCOMMAND=run] -P run_golden.cmake # SOURCE test .sqt dosyası (tam yol)
# # EXPECTED beklenen çıktı dosyası (tam yol)
# COMMAND varsayılanı "run". IR testleri için COMMAND=ir geçilir. # COMMAND "run" (varsayılan) veya "ir"
# OPTIMIZED 1 ise --optimized bayrağı eklenir
if(NOT DEFINED COMMAND) if(NOT DEFINED COMMAND)
set(COMMAND "run") set(COMMAND "run")
endif() endif()
set(EXTRA_FLAGS "")
if(OPTIMIZED)
list(APPEND EXTRA_FLAGS "--optimized")
endif()
execute_process( execute_process(
COMMAND "${BINARY}" "${COMMAND}" "file:${SOURCE}" COMMAND "${BINARY}" "${COMMAND}" ${EXTRA_FLAGS} "file:${SOURCE}"
OUTPUT_VARIABLE ACTUAL OUTPUT_VARIABLE ACTUAL
ERROR_VARIABLE STDERR_OUT ERROR_VARIABLE STDERR_OUT
RESULT_VARIABLE EXIT_CODE RESULT_VARIABLE EXIT_CODE

View File

@ -11,6 +11,8 @@
#include "semantic/structural_validator.hpp" #include "semantic/structural_validator.hpp"
#include "diagnostic/diagnostic_engine.hpp" #include "diagnostic/diagnostic_engine.hpp"
#include "ir/ir_generator.hpp" #include "ir/ir_generator.hpp"
#include "core/config.hpp"
#include "opt/optimization_manager.hpp"
inline int cmdIr(const CliArgs& args) { inline int cmdIr(const CliArgs& args) {
std::string filePath = inputFilePath(args); std::string filePath = inputFilePath(args);
@ -41,11 +43,23 @@ inline int cmdIr(const CliArgs& args) {
return 1; return 1;
} }
IRGenerator irGenerator; // --optimized: optimize edilmiş AST klonu üzerinden IR üret
IRProgram program = irGenerator.generate(ast, symbolTable); 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(); program.dump();
delete optimizedAst; // nullptr ise no-op
delete ast; delete ast;
for (auto* t : tokens) delete t; for (auto* t : tokens) delete t;
return 0; return 0;

View File

@ -271,13 +271,19 @@ int IRGenerator::generateExpression(ASTNode* node) {
switch (lit->literalType) { switch (lit->literalType) {
case LiteralType::INTEGER: { case LiteralType::INTEGER: {
int value = 0; 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); value = std::stoi(lit->parserToken.token->token);
emitLoadConst(slot, value); emitLoadConst(slot, value);
break; break;
} }
case LiteralType::BOOLEAN: { 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; lit->parserToken.token->token == "true") ? 1 : 0;
emitLoadConst(slot, value); emitLoadConst(slot, value);
break; 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