feat: ADR-024/025/021 — string concat, try/catch/throw, nullable akış-analizi #115
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
10
|
|
||||||
0
|
|
||||||
0
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
14
|
|
||||||
3
|
|
||||||
1
|
|
||||||
0
|
|
||||||
1
|
|
||||||
0
|
|
||||||
0
|
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue