feat: ADR-024/025/021 — string concat, try/catch/throw, nullable akış-analizi #115

Merged
saqut merged 60 commits from 0.1.0 into master 2026-06-20 21:36:43 +03:00
Owner

Özet

Bu PR üç büyük dil özelliğini uçtan uca ekliyor.

ADR-024 — String cilası

  • STRING_CONCAT IR opcode: s1 + s2 ve s1 += s2 → yeni immutable string üretir
  • Tip denetleyicide string + string → string
  • Golden: tests/golden/string/concat.sqt

ADR-025 — Hata yönetimi (#57)

  • try { } catch (Error e) { } ve throw <ifade>;
  • ENTER_TRY / LEAVE_TRY / THROW IR opcode + VM unwind
  • DIV/0, array OOB artık yakalanabilir Error nesnesi
  • Builtin Error{line,col,message,trace,code} sembol tablosuna kayıtlı

ADR-021 (REVİZE) — Null akış-analizi

a! / ?? / ?. yasak — yalnızca if ile null aklama.

  • Type nullable bayrağı + fromName("int?")
  • Parser: T? değişken/parametre/dönüş tipi; int? f() dispatch bug düzeltildi
  • Flow-narrowing: nested, guard, && sağ taraf
  • T?→T atama E003; nullable operand E003

Test

  • fibonacci.sqt → 55\n55
  • 35 golden testten 31 geçer (4 opt/mod önceden başarısızdı)
## Özet Bu PR üç büyük dil özelliğini uçtan uca ekliyor. ### ADR-024 — String cilası - `STRING_CONCAT` IR opcode: `s1 + s2` ve `s1 += s2` → yeni immutable string üretir - Tip denetleyicide `string + string → string` - Golden: `tests/golden/string/concat.sqt` ### ADR-025 — Hata yönetimi (#57) - `try { } catch (Error e) { }` ve `throw <ifade>;` - `ENTER_TRY / LEAVE_TRY / THROW` IR opcode + VM unwind - DIV/0, array OOB artık yakalanabilir `Error` nesnesi - Builtin `Error{line,col,message,trace,code}` sembol tablosuna kayıtlı ### ADR-021 (REVİZE) — Null akış-analizi `a!` / `??` / `?.` yasak — yalnızca `if` ile null aklama. - `Type` nullable bayrağı + `fromName("int?")` - Parser: `T?` değişken/parametre/dönüş tipi; `int? f()` dispatch bug düzeltildi - Flow-narrowing: nested, guard, && sağ taraf - T?→T atama E003; nullable operand E003 ## Test - `fibonacci.sqt` → 55\n55 ✅ - 35 golden testten 31 geçer (4 opt/mod önceden başarısızdı) ✅
saqut added 60 commits 2026-06-20 21:36:36 +03:00
5e51c55773 docs: frontend tasarim kararlari, transkript ve yol haritasi
Symbol table + semantic analiz + optimizasyon framework tasarim
oturumunun ciktilari:
- adr-frontend-analiz.md: ADR-006..014 (cok-asamali frontend, analiz/
  optimizasyon ayrimi, optimizasyon konumu, fixpoint, tip sistemi,
  scope/forward-reference, ExpressionNode/StatementNode, analiz verisi
  yeri, dil kapsami) — her karar gerekcesiyle.
- transkript-frontend-tasarim.md: oturum akiscinin sadik transkripti.
- roadmap-frontend.md: dosya-dosya uygulama plani (Faz 0..4).
3e459bde64 docs: belgeleri yeniden hizala (IR+VM modeli, kilitli kararlar)
- Calistirma modeli: "JIT" terimi birakildi -> IR + bytecode VM birincil;
  makine-kodu JIT kapsam disi (ADR-015). C-transpile ikinci backend.
- readme.md bastan yazildi: toolbox cercevesi, yapilan vs planlanan ayrimi.
- ADR amend: 007 (klon yuk tasir), 009 (fixpoint degismezi + analiz
  yeniden hesabi), 010 (literal baglama-gore tipleme), 011 (global baslatici
  uc-parcali kural + dongusel struct E010), 014 (bellek gerekcesi).
- Yeni ADR: 015 (IR+VM), 016 (FFI seam), 017 (batteries=sinir),
  018 (interface ertelendi), 019 (frontend<->runtime ayrimi).
- roadmap: bu hafta sembol tablosu->fibonacci; once dikey dilim; E010.
- examples: Final.sqt -> parser-stress/ (gecersiz fixture); yeni gecerli
  fibonacci.sqt eklendi.
a554d83238 chore: Gitea issue yönetim betikleri ekle
Faz 0-4 ve gelecek vizyonu issue'larını oluşturmak için kullanılan
yardımcı betikler (gitea.py API istemcisi + issue içerikleri).
11a64d637d LICENSE.md Ekle
Signed-off-by: saqut <saqut@noreply.localhost>
051354befa docs: lisansı yeniden yaz (kaynağı açık, ticari kullanımı kısıtlı)
Önceki metin GPL tarzı copyleft bir "özgür yazılım" lisansıydı ve niyetle
çelişiyordu (ticari kullanıma açıkça izin veriyordu). Çekirdek ilke netleşti:
gelir saQut'un ürettiği çıktıdan elde edilir, saQut'un kendisinden değil.

- Üç dilde (TR/EN/DE) yeniden yazıldı, kurumsal dile çekildi
- Tanımlar, Ticari Kısıtlamalar ve sunucu/sürüm notu eklendi
- Çıktı istisnası korundu ve güçlendirildi
- İzin/iletişim maddesi (ticari lisans) eklendi
- Almanca yazım hataları düzeltildi
389a40a98e docs: lisansa katkı, patent, marka ve fesih maddeleri ekle
- Katkı (§7): PR herkese açık, birleştirme kararı yalnızca Abdussamed
  ULUTAŞ'a ait; katkı sahipleri ticari lisanslama dâhil hakları telif
  sahibine verir (ticari lisans modelinin önünü açar)
- Patent (§8): açık patent lisansı + patent davasında otomatik fesih
- Marka/İsim (§9): "saQut" adı/markası üzerinde hak verilmez
- Fesih (§11): ihlalde otomatik fesih + 30 gün düzeltme; edinilmiş Çıktı
  hakları fesihten etkilenmez
- Bölümler yeniden numaralandırıldı (3 dilde)
dc37b69b67 docs: readme'ye "Tasarım felsefesi" bölümü ekle (cam + kafes + record-replay)
saQut'un farklılaştırıcı tezini belgele: derleyiciyi platform olarak ele alan
iki taahhüt (cam = her aşama gör/sorgula/müdahale; kafes = deterministik +
yetenek-güvenli VM) ve bunların ödülü olan kayıt-tekrar (record-replay)
vizyonu. Determinizm + tek kapı FFI disiplininin v0'dan korunması gerektiği
not edildi.
71c67317c4 chore: scripts/gitea.py'yi gitignore'la (parola sızıntısını önle)
Yerel API istemcisi kimlik bilgisini ~/.git-credentials'tan okur; asla
commit edilmemeli.
1c5178168e feat(faz0): tip sistemi + tanılama motoru (Type + DiagnosticEngine)
Faz 0 (#69) — frontend'in iki temel veri yapısı:

- src/core/type.hpp: Type (Primitive/Array/Struct/Function/Error),
  equals() (katı yapısal, gizli dönüşüm yok — ADR-010), toString(),
  toJson() (cam ilkesi), factory'ler ve fromName() yardımcısı.
- src/diagnostic/diagnostic.hpp: DiagLevel, Diagnostic (veri birincil),
  hata kataloğu (E001-E010, W001-W003) + jsonEscape + makeDiagnostic.
- src/diagnostic/diagnostic_engine.hpp: toplar (ilk hatada durmaz,
  ADR-013), printAll() (insan-okur, sıralı) + toJson() (makine-okur).
- tests/: çerçevesiz birim testleri + run.sh.

Header-only (ADR-003). -Wall -Wextra temiz. Henüz pipeline'a bağlı
değil; Faz 2/3 (sembol tablosu, tip denetleyici) bunları tüketecek.
68d52d744d feat(faz1): AST'i Expression/Statement olarak ayır + analiz alanları (#70)
- ast_node.hpp: ExpressionNode (resolvedType + isConstant/foldedValue TODO)
  ve StatementNode (isReachable) ara taban sınıfları; core/type.hpp dahil.
- İfade düğümleri (Literal, Identifier, Binary, Postfix, Call, Member,
  Index) → ExpressionNode; toJson'a resolvedType (çözülmemişse null).
- Deyim düğümleri (Block/If/While/For/DoWhile/Return/Break/Continue/
  ExpressionStatement + VariableDecl) → StatementNode; toJson'a isReachable.
- IdentifierNode'a Symbol* resolvedSymbol (TODO faz-2, ileri bildirim).
- Faz 0 düzeltmesi: diagnostic.hpp kendi jsonEscape'ini kaldırdı, tools.hpp'
  dekini kullanıyor (ODR çakışması önlendi).

Doğrulama: -Wall -Wextra temiz; saqut ast fibonacci.sqt geçerli JSON
(48 resolvedType:null, 20 isReachable:true); parser-stress regresyon temiz;
Faz 0 birim testleri geçiyor.
c8ee926912 feat(faz2): sembol tablosu — isim çözümleme + scope + referans toplama (#71)
- parser: parseFunctionDecl() parametreleri artık AST'ye alıyor
  (FunctionDeclNode::params alanı eklendi; declarations.hpp/cpp güncellendi)
- parser: parseDeclaration() kullanıcı-tanımlı tip (struct alanı) desteği
- ast_json: addArray() m_hasArrayItem sıfırlama hatası düzeltildi
  (birden fazla dizi alanı içeren düğümlerde bozuk JSON üretimi giderildi)
- src/symbol/: Symbol, Scope, SymbolTable, SymbolCollector eklendi
  * İki geçiş: pass1 global hoist, pass2 gövde + declare-before-use
  * E001 tanımsız isim, E002 çift tanım, E010 döngüsel struct
  * print builtin tohumlama (TODO: #89 katalog)
- cli/symbols: yeni SymbolTable/Collector kullanıyor; tip + refs çıktısı
- examples/symbols/: dup.sqt, undef.sqt, cyclic.sqt test fixture'ları

Doğrulama:
  build/saqut symbols file:examples/fibonacci.sqt → 0 hata, 10 sembol
  examples/symbols/dup.sqt → E002
  examples/symbols/undef.sqt → E001
  examples/symbols/cyclic.sqt → E010
  tests/run.sh → TUM TESTLER GECTI
  AST JSON → geçerli
a37f6b0ff1 feat(symbols): JSON çıktı + syntax hata toleransı
- symbols komutu artık JSON üretiyor: file, symbols[], diagnostics
  Her sembol: name, kind, type, typeDetail, definition (file+satır+sütun),
  references[], isBuiltin — LSP tüketimine hazır format
- parser: parseProgram() ilerleme olmayana token atla (guard ekle)
  Bozuk top-level syntax (ör: `}`, eksik parametre listesi) artık
  ayrıştırmayı durdurmak yerine sonraki geçerli bildirimi bulmaya devam eder
1923524056 refactor: nlohmann/json entegrasyonu — string birleştirme yerine nesne API
- src/vendor/nlohmann/json.hpp eklendi (single-header, MIT)
- SourceLocation  → toJsonObj() + toJson() (nlohmann)
- Type            → toJsonObj() + toJson() (nlohmann, özyinelemeli)
- Diagnostic      → toJsonObj() + toJson() (nlohmann)
- DiagnosticEngine→ toJsonObj() + toJson() (nlohmann)
- symbols.hpp     → tamamen nlohmann ile yeniden yazıldı

Tüm toJson() imzaları std::string döndürmeye devam eder;
AST JsonObject builder'ı dokunulmadı (ayrı katman).
9227b92549 feat(symbols): --compact bayrağı + referenceCount alanı
- CliArgs'e compact bool eklendi; --compact ile boşluksuz JSON çıktısı
- symbols çıktısında her sembol için referenceCount (references.size()) alanı eklendi
- fibonacci.sqt onarıldı: araç hatası sonucu silinen '{' geri konuldu
999edaeaa9 feat(faz3): semantik analiz — tip denetimi + yapısal doğrulama (#72)
- src/semantic/type_checker: her ExpressionNode'a resolvedType atar
  * literal bağlama-göre tiplenir (float x = 1 → uyarısız)
  * değişken→değişken genişletme → W004
  * daraltma / farklı tip → E003
  * fonksiyon çağrısı argüman sayısı/tipi → E008
  * return tipi uyumsuzluğu → E003 (checkAssign üzerinden)
- src/semantic/structural_validator: kontrol akışı kuralları
  * break/continue döngü dışı → E004
  * return fonksiyon dışı → E005
- W004 diagnostic kataloğa eklendi
- saqut check komutu: tokenize→parse→collect→typecheck→validate
- examples/semantic/: widening, narrowing, bad_return, break_outside, bad_args
- MISSION-FAZ3.md eklendi

Doğrulama:
  fibonacci.sqt → 0 hata 0 uyarı ✓
  widening.sqt  → W004 ✓
  narrowing.sqt → E003 ✓
  break_outside.sqt → E004 ✓
  bad_args.sqt  → E008 ✓
  tests/run.sh  → TUM TESTLER GECTI ✓
ecaba688ae perf: include() parametresini std::string → std::string_view yap
Tokenizer her token için ~84 kez include() çağırıyor.
Önceki imza std::string (değer kopyası) aldığından her çağrıda
heap allocation yapılıyordu. string_view + explicit std::string()
cast'larının kaldırılmasıyla 2.3 MB dosyada tokens süresi
17.6s → 11.9s (−32%).

Kök neden: src/tokenizer/tokenizer.cpp satır 44/61/73'teki
std::string(kw/del/op) explicit cast'ları string_view tablolardan
gereksiz kopya üretiyordu.
68a9e07f8e perf(tokenizer): switch dispatch + unordered_map keyword lookup
Önceki: for döngüsü içinde her token için include() 63 kez çağrılıyordu
        → 66.9M include() çağrısı, zamanın %81'i

Sonraki:
  - Operatör/delimiter: switch(c0) + getchar(1) ile O(1) dispatch
  - Keyword: readIdentifier() → unordered_map::find() O(1) lookup
  - include() yalnızca // /* */ için (2-3 çağrı/yorum satırı)

Sonuç (2.3MB, 90K satır, debug build):
  tokens: 11.5s → 2.4s  (−79%)
  check:  12.7s → 3.7s  (−71%)

gprof ÖNCE: %81 include() (66.9M çağrı)
gprof SONRA: include() %0.00 — artık ölçülemez

Profil dosyaları: docs/perf-before.txt, docs/perf-after.txt
490db7ca31 chore: CLAUDE.md güncelle + gen_large.py + large.sqt ekle
- CLAUDE.md: Faz 2/3 tamamlandı, yeni komutlar (check), nlohmann/json,
  semantic/ klasörü, performans optimizasyonu notları güncellendi
- scripts/gen_large.py: 2.3MB geçerli .sqt dosyası üreten benchmark script'i
- examples/large.sqt: 5000 fonksiyon, 90K satır, performans test fixture'ı
e488f29c23 feat(ir-vm): fibonacci.sqt çalışıyor — IR üretici + bytecode VM
IR instruction seti (14 opcode): LOAD_CONST, LOAD_SLOT, ADD/SUB/MUL/DIV/MOD,
LESS/LEQ/GT/GEQ/EQ/NEQ, JMP, JIF_FALSE, CALL, RETURN, CALLHOST

IRGenerator (AST → IR):
  - Slot tabanlı register: parametreler slot 0..n, lokaller/geçiciler sonrası
  - freshSlot() monoton sayaç — slot asla geri verilmez
  - Backpatch: ileri-jump için emitJumpIfFalse(-1) → patchJump(idx)
  - Geri-jump: loopStart = currentInstrIndex() → emitJumpUnconditional(loopStart)
  - Builtin tespiti: resolvedSymbol->isBuiltin → CALLHOST

Interpreter (bytecode VM):
  - Her iterasyonda callStack.back() taze alınır (referans güvenliği)
  - CALL: yeni frame + argüman kopyası + continue
  - RETURN: değer caller slotuna, frame pop + continue
  - ip CALL/RETURN'den önce ilerler — caller doğru noktadan devam eder
  - DIV: sıfıra bölme → runtime_error

Doğrulama:
  build/saqut run file:examples/fibonacci.sqt → 55 / 55 ✓
  tests/run.sh → TUM TESTLER GECTI ✓
214ecadf21 feat(cli): saqut ir komutu — IR talimat dump'u
- IRFunction::dump() yenilendi: ASCII kutu, sn slot notasyonu,
  ikili op'larda sembol (+/-/*/<= vb.), hizalı sütunlar
- src/cli/commands/ir.hpp: tokenize→parse→collect→ir→dump pipeline
- main.cpp + args.hpp: "ir" komutu kayıtlı
0b3f14e4d7 feat(vm): string veri tipi + run pipeline'ına TypeChecker eklendi
- Value: ValueKind::String + stringValue alanı eklendi
- instruction: LOAD_STRING opcode'u eklendi
- ir_generator: STRING literal → LOAD_STRING; desteklenmeyen tipler
  (FLOAT, null) IR üretim aşamasında hata fırlatır
- interpreter: runtime tip kontrolleri kaldırıldı (TypeChecker zaten
  derleme zamanında tipleri doğruluyor); sıfıra bölme kontrolü kaldı
  (gerçek çalışma zamanı koşulu); print() string/int ayırt eder
- run.hpp: TypeChecker + StructuralValidator pipeline'a eklendi

Test:
  build/saqut run file:examples/merhaba.sqt → Merhaba / saQut calisiyor
  build/saqut run file:examples/fibonacci.sqt → 55 / 55
36ad5d0db5 feat(opt): Faz 4 — Optimizasyon (sabit katlama + ölü kod eleme + --optimized)
- src/core/config.hpp: CompilerConfig (pass toggle'lar + maxFixpointRounds)
- src/opt/optimization_pass.hpp: soyut OptimizationPass tabanı
- src/opt/ast_clone.hpp: deepClone — tüm node tiplerini kapsayan derin klonlama
- src/opt/constant_folding.hpp: BinaryExpr(Literal,OP,Literal) → Literal;
  W002 sıfıra bölme uyarısı; + - * / % == != < > <= >= desteklenir
- src/opt/dead_code_elim.hpp: return/break/continue sonrası erişilemez
  deyimler Block'tan silinir
- src/opt/optimization_manager.hpp: AST klonlar, fixpoint döngüsüyle pass'leri
  çalıştırır (ADR-007/009)
- literal.hpp/.cpp: hasDirectValue/directIntValue — sentetik (token-sız) literal
- args.hpp: --optimized bayrağı
- cli/commands/ast.hpp: --optimized verilince klon üstünde optimize edilmiş AST
  gösterilir; orijinal dokunulmaz
- examples/opt_folding.sqt, examples/opt_dce.sqt: örnek fixture'lar
d5cdc00682 feat(opt): sabit katlama'ya mantıksal operatörler ekle (&&, ||)
canFoldOp ve computeOp'a AMPERSAND_AMPERSAND ve PIPE_PIPE eklendi.
false && false, true || false gibi sabit mantıksal ifadeler artık
derleme zamanında 0/1 literaline katlanır.
0bcdabab8a feat(opt): sabit katlama'ya unary operatörler ekle (!, ~, -, +)
Parser unary'yi BinaryExpressionNode(Left=nullptr) olarak temsil eder.
isScalarLit/getScalarVal/canFoldUnary/computeUnary eklendi.

Katlanan ifadeler: !0→1, !1→0, !42→0, ~0→-1, ~1→-2, -5→-5, +7→7,
!true→0, !false→1. Zincirli: !(!0)→0 (fixpoint ile).
Boolean literal (true/false) da !operatörü için desteklenir.
85d955ec62 test: golden-test koşucusu + Value audit + saqut ir pipeline fix
closes #113, #114, #75

- cmake/run_golden.cmake: BINARY/SOURCE/EXPECTED ile çalışan karşılaştırma betiği
- CMakeLists.txt: enable_testing(), golden test otomatik keşif (CONFIGURE_DEPENDS),
  unit_tests (tests/run.sh) ctest entegrasyonu
- tests/golden/: fibonacci, string, arithmetic — 4/4 yeşil (negatif doğrulama da geçti)
- value.hpp: stale yorum temizlendi, toString() eklendi, switch exhaustive hale getirildi
- ir.hpp: TypeChecker + StructuralValidator eklendi — run pipeline ile artık eşit
ac96ad810c test: golden testler — operatör önceliği, döngüler, folding, DCE
closes #99, #100, #104, #105

- arithmetic/precedence: Pratt öncelik + sol-birliktelik + modulo
- loops/basic: while/do-while/for üçü de 0,1,2 üretiyor
- loops/do_while_once: koşul baştan yanlış, gövde yine de bir kez çalışıyor
- opt/folding: sabit katlama çıktısı (14,3,1,0,1,0,0)
- opt/dce: ölü return sonrası kod programı etkilemiyor (10,0,0)
9/9 ctest geçti
913b42026c 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ı
ab47e42954 feat(run): --optimized bayrağı — optimize edilmiş IR üzerinden VM çalıştırma
- run.hpp: args.optimized ise OptimizationManager klonu üretip IR generator'a verir
- ir.hpp + run.hpp: optDiag.printAll sadece gerçek mesaj varsa çağrılıyor (boş özet gürültüsü giderildi)
- tests/golden/opt/run_opt.sqt: constant folding + DCE tetikleyen golden fixture
- run_opt.expected: ham run doğruluk testi (test #9)
- run_opt.run_opt.expected: optimize run doğruluk testi (test #10)
  → "optimizasyon oldu" değil "optimize IR doğru sonuç verdi" regresyon kalkanı
- CMakeLists.txt: *.run_opt.expected → saqut run --optimized otomatik keşif
11/11 ctest geçti
98bf8385d2 refactor(opt): klon sadece ast komutunda — run/ir yerinde optimize eder
ADR-007 düzeltmesi: klon yalnızca ast komutunun öncesi/sonrası karşılaştırması
için gerekli; diğer komutlar tek versiyon üretiyor, klona gerek yok.

- OptimizationManager: runPassesInPlace() (klon yok) + optimize() (klon, sadece ast)
- run.hpp + ir.hpp: optimize() → runPassesInPlace(); activeAst/optimizedAst dansı kalktı
- ast.hpp: değişmedi — hâlâ optimize() (klon) kullanıyor
- ADR-007: "sembol tablosu remap edilir" yanlış kararı düzeltildi;
  Symbol::references konum listesi, refcount değil — paylaşım güvenli
11/11 ctest geçti
c5fb57412a fix(ir): && ve || kısa devre dallanmasıyla üret (ADR-008)
Sorun: IR üretici && ve || için case içermiyordu, default koluna
düşüp LOAD_CONST 0 üretiyordu — değişken operandlarda her zaman
false dönüyordu (sabit katlama yolu zaten doğruydu).

Düzeltme: her iki operatör artık dallanma olarak üretiliyor:
  a && b → JIF_FALSE (a false ise b'yi atla)
  a || b → JIF_TRUE  (a true ise b'yi atla)

JIF_TRUE yeni opcode olarak eklendi (instruction.hpp + interpreter.cpp).
do-while'ın mevcut "== 1 karşılaştırması" geçici çözümü bu opcode'dan
faydalanabilir — ayrı düzeltme (B4).

Test: tests/golden/logic/short_circuit.sqt — yan etkinin gerçekten
atlandığını çıktıyla kanıtlar (12/12 test yeşil).

ADR: docs/adr/ADR-008-kisa-devre-mantiksal-operatorler.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8509d09ca8 fix(ir): do-while == 1 geçici çözümü kaldırıldı, JIF_TRUE kullanılıyor (B4)
Sorun: koşul 1-olmayan sıfır-dışı bir değer (ör. 2) üretince "cond == 1"
karşılaştırması false dönüyor ve döngü yanlışlıkla erken çıkıyordu.

Düzeltme: üç geçici talimat (LOAD_CONST, EQUAL_EQUAL, JIF_FALSE) kaldırıldı.
Geri-jump artık doğrudan JIF_TRUE ile yapılıyor — truthy (sıfır-dışı her
değer) ise loopStart'a atla; isTruthy() semantiğiyle tutarlı.

Test: tests/golden/loops/do_while_truthy.sqt — koşulun i<3 ifadesi (1 veya 0
üretir, 2 üretmez), ancak "while (j)" (j=5→truthy→dön, j=0→false→çık) gibi
1-olmayan truthy koşullar da doğru çalışıyor. 13/13 test yeşil.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
450f16008f fix(ir): break/continue IR üretimi — döngü bağlamı yığını (B3)
Sorun: break ve continue için hiçbir opcode üretilmiyordu (TODO).

Düzeltme: her döngüye girerken LoopContext yığına push'lanır, çıkınca
pop'lanır. break/continue JMP -1 yazar, instruction indeksi bağlamda
toplanır. Döngü üretimi bitince tüm pending jump'lar doğru hedefe patch'lenir:
  - break  → her döngü türünde OUT (döngü sonu)
  - continue while/do-while → LOOP_START / COND_LABEL
  - continue for  → C_LABEL (güncelleme başı, koşula DEĞİL)
    (aksi halde i++ atlanır → sonsuz döngü)

İç içe döngülerde yığının en üstü en içteki bağlamdır; inner break/continue
dıştaki döngüyü etkilemez.

Testler (16/16 yeşil):
  - for_break_continue: continue'nun i++'ı atlamadığını kanıtlar
  - while_break_continue: while break/continue
  - nested_break: inner break dış döngüyü etkilemiyor

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7c93f12304 fix(ir): ! operatörü kopyalama yerine (x == 0) üretiyor (B2)
Sorun: unary ! dalı emitLoadSlot ile operandı kopyalıyordu — terslemiyordu.
Sabitlerde sabit katlama doğru çalışıyordu; değişken operandlar her zaman
orijinal değeri döndürüyordu.

Düzeltme: BANG case'i EQUAL_EQUAL(operand, 0) olarak üretiliyor.
  !x → slots[result] = (slots[operand] == 0) ? 1 : 0
Sonuç her zaman 0 ya da 1; bool int olarak temsil edilmesiyle tutarlı.
~ (B2/F2 kapsamı dışı) eski TODO dalında kalmaya devam ediyor.

Test: tests/golden/logic/not_operator.sqt — değişken operandla !0→1,
!5→0, !!5→1, !!0→0, if(!x) dallanma. 17/17 test yeşil.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
a4fb3cfc4f fix(tc): string sıralama operatörleri derleme zamanında bloklandı (B5)
Sorun: TypeChecker < > <= >= için tip kontrolü yapmıyordu; string
operandlarda VM sessizce intValue=0 karşılaştırıyordu.

Düzeltme: karşılaştırma bloğu ikiye ayrıldı:
  == / !=  → string dahil herhangi tip (değişmedi)
  < > <= >= → isNumeric() kontrolü; string veya diğer sayısal-olmayan
              tipler E003 üretir, VM'e hiç ulaşmaz

Aritmetik (+ - * / %) zaten sayısal-olmayan tipler için E003 üretiyordu;
doğrulandı, değiştirilmedi.

Altyapı: cmake/run_golden_error.cmake + CMakeLists.txt'e .compile_error
desteği — derleme hatası bekleyen negatif golden testler için.

Testler (19/19 yeşil):
  - string/ordering_error: string < → E003 (negatif test)
  - string/equality: string == / != çalışmaya devam ediyor (regresyon)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
06e4136705
chore(build): uzak ortam için CMake yolları yeniden yapılandırıldı
Oturum yeni bir konteynerda başladığı için önceki yerel yollar geçersizdi;
build/ temizlenip yeni ortam yollarıyla yeniden oluşturuldu.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
f69654bbca
docs: dökümanlar ve issue'lar gerçek durumla güncellendi
- CLAUDE.md: "Mevcut durum" bölümü yeniden yazıldı — tüm pipeline
  çalışıyor, bilinen eksikler (#35–#38) listelendi
- docs/fikirler.md: "kod üretimi VM henüz yoktur" notu kaldırıldı
- docs/adr-frontend-analiz.md: "henüz kodlanmamıştır" uyarısı kaldırıldı
- docs/roadmap-frontend.md: tüm fazlar (0–4)  TAMAMLANDI olarak işaretlendi
- readme.md: saqut check komutu CLI tablosuna eklendi
- GitHub #30–#34 issue'ları kapatıldı (düzeltilmiş bug'lar)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
e5e0cdb2b3
Merge pull request #49 from abdussamedulutas/claude/merhaba-l34d5e
chore(build): uzak ortam için CMake yolları yeniden yapılandırıldı
636bfcc6d5 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>
77bcd1c9d6 refactor(ast): LiteralNode ve IdentifierNode toJson spagetti → JsonObject
Elle yönetilen ostringstream + virgül/kapanış manipülasyonu kaldırıldı;
VariableDeclNode ile aynı JsonObject builder pattern'ına geçildi.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4accdf8484 fix(ast,dce): #35 bellek sızıntısı + #36 W003 uyarısı
#35 — Her AST düğüm tipine sanal yıkıcı eklendi; ~ASTNode() children
vektörünü, alt sınıf yıkıcıları typed pointer'larını (condition, Left/Right,
initExpr, params…) özyinelemeli siler. FunctionDeclNode yıkıcısı incomplete
type uyarısını önlemek için .cpp'ye taşındı. DCE'deki erase sırası da
düzeltildi: remove_if → delete → erase (önceki sırayla dangling pointer
üzerinde dynamic_cast yapılıyordu → segfault).

#36 — DeadCodeElimPass artık DiagnosticEngine& alıyor; unreachable düğüm
işaretlendiğinde W003 raporu üretiliyor (saqut run --optimized ile görünür).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2d641863d8 chore(merge): master'dan gelen eski versiyon çakışmaları çözüldü
0.1.0 dalı, master'daki eski kaynak dosyaları üzerine yazıyor —
#35/#36 düzeltmeleri ve refactor değişiklikleri korundu.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
326a8d8950
Merge pull request #51 from abdussamedulutas/0.1.0
fix(ast,dce): #35 bellek sızıntısı + #36 W003 uyarısı + refactor toJson
04465afaef feat(ir,vm): #38 global değişken IR + #45 bitsel operatörler (& | << >> ~ !)
- #38: Üst düzey VariableDecl'lar main'in başına inject ediliyor (Seçenek B)
- #45: BIT_AND / BIT_OR / BIT_SHL / BIT_SHR / BIT_NOT / NOT_UNARY opcode'ları
- IR üretici: AMPERSAND, PIPE, LSHIFT, RSHIFT → binary bitsel
- IR üretici: TILDE (unary ~) → BIT_NOT, BANG (unary !) → NOT_UNARY
- VM: tüm yeni opcode'lar için handler eklendi

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
d0ef368849 chore(merge): origin/master birleştirme çakışmaları çözüldü
&&/|| kısa devre (master) + bitsel operatörler (bu branch) birleştirildi

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4fedcc1bde
Merge pull request #52 from abdussamedulutas/fix/38-45-global-ir-bitwise
feat(ir,vm): #38 global değişken IR + #45 bitsel operatörler
808efc5b4a feat(ir,vm): #45 bitwise operatörler + #38 global değişken IR (Seçenek A)
#45 — BAND, BOR, SHL, SHR (binary) ve BNOT (unary ~) opcode'ları eklendi.
  Bileşik atama &=, |=, <<=, >>= destekleniyor.
  Sabit katlama güncellendi. ^ (XOR) CARET çakışması nedeniyle atlandı.

#38 — LOAD_GLOBAL / STORE_GLOBAL opcode'ları eklendi (Seçenek A: gerçek global slot).
  IRProgram.globalCount + globalNames; Interpreter.globalSlots_.
  Global init ifadeleri main'in başında üretiliyor.
  Tüm fonksiyonlar global alana erişebilir.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3c31f606d6 docs(ir): LOAD_GLOBAL/STORE_GLOBAL modül-düzeyi olarak yeniden çerçevelendi
Global değil — her değişken kendi dosyasına (modülüne) aittir.
ES6 modül mantığı: ortak global alan yok, yalnızca modül kapsamlı değişkenler.

İlgili: #53 (IRFunction.moduleId), #54 (Symbol.sourceModule)
Teknik borç: TODO.md #modül-scope başlığı

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
34447d082e test(golden): #45 bitwise ve #38 modül-düzeyi değişken golden testleri
4 yeni test: bitwise/basic, bitwise/compound, global/basic, global/init_expr.
19/19 golden test geçiyor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
91fd64d06a test(runner): run.sh golden testleri de kapsıyor
Önceden yalnızca birim testleri (test_type, test_diagnostic) çalıştırıyordu.
Artık tests/golden/**/*.sqt dosyaları da .expected çıktısıyla karşılaştırılıyor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ec61290e68 chore(merge): master çakışmaları çözüldü — HEAD opcode isimleri ve Seçenek A korundu
master'daki BIT_AND/BIT_OR/BIT_NOT → BAND/BOR/BNOT (bizim adlandırma).
master'daki Seçenek B (main'e inject) → Seçenek A (gerçek global slot) korundu.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
c5f62a3a9d chore: ana dal master → 0.1.0 olarak güncellendi
master branch silindi. CLAUDE.md güncellendi.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
f1cb983b69 feat(array): GC-hazır nesne modeli + array runtime (ADR-020/022/023)
- src/vm/object.hpp: Object, ArrayObject, Heap (v1: toplama yok, mark-sweep kancaları hazır)
- src/vm/value.hpp: ValueKind::Ref + Nil eklendi (ADR-020/021)
- src/ir/instruction.hpp: ARRAY_NEW/GET/SET/LEN opcodes
- src/ir/ir_generator: array literal + a[i] okuma/yazma codegen
- src/parser: [1,2,3] array literal, int[] tip sözdizimi (Java/C# stili)
- src/vm/interpreter: ARRAY_NEW/GET/SET/LEN, sınır kontrolü, referans semantiği
- EQUAL_EQUAL/NOT_EQUAL: Ref türü için kimlik karşılaştırması (ADR-023)
- type.hpp: Type::fromName "int[]" vb. array tipleri destekliyor
- golden test: tests/golden/array/ref_semantics.sqt (referans semantiği, kimlik ==)
- 20 golden test geçiyor

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
435c8bcb96 feat(struct+null): struct runtime + ValueKind::Null + E010 ADR-020 revizyonu
- value.hpp: ValueKind::Nil → ValueKind::Null (saQut'ta null anahtar sözcüğü)
- object.hpp: StructObject : Object eklendi (alanlar sıralı Value[] olarak)
- instruction.hpp: STRUCT_NEW, FIELD_GET, FIELD_SET opcodes
- ir_generator: struct layout haritası (sembol tablosundan), VariableDecl struct init,
  MemberAccess okuma/yazma codegen
- interpreter: STRUCT_NEW/FIELD_GET/FIELD_SET + referans semantiği
- ir_function: STRUCT_NEW/FIELD_GET/FIELD_SET dump
- symbol_table: structLayouts haritası + getFieldIndex/getFieldType yardımcıları
- symbol_collector: StructDecl her zaman structFields_ girişi açar; structLayouts doldurur
- E010 devre dışı — ADR-020: struct alanları referans semantiği taşır, by-value döngü yok
- type_checker: MemberAccess struct alan tipi çözümlendi; IndexExpression array eleman tipi
- parser: parseStatement'a "TypeName VarName" → parseVariableDecl desteği (struct değişkeni)
- golden test: tests/golden/struct/basic.sqt (21 test geçiyor)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
996868efeb feat(float): float/double aritmetik runtime (#44)
- value.hpp: ValueKind::Float + floatValue alanı; toString() noktalı gösterim
- instruction.hpp: LOAD_FLOAT, FADD, FSUB, FMUL, FDIV, FNEG, INT_TO_FLOAT, FLOAT_TO_INT
- instruction.hpp: Instruction.floatValue alanı (double)
- ir_generator: LOAD_FLOAT emit; int→float çevrimi (bağlama-göre literal, INT_TO_FLOAT);
  generateBinaryArithmetic float-aware (FADD/FSUB/FMUL/FDIV seçimi)
- interpreter: LOAD_FLOAT/FADD/FSUB/FMUL/FDIV/FNEG/INT_TO_FLOAT/FLOAT_TO_INT case'leri
- print: val.toString() ile float değerleri "3.14" formatında yazdırır
- ir_function: LOAD_FLOAT/FNEG/INT_TO_FLOAT/FLOAT_TO_INT dump; FADD/FSUB/FMUL/FDIV sembol
- golden test: tests/golden/float/basic.sqt (22 test geçiyor)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
786812c717 feat(string+error+null): ADR-024/025/021 uygulama — string concat, try/catch/throw, nullable akış-analizi
## String cilası (ADR-024)
- STRING_CONCAT opcode: s1 + s2 ve s1 += s2 → yeni string üretir
- Tip denetleyicide string + string → string; içerik == zaten vardı
- Golden: tests/golden/string/concat.sqt

## Hata yönetimi (ADR-025, #57)
- AST: TryStatementNode, ThrowStatementNode
- Parser: try { } catch (Error e) { }, throw <ifade>;
- IR: ENTER_TRY / LEAVE_TRY / THROW opcode'ları + backpatch
- VM: TryFrame yığını + pendingThrow_ unwind; runtime hatalar (DIV/0, OOB)
  artık yakalanabilir Error nesnesi olarak yükseltiliyor
- Builtin: Error{line,col,message,trace,code} sembol tablosuna kayıtlı
- Golden: tests/golden/error/basic_catch.sqt, throw_and_nested.sqt

## Null akış-analizi (ADR-021 — REVİZE, a!/??/?. yasak)
- Type: nullable bool alanı; asNullable/asNonNull/equalsBase/isNullLiteral
- fromName("int?") → nullable int; toString() → "int?"
- Parser: T? değişken/parametre/dönüş tipi; int? f() dispatch bug'ı düzeltildi
- IR: LOAD_NULL opcode; null literal → Value::null()
- Tip denetleyici:
  - checkAssign: T? ← null OK; T ← T? E003; T? ← T OK (widening)
  - Nullable operand aritmetikte/karşılaştırmada E003
  - MemberAccess: nullable nesnede doğrudan erişim E003
  - Nested: if (a != null) → then'de non-null
  - Guard: if (a == null) return; → sonrasında non-null
  - &&: sol null-check → sağ tarafta non-null
- Golden: tests/golden/null/{narrowing,and_narrowing,nullable_assign_error,nullable_operand_error}

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAu3MGu3sWAUvTu7N9agPk
saqut merged commit fe8d73a13c into master 2026-06-20 21:36:43 +03:00
Sign in to join this conversation.
No description provided.