fix(ir): %= bileşik atama IR üretiminde eksikti (B8)

Teşhis (a): Sadece %=  unutulmuş — +=, -=, *=, /= doğru çalışıyordu.
PERCENT_EQUAL MOD opcode'una yönlendirildi; sıfıra mod runtime hatası
zaten interpreter'da mevcut, yeni kod gerekmedi.

CMakeLists.txt'e .runtime_error uzantısı eklendi (çalışma zamanı
hatası golden testleri için; aynı run_golden_error.cmake altyapısı).

Testler: compound_mod (17%5=2 zinciri) + mod_by_zero (runtime hata).
21/21 geçti.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
saqut 2026-06-19 16:52:30 +03:00
parent e5e0cdb2b3
commit 636bfcc6d5
6 changed files with 65 additions and 9 deletions

View File

@ -101,4 +101,18 @@ foreach(SQT_FILE ${ALL_GOLDEN_SQT})
-P "${CMAKE_SOURCE_DIR}/cmake/run_golden_error.cmake" -P "${CMAKE_SOURCE_DIR}/cmake/run_golden_error.cmake"
) )
endif() endif()
# Negatif test: .runtime_error çalışma zamanı hatası beklenen golden testler.
# Aynı altyapı: exit code != 0 + stderr içeriği kontrolü.
set(RUNTIME_ERROR_EXPECTED "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.runtime_error")
if(EXISTS "${RUNTIME_ERROR_EXPECTED}")
add_test(
NAME "golden_${TNAME}_runtime_error"
COMMAND ${CMAKE_COMMAND}
-DBINARY=${SAQUT_BINARY}
-DSOURCE=${SQT_FILE}
-DEXPECTED=${RUNTIME_ERROR_EXPECTED}
-P "${CMAKE_SOURCE_DIR}/cmake/run_golden_error.cmake"
)
endif()
endforeach() endforeach()

View File

@ -376,12 +376,13 @@ int IRGenerator::generateExpression(ASTNode* node) {
return varSlot; return varSlot;
} }
// Birleşik atama: += -= *= /= // Birleşik atama: += -= *= /= %=
// x += y ≡ x = x + y // x OP= y ≡ x = x OP y
if (bin->Operator == TokenType::PLUS_EQUAL || if (bin->Operator == TokenType::PLUS_EQUAL ||
bin->Operator == TokenType::MINUS_EQUAL || bin->Operator == TokenType::MINUS_EQUAL ||
bin->Operator == TokenType::STAR_EQUAL || bin->Operator == TokenType::STAR_EQUAL ||
bin->Operator == TokenType::SLASH_EQUAL) { bin->Operator == TokenType::SLASH_EQUAL ||
bin->Operator == TokenType::PERCENT_EQUAL) {
auto* lhsId = (IdentifierNode*)bin->Left; auto* lhsId = (IdentifierNode*)bin->Left;
std::string varName = lhsId->parserToken.token->token; std::string varName = lhsId->parserToken.token->token;
@ -389,9 +390,10 @@ int IRGenerator::generateExpression(ASTNode* node) {
int rhsSlot = generateExpression(bin->Right); int rhsSlot = generateExpression(bin->Right);
Opcode arithOp = Opcode::ADD; Opcode arithOp = Opcode::ADD;
if (bin->Operator == TokenType::MINUS_EQUAL) arithOp = Opcode::SUB; if (bin->Operator == TokenType::MINUS_EQUAL) arithOp = Opcode::SUB;
else if (bin->Operator == TokenType::STAR_EQUAL) arithOp = Opcode::MUL; else if (bin->Operator == TokenType::STAR_EQUAL) arithOp = Opcode::MUL;
else if (bin->Operator == TokenType::SLASH_EQUAL) arithOp = Opcode::DIV; else if (bin->Operator == TokenType::SLASH_EQUAL) arithOp = Opcode::DIV;
else if (bin->Operator == TokenType::PERCENT_EQUAL) arithOp = Opcode::MOD;
int resultSlot = freshSlot(); int resultSlot = freshSlot();
emitBinaryOp(arithOp, resultSlot, varSlot, rhsSlot); emitBinaryOp(arithOp, resultSlot, varSlot, rhsSlot);

View File

@ -0,0 +1,4 @@
2
1
0
2

View File

@ -0,0 +1,27 @@
// B8: %= bileşik atama doğru IR üretmeli.
// Elle hesap: 17%5=2, 10%3=1, 0%4=0, zincir: 20+5=25-3=22*2=44/4=11%3=2
int main() {
int a = 17;
a %= 5;
print(a); // 2
int b = 10;
b %= 3;
print(b); // 1
int c = 0;
c %= 4;
print(c); // 0
// Tüm bileşik atamalar zinciri (regresyon)
int x = 20;
x += 5; // 25
x -= 3; // 22
x *= 2; // 44
x /= 4; // 11
x %= 3; // 2
print(x); // 2
return 0;
}

View File

@ -0,0 +1 @@
sıfıra bölme \(mod\)

View File

@ -0,0 +1,8 @@
// Runtime test: a %= 0 → çalışma zamanı sıfıra bölme hatası vermeli.
int main() {
int a = 7;
a %= 0;
print(a);
return 0;
}