From 1232748f9fa1e5905d709bb5bcb03a42687fc1a4 Mon Sep 17 00:00:00 2001 From: abdussamedulutas Date: Sun, 14 Jun 2026 22:44:30 +0300 Subject: [PATCH] =?UTF-8?q?chore:=20Gitea=20issue=20y=C3=B6netim=20betikle?= =?UTF-8?q?ri=20ekle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). Co-Authored-By: Claude Sonnet 4.6 --- scripts/create_future_issues.py | 560 +++++++++++++++++++++++++++ scripts/create_issues.py | 160 ++++++++ scripts/create_syntax_test_issues.py | 499 ++++++++++++++++++++++++ 3 files changed, 1219 insertions(+) create mode 100644 scripts/create_future_issues.py create mode 100644 scripts/create_issues.py create mode 100644 scripts/create_syntax_test_issues.py diff --git a/scripts/create_future_issues.py b/scripts/create_future_issues.py new file mode 100644 index 0000000..e8700a9 --- /dev/null +++ b/scripts/create_future_issues.py @@ -0,0 +1,560 @@ +#!/usr/bin/env python3 +"""Faz 0-4 sonrasi icin vizyon/backlog issue'lari. + +Bu issue'lar PLAN degildir; fikir/tartisma kayitlaridir. Faz issue'larindan +(#69-73) farkli olarak "Sonuc ve Basari Kriterleri" / "Muhendis olmayan analiz" +bolumleri yoktur - bunun yerine "Acik Sorular" bolumu vardir. Iceriklerin +zamanla degismesi beklenir. +""" +from gitea import make_request, REPO_PATH + +L_FIKIR = 66 +L_IRVM = 67 +L_MODUL = 68 +L_TIP = 69 +L_FFI = 70 +L_TOOLING = 71 +L_VIZYON = 72 + +issues_data = [ + # ---------------- IR & Bytecode VM ---------------- + { + "title": "[Fikir] IR Komut Seti Tasarımı (Üç-Adresli Kod / Three-Address Code)", + "labels": [L_FIKIR, L_IRVM], + "body": """### Giriş (Nedir, Neden Önemli?) +Faz 0-4 bitince AST (Abstract Syntax Tree, Soyut Sözdizimi Ağacı) tip ve sembol bilgisiyle dolu olacak. Ama AST hâlâ "ağaç" — VM'in (Bytecode VM, Bayt Kodu Sanal Makinesi) çalıştırabileceği düz bir komut listesi değil. Bu issue, AST'den üretilecek **IR'in (Immediate Representation, Ara Temsil)** komut setini tartışır. + +--- + +### Gelişme (Olası Yaklaşımlar) +- **Üç-adresli kod (three-address code):** `t1 = a + b`, `t2 = t1 * c` gibi her komut en fazla bir işlem yapar. Okunabilirlik (alet çantası felsefesiyle uyumlu — `saqut ir` ile basılabilir) ile uygulama kolaylığı arasında iyi bir denge. +- Minimal opcode ailesi: aritmetik (`add/sub/mul/div`), karşılaştırma, atama (`store/load`), kontrol akışı (`jump/jump_if_false/label`), fonksiyon (`call/return`), dizi/struct erişimi (`get_field/set_field/get_index/set_index`). +- Her IR komutu kaynak `SourceLocation`'ı taşımalı — hata mesajları ve "öncesi/sonrası" karşılaştırması için (alet çantası amacı). +- `examples/fibonacci.sqt` için elle IR çıktısı yazılıp hedef format netleştirilebilir (taslak doküman olarak). + +--- + +### Açık Sorular +- Üç-adresli kod mu, yoksa stack-tabanlı (yığın tabanlı) bir ara form mu daha basit olur? (VM tasarımıyla bağlantılı, bkz. ilgili issue) +- Struct/array gibi değer-semantikli (value semantics) tipler IR seviyesinde nasıl temsil edilir — kopyalama ne zaman gerçek bir IR komutu olur? +- Optimizasyon (Faz 4) pass'leri AST üzerinde mi kalır, yoksa IR seviyesine de mi taşınır? + +*İmza/Yorum:* Bu issue, "IR güçlendirme" yol haritasının (roadmap-frontend.md sonu) ilk taslağıdır. Faz 0-4 bitmeden kilitli karar alınmamalı — sadece beyin fırtınası.""" + }, + { + "title": "[Fikir] IR'in Serileştirilmesi ve İncelenebilirliği (`saqut ir` komutu)", + "labels": [L_FIKIR, L_IRVM], + "body": """### Giriş (Nedir, Neden Önemli?) +saQut'un varlık sebebi "her aşamanın dışarıdan görülebilir olması". Token, AST ve sembol tablosu zaten `saqut tokens/ast/symbols` ile JSON olarak görülebiliyor. IR de aynı muameleyi görmeli. + +--- + +### Gelişme (Olası Yaklaşımlar) +- `saqut ir file:kaynak.sqt` komutu: AST'den üretilen IR'i hem **insan-okur metin** (örn. assembly benzeri `t1 = a + b`) hem de **JSON** (`--format=json`) olarak basar. +- `--optimized` bayrağıyla optimizasyon öncesi/sonrası IR yan yana (diff) gösterilebilir — Faz 4'teki AST öncesi/sonrası karşılaştırmasının IR karşılığı. +- Her IR komutuna kaynak satır/sütun referansı eklenip, IR'den kaynağa "geri işaretleme" (source map benzeri) yapılabilir — ileride debugger için temel oluşturur. + +--- + +### Açık Sorular +- IR metin formatı kendi mini-sözdizimi mi olacak, yoksa mevcut JSON şemasının bir uzantısı mı? +- IR dump'ı dosyaya yazılıp tekrar VM'e beslenebilir mi (round-trip) — bu, derleme adımlarını birbirinden bağımsız test etmeyi kolaylaştırır. + +*İmza/Yorum:* Bu, "programlanabilir derleyici" vaadinin IR ayağı. Küçük ama saQut'un kimliği için sembolik önemde.""" + }, + { + "title": "[Fikir] Bytecode Formatı: Yığın-Tabanlı mı (Stack-based), Register-Tabanlı mı VM?", + "labels": [L_FIKIR, L_IRVM], + "body": """### Giriş (Nedir, Neden Önemli?) +ADR-015 çalıştırma modelini kilitledi: IR + bytecode VM (yorumlayıcı döngü), gerçek makine-kodu JIT yok. Ama VM'in *iç mimarisi* henüz seçilmedi: **yığın-tabanlı (stack-based, Python/JVM/Wasm tarzı)** mi, **register-tabanlı (Lua 5'in VM'i tarzı, sanal register'lar)** mı? + +--- + +### Gelişme (Olası Yaklaşımlar) +- **Yığın-tabanlı:** Komutlar değer push/pop eder (`push a`, `push b`, `add`). Üretmesi basit, IR'den bytecode'a çeviri kolay. Dezavantaj: gereksiz push/pop'lar (performans, ama saQut için öncelik değil — bkz. ADR-015 "determinizm/incelenebilirlik > hız"). +- **Register-tabanlı:** Her fonksiyonun sanal register'ları olur (`add r1, r2, r3`). Daha az komut, ama derleyici tarafı (register allocation - kayıt tahsisi) daha karmaşık. +- saQut'un önceliği **basitlik + incelenebilirlik** olduğu için yığın-tabanlı VM ile başlamak "önce dikey dilim" ilkesine daha uygun olabilir; register-tabanlı'ya geçiş ileride bir "VM v2" issue'su olabilir. + +--- + +### Açık Sorular +- Yığın-tabanlı seçilirse, fonksiyon çağrıları için ayrı bir "call stack" mı, tek bir birleşik yığın mı kullanılır? +- Debug/inceleme modunda her adımdan sonra yığının tam içeriği dump edilebilir mi (alet çantası vaadiyle doğrudan ilişkili)? + +*İmza/Yorum:* Bu karar IR komut setini (önceki issue) doğrudan etkiler — birlikte tartışılmalı. Önerim: v0 için yığın-tabanlı, basitliği ve incelenebilirliği önceliklendirdiği için.""" + }, + { + "title": "[Fikir] VM Yorumlayıcı Döngüsü ve Dispatch Stratejisi", + "labels": [L_FIKIR, L_IRVM], + "body": """### Giriş (Nedir, Neden Önemli?) +Bytecode VM'in kalbi, her komutu okuyup ilgili işlemi yapan "yorumlayıcı döngü" (interpreter loop / dispatch loop). Bu döngünün nasıl yazılacağı hem performansı hem de kod okunabilirliğini etkiler. + +--- + +### Gelişme (Olası Yaklaşımlar) +- **Switch-case dispatch:** `switch(opcode) { case ADD: ...; case JUMP: ...; }`. En basit, en okunabilir, derleyici bağımsız (portable). saQut'un "incelenebilir" felsefesiyle en uyumlu başlangıç noktası. +- **Computed goto / jump table:** Daha hızlı ama derleyiciye özel uzantılar gerektirir (GCC/Clang `&&label`), taşınabilirlik düşer. Hız öncelik değilse (ADR-015) v0'da gereksiz karmaşıklık. +- **Threaded code:** Her IR komutunu doğrudan bir C++ fonksiyon pointer'ına çeviren ileri teknik — şimdilik kapsam dışı. +- v0 önerisi: basit switch-case + her adımda "trace" modu (her komut çalışmadan önce/sonra durum dump edilebilir, ADR-016 FFI seam ile `print` zaten bu yola hazırlanıyor). + +--- + +### Açık Sorular +- Yorumlayıcı tek bir `run()` fonksiyonu mu olacak, yoksa her opcode için ayrı `handle_*` fonksiyonu mu (okunabilirlik vs. fonksiyon çağrı maliyeti — ama maliyet öncelik değil)? +- Adım-adım çalıştırma (step) ve "tüm programı çalıştır" (run) aynı döngüyü mü paylaşacak? + +*İmza/Yorum:* "Önce dikey dilim" ilkesi burada da geçerli: en basit switch-case ile fibonacci çalışsın, optimize dispatch ileri bir konu.""" + }, + { + "title": "[Fikir] Fonksiyon Çağrı Mekanizması ve Call Frame Tasarımı", + "labels": [L_FIKIR, L_IRVM], + "body": """### Giriş (Nedir, Neden Önemli?) +`examples/fibonacci.sqt` özyinelemeli (recursive) bir fonksiyon. VM'in fonksiyon çağrılarını (call/return), parametreleri ve yerel değişkenleri nasıl tuttuğu — yani **call frame (çağrı çerçevesi)** tasarımı — özyinelemenin doğru çalışması için kritik. + +--- + +### Gelişme (Olası Yaklaşımlar) +- Her fonksiyon çağrısında bir "frame" oluşturulur: dönüş adresi, parametreler, yerel değişkenler için ayrılan yer. Bu frame'ler bir "call stack" üzerinde tutulur (host C++ heap'i üzerinde — ADR-015, özel allocator yok). +- Özyinelemeli çağrılar (fibonacci(n-1), fibonacci(n-2)) her biri kendi frame'ine sahip olmalı — değişkenler birbirine karışmamalı (scope-based memory model, ADR-014). +- Maksimum çağrı derinliği (stack overflow koruması) — basit bir sayaç/limit ile "stack taşması" hatası verilebilir (yeni bir E-kodu olabilir, ileride katalogla birleştirilir). + +--- + +### Açık Sorular +- Frame boyutu derleme zamanında mı (compile-time, fonksiyonun yerel değişken sayısına göre) hesaplanır, yoksa dinamik mi büyür? +- Fonksiyon dönüş değeri yığının üstüne mi konur (yığın-tabanlı VM ile uyumlu), yoksa ayrı bir "return register" mı kullanılır? + +*İmza/Yorum:* Bu issue VM tasarımı (önceki issue) seçimine bağımlıdır; ama fibonacci'nin "bitti" tanımı (recursive + iterative) bu mekanizma olmadan anlamsızdır — birinci öncelikli IR/VM konusu.""" + }, + { + "title": "[Fikir] Array ve Struct'ların Runtime Bellek Düzeni", + "labels": [L_FIKIR, L_IRVM], + "body": """### Giriş (Nedir, Neden Önemli?) +Dil kimliği `struct` ve `int[]` (array/dizi) içeriyor, value semantics (değer semantiği) ile. VM çalışırken bu değerlerin bellekte nasıl yer alacağı — kopyalama ne zaman olur, struct içinde struct/array nasıl saklanır — netleşmeli. + +--- + +### Gelişme (Olası Yaklaşımlar) +- Value semantics demek: `struct Point p2 = p1;` ifadesi `p1`'in **tam kopyasını** oluşturur (referans değil). VM'de bu, struct'ın tüm alanlarının yığın/heap'te kopyalanması anlamına gelir. +- Array boyutu derleme zamanında sabit mi (E009 hatası bunu zaten kontrol ediyor), yoksa dinamik büyüyebilen bir array tipi de mi olacak (`std::vector` benzeri, host heap üzerinde)? +- Struct içinde struct: iç içe value-copy maliyeti büyüyebilir — ama saQut'ta "hız öncelik değil" (ADR-015), önce doğruluk. + +--- + +### Açık Sorular +- Dinamik boyutlu array (`int[]` boyutu çalışma zamanında belirlenen) v0 kapsamında mı, yoksa v1'e mi bırakılır? +- Struct kopyalama IR'de tek bir "copy" komutu mu olur, yoksa alan-alan kopyalama komut dizisine mi açılır (incelenebilirlik açısından ikincisi daha "alet çantası" uyumlu olabilir)? + +*İmza/Yorum:* ADR-014'teki "scope-based bellek artık gerekçeli" notuyla doğrudan ilişkili — bu issue o kararın runtime'a yansımasıdır.""" + }, + { + "title": "[Fikir] IR Seviyesinde Kontrol Akışı Grafiği (CFG) ve SSA — Gerekli mi?", + "labels": [L_FIKIR, L_IRVM], + "body": """### Giriş (Nedir, Neden Önemli?) +Çoğu "gerçek" derleyici (GCC, LLVM) IR'i bir **CFG (Control Flow Graph, Kontrol Akışı Grafiği)** üzerinde **SSA (Static Single Assignment, Statik Tekil Atama)** formunda tutar. Bu, ileri optimizasyonları (constant propagation, dead code elimination'ın güçlü hali) çok kolaylaştırır ama ciddi bir mühendislik yatırımıdır. + +--- + +### Gelişme (Olası Yaklaşımlar) +- saQut'un Faz 4 optimizasyonları (constant folding, dead code elimination) şu an **AST üzerinde** çalışıyor ve bu yeterli olabilir — CFG/SSA şart değil. +- CFG/SSA'nın getirisi: döngü içindeki optimizasyonlar, daha güçlü dead-code analizi. Maliyeti: yeni bir ara temsil katmanı, "basit kalsın" ilkesiyle gerilim yaratabilir. +- Orta yol: basit IR (üç-adresli kod, lineer komut listesi + `jump`/`label`) yeterli olduğu sürece CFG/SSA'ya **geçilmez**; ancak optimizasyon ihtiyaçları büyürse (örn. döngü-invariant kod taşıma) bu issue tekrar açılır. + +--- + +### Açık Sorular +- "Yeterlilik" sınırı nasıl ölçülür? Belki: fibonacci + birkaç döngü/dizi örneği optimize edildiğinde gözle görülür iyileşme varsa CFG/SSA'ya gerek yoktur. +- CFG olmadan da basit "basic block" (temel blok) kavramı IR'e eklenebilir mi (sadece jump hedeflerini gruplamak için, SSA olmadan)? + +*İmza/Yorum:* Bu issue kasıtlı olarak "yapma" eğiliminde — erken soyutlama riskine karşı bir hatırlatma (roadmap'teki "önce dikey dilim" ilkesi).""" + }, + # ---------------- Moduller / Import ---------------- + { + "title": "[Fikir] Import Sözdizimi ve Modül Çözümleme", + "labels": [L_FIKIR, L_MODUL], + "body": """### Giriş (Nedir, Neden Önemli?) +Şu ana kadar tüm tasarım **tek dosyalı** programları (`examples/fibonacci.sqt`) hedefliyor. Ama gerçek projeler birden fazla dosyaya bölünür. saQut'a "başka bir dosyadaki fonksiyon/struct'ı kullan" diyebilmek için bir **import (içe aktarma)** sözdizimi gerekir. + +--- + +### Gelişme (Olası Yaklaşımlar) +- En basit model: `import "util.sqt"` — dosya yolu tabanlı, C'nin `#include`'una benzer ama metin yapıştırma değil, **sembol tablosu seviyesinde birleştirme** (her dosya kendi AST'sine sahip kalır, sembol çözümleme dosyalar arası genişler). +- Alternatif: isim-tabanlı modül sistemi (`import util` → `util.sqt` veya `util/` dizini arar), Go/Python tarzı. +- saQut'ta `class`/namespace yok — modül adı, dosya adına eşlenebilecek doğal bir "isim alanı" (namespace) adayı olabilir: `util.helper()` gibi nokta-erişimi. + +--- + +### Açık Sorular +- Döngüsel import (A, B'yi; B, A'yı import ediyor) nasıl ele alınır — derleme hatası mı, yoksa forward-declaration ile mi çözülür (ADR-011'deki forward-reference mantığına benzer)? +- Import edilen dosyanın AST'si her derlemede yeniden mi ayrıştırılır, yoksa bir "derleme birimi cache"i mi olur (LSP issue'suyla bağlantılı)? + +*İmza/Yorum:* Bu, "Faz 5: Modüller" için doğal bir başlangıç noktası olabilir — ama Faz 0-4 (tek dosya, fibonacci) bitmeden ele alınmamalı.""" + }, + { + "title": "[Fikir] Modüller Arası Görünürlük (public/private) ve İsim Çakışmaları", + "labels": [L_FIKIR, L_MODUL], + "body": """### Giriş (Nedir, Neden Önemli?) +İmport sistemi geldiğinde, "her şey her yerden görülebilir mi" sorusu ortaya çıkar. Bu, sembol tablosunun (Faz 2) modüller arası nasıl genişletileceğiyle doğrudan ilgili. + +--- + +### Gelişme (Olası Yaklaşımlar) +- En basit kural: bir dosyadaki **tüm üst-seviye tanımlar** (fonksiyon, struct, global değişken) import eden dosyaya açık olur — "herkese açık" (public-by-default), C'nin extern'siz fonksiyonlarına benzer. Basitlik açısından v0 için cazip. +- Daha kontrollü model: `private` anahtar kelimesi ile bir dosyaya özel tanımlar işaretlenebilir — ama bu, dil kimliğine yeni bir anahtar kelime ekler (ADR'lerle uyumlu mu tartışılmalı). +- İsim çakışması (iki modülde aynı isimde fonksiyon): modül-öneki (`util.process()`) zorunlu kılınarak çözülebilir — bu, import sözdizimi issue'suyla birlikte kararlaştırılmalı. + +--- + +### Açık Sorular +- "Herkese açık" model, sembol tablosunun global scope'unu modüller arasında nasıl birleştirir — her modül kendi global scope'una mı sahip olur, yoksa tek bir "program-geneli" scope mu? +- Bu karar E002 (çift tanım) hatasının kapsamını değiştirir mi — aynı isim iki modülde tanımlanırsa hata mı, yoksa öneklemeyle ayrışır mı? + +*İmza/Yorum:* Önerim: v0 için "herkese açık, modül-önekiyle eriş" — basit ve declare-before-use (ADR-011) felsefesiyle tutarlı.""" + }, + { + "title": "[Fikir] Çoklu Dosya Derleme ve Bağımlılık Sırası", + "labels": [L_FIKIR, L_MODUL], + "body": """### Giriş (Nedir, Neden Önemli?) +Import sistemi geldiğinde, `saqut run main.sqt` komutu artık tek dosya değil, bir **bağımlılık ağacı** (dependency graph) derlemek zorunda kalır. Bu issue, CLI ve derleme akışının (pipeline) buna nasıl uyacağını tartışır. + +--- + +### Gelişme (Olası Yaklaşımlar) +- Derleyici önce tüm `import` ifadelerini tarayıp bir **dosya bağımlılık grafiği** çıkarır (basit DFS/topological sort — ADR-011'deki struct çevrim kontrolüyle aynı algoritmik aile). +- Her dosya kendi AST'sine ve (Faz 2 sonrası) kendi sembol tablosu parçasına sahip olur; sembol çözümleme son adımda birleştirilir. +- "Programlanabilir derleyici" felsefesiyle: `saqut ast --module=util.sqt` gibi tek bir modülün AST'si de ayrı incelenebilir kalmalı — çoklu dosya derleme tek-dosya inceleme yeteneğini kırmamalı. + +--- + +### Açık Sorular +- Döngüsel bağımlılık (önceki issue'da bahsedilen) burada nasıl raporlanır — yeni bir E-kodu mu (örn. `E011`)? +- Derleme çıktısı (IR/bytecode) tek bir birleşik dosya mı olur, yoksa modül-başına ayrı IR mi üretilip VM'de "link" edilir (gerçek linker'lara benzer ama çok daha basit)? + +*İmza/Yorum:* Bu konunun karmaşıklığı yüksek olabilir — "önce dikey dilim" ilkesi burada özellikle geçerli: tek-dosya fibonacci bitmeden bu issue'ya başlanmamalı.""" + }, + # ---------------- Tip Sistemi Genişletmeleri ---------------- + { + "title": "[Fikir] Native Decimal Tipi (Ondalıklı Sayılarda Hassasiyet)", + "labels": [L_FIKIR, L_TIP], + "body": """### Giriş (Nedir, Neden Önemli?) +`float`/`double` ikili (binary) kayan-nokta sayılardır ve ondalık kesirleri (örn. `0.1`) tam temsil edemez — bu, para/finans hesaplamalarında hatalara yol açar. Birçok modern dil (C#, Python `Decimal`) bunun için ayrı bir **decimal (ondalık) tip** sunar. + +--- + +### Gelişme (Olası Yaklaşımlar) +- `decimal` yeni bir primitif `TypeKind` olarak `src/core/type.hpp`'ye eklenebilir (Faz 0'ın `Type` sınıfı genişletilebilir tasarlanmalı — bu issue o genişletilebilirliği şimdiden akılda tutmak için var). +- Runtime temsili: sabit-noktalı (fixed-point) tamsayı + ölçek (scale) çifti (örn. "scaled integer" — `12345` ve ölçek `2` → `123.45`). Host heap'te basit bir struct olarak tutulabilir, özel kütüphane gerekmez (v0). +- Literal Adaptasyon Kuralı (ADR-010) ile ilişki: `decimal x = 1;` geçerli olmalı (tamsayı → decimal kayıpsız); `decimal x = 1.5;` (float literal → decimal) hassasiyet tartışması gerektirir. + +--- + +### Açık Sorular +- `decimal` aritmetiği (`+`, `*`) için taşma (overflow) kuralları ne olacak — hata mı, yoksa otomatik büyüme mi (bu, "host heap, özel allocator yok" ADR-015 ilkesiyle gerilim yaratabilir)? +- Bu tip v0.1'in parçası mı, yoksa "batteries" (ADR-017) kapsamında ileride bir FFI/kütüphane çözümü mü? + +*İmza/Yorum:* "Modern dillerin standart hale getirdiği ama derleyici çekirdeğine gömülmesi gereken" tiplerin ilk örneği — kullanıcı isteğiyle doğrudan örtüşüyor.""" + }, + { + "title": "[Fikir] Native Date/Time (Tarih/Zaman) Tipi", + "labels": [L_FIKIR, L_TIP], + "body": """### Giriş (Nedir, Neden Önemli?) +Tarih/zaman, hemen her gerçek programda karşılaşılan ama yanlış yapılması çok kolay bir konudur (saat dilimleri, artık yıllar, formatlar). Modern diller (Go, Rust, JS `Temporal`) bunu standart kütüphaneye/derleyiciye yakın tutar. + +--- + +### Gelişme (Olası Yaklaşımlar) +- v0 için minimal yaklaşım: `date`/`datetime` yeni bir primitif tip olarak değil, **struct olarak saQut'un kendisinde** tanımlanabilir (`struct Date { int year; int month; int day; }`) — bu, "batteries = FFI/kütüphane sınırı" (ADR-017) felsefesiyle örtüşür ve derleyici çekirdeğine yük bindirmez. +- Daha ileri: gerçek saat/takvim hesapları (örn. "bugünden 30 gün sonrası") host sisteminden FFI (ADR-016, `callhost`) ile alınabilir — saat dilimi/takvim mantığı saQut içine yazılmaz, denenmiş bir C kütüphanesine (örn. sistem `time.h`) bağlanır. +- Eğer ileride performans/ergonomi nedeniyle native bir `date` tipi gerekirse, bu issue "native tip mi, struct+FFI mi" kararının kaydı olarak kalır. + +--- + +### Açık Sorular +- "Şu anki zaman" gibi dış-dünya bağımlı bilgi nasıl elde edilir — bu doğrudan FFI seam'in (`print` sonrası) ikinci gerçek kullanım örneği olabilir mi? +- Tarih aritmetiği (`tarih + 5 gün`) operatör overload'ı gerektirir mi — ama dilde operatör overload yok (kilitli karar); bu çatışmayı nasıl çözeriz (fonksiyon: `addDays(d, 5)`)? + +*İmza/Yorum:* Önerim: v0'da struct+FFI, native tip değil — "batteries boundary" ilkesinin ikinci somut test vakası.""" + }, + { + "title": "[Fikir] Enum (Sabit Kümesi) Desteği", + "labels": [L_FIKIR, L_TIP], + "body": """### Giriş (Nedir, Neden Önemli?) +Şu anki dil kimliğinde `enum` yok. Ama "renk", "durum", "yön" gibi sabit bir küme içinden değer alan değişkenler çok yaygındır ve bunları `int` ile temsil etmek (örn. `0=KIRMIZI, 1=MAVI`) hem hata-eğilimli hem de okunaksızdır. + +--- + +### Gelişme (Olası Yaklaşımlar) +- En basit model: `enum Renk { KIRMIZI, MAVI, YESIL }` — derleme zamanında `int`'e eşlenen adlandırılmış sabitler. Tip denetimi (Faz 3) açısından `Renk` ayrı bir `TypeKind` (ya da struct'a benzer adlandırılmış-tip) olarak ele alınabilir; `int`'le gizli dönüşüm yasak (ADR-010 ile tutarlı — `Renk x = 0;` yerine `Renk x = KIRMIZI;`). +- `switch`/`match` ile birlikte düşünülürse (dilde şu an `switch` yok, sadece `if`) enum'un asıl gücü ortaya çıkar — bu issue, ileride bir `switch` tartışmasını da tetikleyebilir. +- Struct'lara ek yük getirmez, sembol tablosuna (Faz 2) yeni bir `SymbolKind::EnumValue` eklenmesi yeterli olabilir. + +--- + +### Açık Sorular +- Enum değerleri sadece `int` mi temsil eder, yoksa ileride `string` etiketli enum (örn. JSON serileştirmede yararlı) da düşünülür mü? +- `interface` gibi enum da "ertelendi" listesine mi girer, yoksa v0.1'e (fibonacci sonrası ilk gerçek dil-genişletmesi) yakın bir öncelik mi? + +*İmza/Yorum:* Düşük karmaşıklıkta, yüksek günlük-kullanım faydası olan bir özellik — "fibonacci sonrası ilk küçük kazanımlar" listesine iyi bir aday.""" + }, + { + "title": "[Fikir] String'in İç Temsili ve Unicode/UTF-8 Stratejisi", + "labels": [L_FIKIR, L_TIP], + "body": """### Giriş (Nedir, Neden Önemli?) +`string` tipi dil kimliğinde var ama "string nedir" sorusu (bayt dizisi mi, karakter dizisi mi, UTF-8 mi) henüz hiç tartışılmadı. Bu karar, `length()`, indeksleme (`s[0]`), ve dosya/konsol I/O'sunun davranışını doğrudan belirler. + +--- + +### Gelişme (Olası Yaklaşımlar) +- **UTF-8 bayt dizisi (Go/Rust tarzı):** En basit runtime temsili (host C++ `std::string`'e doğrudan eşlenir, ADR-015 "host heap" ilkesiyle uyumlu). Ama `s[0]` bir bayt döner, bir "karakter" değil — Türkçe karakterler (ç, ş, ğ) çok-baytlı olduğundan indeksleme kafa karıştırabilir. +- **Kod-noktası (code point) dizisi:** Her "karakter" tek birim — daha sezgisel ama dönüşüm/depolama maliyeti var. +- v0 önerisi: UTF-8 bayt temsilini benimse (C++'la doğal uyum), ama `length()`/indeksleme dokümantasyonunda "bayt sayısı/bayt indeksi" olduğu açıkça yazılsın — ileride `runeAt()`/`codepointLength()` gibi yardımcı builtin'lerle (ADR-016/017) kod-noktası erişimi sağlanabilir. + +--- + +### Açık Sorular +- String **immutable (değişmez)** mi olacak (Java/Python tarzı, value-semantics ile de uyumlu) yoksa mutable mi? +- String birleştirme (`+`) ve karşılaştırma operatörleri tip denetiminde (Faz 3) nasıl ele alınacak — `string + int` gizli dönüşüm mü (ADR-010 "gizli dönüşüm yok" ile çatışır, muhtemelen `E003`)? + +*İmza/Yorum:* Bu karar ne kadar erken alınırsa, sonraki tüm builtin/stdlib tasarımı (özellikle JSON/XML parser örnekleri, ADR-017) o kadar sağlam temellenir.""" + }, + # ---------------- FFI / Builtin / Stdlib ---------------- + { + "title": "[Fikir] FFI Seam Detaylı Tasarımı — `callhost` İmzası ve Tip Eşleme (Marshaling)", + "labels": [L_FIKIR, L_FFI], + "body": """### Giriş (Nedir, Neden Önemli?) +ADR-016, "host fonksiyonu çağır" (FFI — Foreign Function Interface, Yabancı Fonksiyon Arayüzü) mekanizmasının **kasıtlı** bir tasarım kararı olduğunu, `print`'in ilk müşterisi olacağını söylüyor. Ama mekanizmanın somut hali (fonksiyon imzası, parametre/dönüş tipi eşlemesi) henüz tasarlanmadı. + +--- + +### Gelişme (Olası Yaklaşımlar) +- VM'de bir `callhost ` IR/bytecode komutu: argümanlar yığından alınır, C++ tarafındaki kayıtlı bir fonksiyon tablosuna (`std::map`) bakılır, sonuç yığına geri konur. +- Tip eşleme: saQut `int`/`float`/`string`/`bool` değerleri C++ `int`/`double`/`std::string`/`bool`'a nasıl çevrilir (marshaling) — basit primitiflerle başlamak ("önce dikey dilim"), struct/array marshaling'i ileri bir adım olarak bırakmak. +- Hata yönetimi: host fonksiyon başarısız olursa (örn. dosya bulunamadı) bu, saQut tarafına nasıl yansır — bir hata kodu mu, yoksa `panic` benzeri bir çalışma-zamanı hatası mı (yeni runtime hata kategorisi gerekebilir)? + +--- + +### Açık Sorular +- Host fonksiyon tablosu derleme zamanında mı sabit (yalnızca derleyicinin sunduğu `print` gibi fonksiyonlar), yoksa kullanıcı kendi C++ fonksiyonunu kayıt edebilir mi (gömülü/embeddable derleyici senaryosu — "alet çantası" ruhuna çok uygun ama kapsam büyütür)? +- `callhost` IR seviyesinde mi, yoksa daha yüksek seviyeli bir AST-annotation mı (Faz 1'in `ExpressionNode` alanlarına eklenebilir)? + +*İmza/Yorum:* `print(fibonacci(n))` çalıştığı gün, bu issue'nun "v0" kapsamı fiilen tamamlanmış olacak — minimal hedef gayet net.""" + }, + { + "title": "[Fikir] Builtin Fonksiyon Kataloğu ve Çözümleme Mekanizması", + "labels": [L_FIKIR, L_FFI], + "body": """### Giriş (Nedir, Neden Önemli?) +`print` ilk builtin (yerleşik) fonksiyon. Ama "builtin" kelimesinin derleyici içinde nasıl bir yeri olacağı — sembol tablosunda mı, ayrı bir kayıt defterinde mi — henüz netleşmedi. Bu issue, `print`'ten sonra gelecek `len`, `toString`, `parseInt` gibi fonksiyonların **sistematik** bir şekilde eklenmesini planlar. + +--- + +### Gelişme (Olası Yaklaşımlar) +- Faz 2'nin Symbol Table'ı (sembol tablosu) başlangıçta "önceden tanımlı" (pre-defined) bir global scope ile kurulabilir — her builtin, kullanıcı kodu hiç okunmadan önce bu scope'a `SymbolKind::Function` olarak eklenir. Böylece `print(x)` çağrısı normal bir fonksiyon çağrısı gibi tip denetiminden (Faz 3) geçer. +- Builtin kataloğu merkezi bir dosyada (`src/runtime/builtins.hpp` gibi) tek listede tutulur: isim, parametre tipleri, dönüş tipi, ve VM'deki karşılığı (FFI üzerinden mi, yoksa doğrudan bir IR opcode'u mu). +- İlk aday liste (fibonacci sonrası "küçük kazanımlar"): `print`, `len` (string/array uzunluğu), `toString` (sayıdan string'e), `parseInt`/`parseFloat`. + +--- + +### Açık Sorular +- Builtin'ler kullanıcı tarafından **gölgelenebilir (shadow)** mi — yani kullanıcı kendi `print` fonksiyonunu tanımlarsa ne olur (muhtemelen `E002` çift tanım, ama global scope'ta builtin'lerle çakışma ayrı ele alınmalı)? +- Builtin kataloğu büyüdükçe (örn. 50+ fonksiyon), bunların hepsi "her zaman yüklü" mü olacak, yoksa modül sistemi (ayrı issue) ile "import edilen" bir stdlib mantığına mı evrilecek? + +*İmza/Yorum:* `print`'in nasıl çözümlendiğini doğru kurmak, sonraki tüm builtin'lerin şablonu olacak — bu yüzden bu issue erken (Faz 2-3 sırasında) gündeme gelmeli.""" + }, + { + "title": "[Fikir] Minimal Stdlib Seti (String/Math/Koleksiyon Yardımcıları)", + "labels": [L_FIKIR, L_FFI], + "body": """### Giriş (Nedir, Neden Önemli?) +ADR-017 "batteries = sınır problemi" diyor ve JSON/XML/HTML gibi parser'ların saQut'un kendisinde yazılabileceğini söylüyor. Ama bunlar için bile bir **minimal temel** (string birleştirme, karşılaştırma, sayı↔string dönüşümleri, dizi üzerinde gezinme yardımcıları) gerekir. Bu issue, "demo programları yazılabilir olması için gereken en küçük stdlib" kümesini tanımlar. + +--- + +### Gelişme (Olası Yaklaşımlar) +- **String:** `length(s)`, `substring(s, start, end)`, `charAt(s, i)`, `concat(a, b)` (veya `+` operatörü), `equals(a, b)`. +- **Sayı:** `toString(n)`, `parseInt(s)`, `parseFloat(s)`, `abs`, `min`, `max`. +- **Array:** `length(arr)`, belki `append`/`push` (dinamik array tartışmasına bağlı — ayrı issue). +- Hepsi builtin kataloğu (önceki issue) üzerinden, ya doğrudan IR opcode'u ya da FFI (`callhost`) ile saç host C++ standart kütüphanesine (``, ``) yaslanır — "asla elle yeniden yazma" (ADR-017, kripto örneğiyle aynı ilke string/math için de geçerli). + +--- + +### Açık Sorular +- Bu set "derleyiciye gömülü" mü olmalı (her zaman hazır) yoksa ileride bir "standart modül" (`import std`) olarak mı paketlenmeli — import sistemi (ayrı issue) ile zamanlama ilişkisi var. +- JSON parser demo'su (ADR-017'de bahsedilen) için bu listenin yeterli olup olmadığı, demo yazılmaya başlandığında netleşecek. + +*İmza/Yorum:* "Fibonacci çalıştı" milestone'undan sonraki ikinci somut hedef belki de "stdlib ile küçük bir JSON parser demo'su" olabilir — bu issue o hedefin ön koşullarını listeliyor.""" + }, + # ---------------- Tooling: LSP / Syntax Highlighting ---------------- + { + "title": "[Fikir] LSP (Language Server Protocol) Sunucusu Mimarisi", + "labels": [L_FIKIR, L_TOOLING], + "body": """### Giriş (Nedir, Neden Önemli?) +**LSP (Language Server Protocol, Dil Sunucusu Protokolü)**, editörlerin (VS Code, Neovim vb.) "kırmızı çizgi göster", "tanıma git", "otomatik tamamla" gibi özellikleri standart bir protokolle derleyiciden alabilmesini sağlar. saQut'un "incelenebilir derleyici" felsefesi, LSP için aslında olağanüstü bir başlangıç noktası: AST, sembol tablosu ve diagnostic'ler zaten JSON olarak dışa açık. + +--- + +### Gelişme (Olası Yaklaşımlar) +- LSP sunucusu, saQut derleyicisinin **üstüne** yazılan ayrı bir süreç (process) olabilir — derleyici çekirdeğini bir kütüphane (library) olarak kullanır, stdin/stdout üzerinden JSON-RPC (LSP'nin temel protokolü) ile editörle konuşur. +- En kritik performans sorunu: editördeki her tuş vuruşunda **tüm dosyayı yeniden derlemek** pahalıdır. "Incremental parsing" (artımlı ayrıştırma) veya en azından "değişen fonksiyonu yeniden derle" gibi bir strateji gerekir — ama bu, v0'ın çok ilerisinde bir konu. +- "Önce dikey dilim": LSP'nin ilk versiyonu sadece `DiagnosticEngine`'in (Faz 0) çıktısını "hover/error squiggle" olarak göstermekle başlayabilir — tüm dosyayı her kaydette yeniden derlemek v0 için yeterli olabilir. + +--- + +### Açık Sorular +- LSP sunucusu aynı C++ binary'sinin bir modu mu (`saqut lsp`) olacak, yoksa tamamen ayrı bir proje mi? +- "Tanıma git" (go-to-definition) özelliği doğrudan Faz 2'nin Symbol Table'ındaki `definitionLoc`/`references` alanlarından besleniyor — bu alanların LSP ihtiyaçlarına göre yeterli olup olmadığı (örn. cross-file references, modül sistemi geldiğinde) kontrol edilmeli. + +*İmza/Yorum:* "Derleyici tamamlandıktan sonra" diye düşünülecek bir konu ama Faz 2'nin sembol tablosu tasarımı şimdiden bunu destekleyecek şekilde (her referansın konumu kayıtlı) kurulursa, LSP'ye geçiş çok daha az acı verir.""" + }, + { + "title": "[Fikir] Syntax Highlighting (Sözdizimi Renklendirme) Grameri", + "labels": [L_FIKIR, L_TOOLING], + "body": """### Giriş (Nedir, Neden Önemli?) +Editörlerde `.sqt` dosyalarının renkli görünmesi (anahtar kelimeler, string'ler, yorumlar farklı renkte) geliştirici deneyiminin en temel parçalarından biri — ve LSP'den bağımsız, çok daha basit bir kazanım. + +--- + +### Gelişme (Olası Yaklaşımlar) +- **TextMate grameri** (VS Code'un kullandığı, regex-tabanlı `.tmLanguage.json`): saQut'un tokenizer'ındaki (Tokenizer) 6 token tipinden (`docs` belgelerine göre) yola çıkarak basit bir regex seti yazılabilir — derleyiciden bağımsız, statik bir dosya. +- **Tree-sitter grameri:** Daha güçlü (gerçek bir parser üretir, hata-toleranslı), ama saQut'un kendi Pratt parser'ından ayrı bir gramer tanımı gerektirir — bakım yükü iki ayrı "dil tanımı" demektir. +- v0 önerisi: TextMate grameri (en düşük efor, en hızlı görsel kazanım) — `saqut tokens` çıktısı referans alınarak anahtar kelimeler/operatörler/literal'ler renklendirilir. + +--- + +### Açık Sorular +- Bu gramer, tokenizer'daki token tanımları değiştiğinde **elle senkronize** mi tutulacak, yoksa `saqut tokens --dump-grammar` gibi bir komutla **otomatik üretilebilir** mi (programlanabilir derleyici felsefesiyle çok uyumlu bir fikir)? +- Hedef editör önceliği ne olacak — VS Code (TextMate) mı, Neovim/Helix (Tree-sitter ekosistemi daha güçlü) mı? + +*İmza/Yorum:* Bu, listedeki **en düşük efor / en yüksek "keyif" oranına** sahip issue'lardan biri — derleyici bitmeden bile, sadece tokenizer çıktısından üretilebilir.""" + }, + { + "title": "[Fikir] `saqut fmt` — Otomatik Kod Biçimlendirici (Formatter)", + "labels": [L_FIKIR, L_TOOLING], + "body": """### Giriş (Nedir, Neden Önemli?) +`gofmt`, `rustfmt`, `prettier` gibi araçlar artık modern bir dilin "olmazsa olmaz"ı haline geldi: kod her zaman aynı şekilde biçimlenir, "stil tartışmaları" ortadan kalkar. saQut'un AST'si zaten JSON'a serileştirilebiliyor — bu, bir formatter için iyi bir temel. + +--- + +### Gelişme (Olası Yaklaşımlar) +- `saqut fmt file:kaynak.sqt`: dosyayı ayrıştırır (AST), AST'yi **kanonik bir şekilde** tekrar kaynak koda yazdırır (pretty-printer / AST → metin). +- Yorumların (comment) korunması en zor kısım — AST yorum bilgisini taşımıyorsa (Faz 0-1 sırasında bu netleşmeli), formatter yorumları silebilir veya yanlış yere koyabilir. Bu, **AST tasarımına şimdiden not edilmesi gereken bir kısıt.** +- "Öncesi/sonrası" felsefesiyle: `saqut fmt --check` (CI'da kullanılabilir — "bu dosya zaten formatlı mı?") ve `saqut fmt --write` (dosyayı yerinde değiştir) ayrımı yapılabilir. + +--- + +### Açık Sorular +- Pretty-printer, AST'den mi yoksa doğrudan token akışından mı (yorumlar dahil tüm token'lar tokenizer'da zaten tutuluyor) üretilmeli — token-tabanlı yaklaşım yorum-koruma sorununu çözebilir. +- Biçimlendirme kuralları (girinti, boşluk, satır uzunluğu) nasıl ve nerede sabitlenecek — `docs/` altında bir "stil kılavuzu" mu yazılacak? + +*İmza/Yorum:* AST tasarımı (Faz 1) sırasında "yorumlar AST'de nasıl temsil edilir" sorusu bu issue'yu doğrudan etkiler — şimdiden not düşülmeye değer bir bağımlılık.""" + }, + # ---------------- Gelecek Vizyonu / Deneysel ---------------- + { + "title": "[Fikir] Zaman-Yolculuğu Hata Ayıklama (Time-Travel Debugging) — IR Anlık Görüntüleri", + "labels": [L_FIKIR, L_VIZYON], + "body": """### Giriş (Nedir, Neden Önemli?) +saQut'un "her aşama incelenebilir" felsefesi VM çalışma zamanına da taşınabilir: VM her IR komutunu çalıştırdığında **tüm değişken/yığın durumunun anlık görüntüsünü (snapshot)** kaydederse, kullanıcı programı "ileri-geri sarabilir" — modern debugger'larda (rr, Chrome DevTools "time travel") popüler ama çoğu küçük dilde olmayan bir özellik. + +--- + +### Gelişme (Olası Yaklaşımlar) +- VM'in yorumlayıcı döngüsüne (ilgili issue) bir "trace modu" eklenir: her adımda (komut, önceki durum, sonraki durum) bir listeye/dosyaya yazılır. +- `saqut run file --trace=trace.json` → `saqut replay trace.json` gibi bir akış: kullanıcı adım adım ileri/geri gidebilir, herhangi bir adımdaki değişken değerlerini görebilir. +- Bellek modeli basit olduğu için (host heap, özel allocator yok — ADR-015) snapshot almak büyük bir teknik engel değil; asıl maliyet disk/bellek kullanımıdır (büyük döngülerde trace çok büyüyebilir — örnekleme/limit gerekebilir). + +--- + +### Açık Sorular +- Trace formatı IR serileştirmesiyle (ilgili issue) aynı JSON şemasını mı paylaşmalı? +- Bu özellik "VM v1"in parçası mı, yoksa tamamen ayrı bir "saqut debug" aracı mı? + +*İmza/Yorum:* Bu, "alet çantası" felsefesinin VM çalışma zamanına en doğal uzantısı — diğer küçük dillerde nadiren bulunan, saQut'u **ayırt edici** kılabilecek bir özellik.""" + }, + { + "title": "[Fikir] Derleyici Playground — WebAssembly'e Derleyip Tarayıcıda Çalıştırma", + "labels": [L_FIKIR, L_VIZYON], + "body": """### Giriş (Nedir, Neden Önemli?) +Rust/Go/TypeScript gibi dillerin "playground" siteleri (tarayıcıda kod yaz, çalıştır, AST/derleme adımlarını gör) hem öğretim hem de tanıtım için çok güçlü bir araç. saQut'un C++ çekirdeği **WebAssembly (Wasm)**'a derlenebilirse (Emscripten ile), tüm derleyici tarayıcıda çalışabilir — sunucu gerekmez. + +--- + +### Gelişme (Olası Yaklaşımlar) +- Emscripten ile `saqut` binary'si bir `.wasm` + JS "glue" koduna derlenir. Web sayfası bu Wasm modülünü yükler, kullanıcı kodunu derleyiciye verir. +- saQut'un CLI komutları (`tokens`, `ast`, `symbols`, ileride `ir`, `run`) zaten JSON döndürdüğü için, web arayüzü bu JSON'ları görselleştirir — örneğin AST'yi bir ağaç diyagramı olarak çizmek. +- "Önce dikey dilim, sonra çerçeve" ilkesiyle: bu issue, derleyicinin **kendisi** tamamlanmadan ele alınmaması gereken, ama CMake yapılandırmasına (ADR-003, header-only) Wasm hedefinin **erkenden uyumlu** olup olmadığının kontrol edilmesi gereken bir konudur. + +--- + +### Açık Sorular +- Wasm derlemesi CI'a (varsa) eklenir mi — "her commit'te playground güncel" gibi bir otomasyon hedefi olur mu? +- Playground sadece görüntüleme mi yapar, yoksa `saqut run` ile gerçek **çalıştırma** da (VM tamamlandıktan sonra) tarayıcıda mümkün olur mu? + +*İmza/Yorum:* "Keyif veren" kategorisinin tipik örneği — teknik olarak büyük bir engel yok (C++ → Wasm olgun bir yol), ama önceliği derleyici çekirdeğinden sonra gelmeli.""" + }, + { + "title": "[Fikir] Dil-İçi Test Bloğu (`test { }`) ve Yerleşik Test Çalıştırıcı", + "labels": [L_FIKIR, L_VIZYON], + "body": """### Giriş (Nedir, Neden Önemli?) +Rust'ın `#[test]` ve Go'nun `_test.go` dosyaları gibi, modern diller test yazmayı dilin/araç zincirinin **bir parçası** haline getiriyor. saQut için de "fonksiyonumu yazdım, hemen yanına küçük bir test ekleyeyim" akışı düşünülebilir — derleyicinin kendi `examples/fibonacci.sqt` gibi referans programlarını doğrulaması için bile yararlı olur. + +--- + +### Gelişme (Olası Yaklaşımlar) +- Sözdizimi fikri: `test "fibonacci(5) dogru sonucu verir" { assert(fibonacci(5) == 5); }` — `test` ve `assert` yeni anahtar kelimeler/builtin'ler olarak eklenir. +- `saqut test file:kaynak.sqt`: dosyadaki tüm `test` bloklarını çalıştırır, `assert` başarısız olursa hangi test/satır olduğunu raporlar (DiagnosticEngine'in bir "test sonucu" varyantı gibi düşünülebilir). +- Bu özellik aslında `assert` builtin'i (FFI/builtin kataloğu issue'suyla ilişkili) + basit bir "bu bloğu normal akıştan ayrı çalıştır" kuralı kadar küçük olabilir — büyük bir çerçeveye gerek yok. + +--- + +### Açık Sorular +- `test` blokları normal derlemede (`saqut run`) tamamen yok sayılır mı (production kodundan ayrışma), yoksa özel bir bayrakla mı dahil edilir? +- Bu, dilin **sözdizimine** mi (yeni anahtar kelime) yoksa sadece bir **kütüphane fonksiyonu** (`assert(...)` + isim kuralına dayalı dosya/fonksiyon tarama) düzeyinde mi kalmalı — ikincisi dil kimliğini (kilitli kararlar) bozmaz. + +*İmza/Yorum:* "Günümüzde frameworklerde olan ama derleyiciye gömülü gelebilecek" taleplere iyi bir örnek — minimal versiyonu (`assert` builtin'i) çok düşük maliyetli.""" + }, + { + "title": "[Fikir] Paket Yöneticisi / Modül Kayıt Defteri (Registry) Vizyonu", + "labels": [L_FIKIR, L_VIZYON], + "body": """### Giriş (Nedir, Neden Önemli?) +Modül sistemi (ayrı issue) "aynı projede birden fazla dosya" sorusunu çözer. Ama "başka birinin yazdığı bir saQut kütüphanesini projeme nasıl eklerim" sorusu bir **paket yöneticisi** gerektirir (npm, cargo, go modules tarzı). Bu, şu an çok uzak bir vizyon ama erken not edilmeye değer. + +--- + +### Gelişme (Olası Yaklaşımlar) +- En minimal hali: `import "https://git.saqut.com/.../util.sqt"` gibi URL-tabanlı import (Go'nun ilk modül modeline benzer) — merkezi bir registry gerektirmez, ADR-017'deki "FFI/kütüphane sınırı" felsefesiyle uyumlu (saQut çekirdeği paket yönetimini bilmez, sadece dosya/URL okur). +- Daha "gerçek" hali: `saqut.toml` gibi bir manifest dosyası, bağımlılık sürümleri, kilit dosyası (lock file) — bu, derleyici çekirdeğinden tamamen ayrı bir CLI aracı (`saqut-pkg`) olarak düşünülebilir, çekirdeği şişirmez. +- saQut'un "alet çantası" kimliği burada bir fırsat sunuyor: paket yöneticisi, saQut'un kendisiyle yazılabilecek bir **dogfooding** (kendi aracını kendi diliyle yazma) projesi olabilir — ama bu, dilin dosya I/O ve string işleme (stdlib issue'ları) yeterince olgunlaştıktan sonra mümkün. + +--- + +### Açık Sorular +- Bu vizyon, projenin "küçük/incelenebilir alet çantası" kimliğiyle ne kadar uyumlu — paket ekosistemi büyüdükçe "monolit korkusu" (ADR-017) geri gelir mi? +- Merkezi bir registry (sunucu, hosting maliyeti) gerçekten gerekli mi, yoksa Git-tabanlı/URL-tabanlı dağıtık model yeterli mi? + +*İmza/Yorum:* En "uzak gelecek" issue'lardan biri — ama "import sistemi" tasarlanırken (örn. URL desteği baştan düşünülürse mi, sonradan mı eklenir) bu vizyonun gölgesi düşebilir, o yüzden şimdiden not.""" + }, + { + "title": "[Fikir] Akıllı Diagnostic — Hata Mesajlarına \"Neden\" ve \"Nasıl Düzeltilir\" Ekleme", + "labels": [L_FIKIR, L_VIZYON], + "body": """### Giriş (Nedir, Neden Önemli?) +Faz 0'ın `Diagnostic` yapısında zaten bir `hint` (ipucu) alanı planlanıyor. Bu issue, o alanın **nasıl** dolduğunu ve modern derleyicilerin (Rust, Elm) "hata mesajı bir öğretmen gibi konuşur" felsefesini saQut'a nasıl taşıyabileceğimizi tartışır — yapay zeka kullanmadan, tamamen kural-tabanlı (rule-based). + +--- + +### Gelişme (Olası Yaklaşımlar) +- Her hata kodu (`E001`...`E010`) için, hata mesajına ek olarak **statik bir "neden" şablonu** ve mümkünse **"şunu dener misin"** önerisi eklenir. Örnek: `E003` (tip uyuşmazlığı) → "saQut'ta değişkenler arası gizli dönüşüm yapılmaz (bkz. ADR-010); `int` bir değeri `float` değişkene atamak için ... yapabilirsiniz." +- Bu şablonlar `docs/adr-frontend-analiz.md`'deki kararlarla **doğrudan bağlantılı** olabilir — hata mesajı, ilgili ADR'nin "neden"ini özetleyen bir cümle içerebilir. Bu, dökümantasyon ile derleyici çıktısını birbirine bağlar (saQut'un "her şey ilişkili ve incelenebilir" ruhuna uygun). +- Elm tarzı "did you mean...?" (yazım hatası önerisi): tanımsız isim hatasında (`E001`), sembol tablosundaki (Faz 2) benzer isimli sembollere Levenshtein-mesafesi gibi basit bir algoritmla öneri sunulabilir — küçük, eğlenceli, yüksek-etkili bir özellik. + +--- + +### Açık Sorular +- Bu zenginleştirilmiş mesajlar `DiagnosticEngine`'in (Faz 0) temel yapısına mı gömülür, yoksa ayrı bir "mesaj kataloğu" dosyası mı olur (çeviri/yerelleştirme ihtimaline de açık kapı bırakır)? +- "Did you mean" önerisi performans maliyeti yaratır mı (her hata için sembol tablosu taraması) — büyük projelerde sorun olur mu? + +*İmza/Yorum:* Bu, derleyicinin "kullanıcıyla konuşma tarzını" belirleyen, teknik olarak küçük ama **algıyı** çok değiştirebilecek bir issue — Faz 0 bittiğinde, kataloğa hint şablonları eklemek ucuz bir ek iştir.""" + }, +] + +for issue in issues_data: + endpoint = f"{REPO_PATH}/issues" + res = make_request(endpoint, method="POST", data=issue) + print(f"Created issue #{res['number']}: {res['title']}") diff --git a/scripts/create_issues.py b/scripts/create_issues.py new file mode 100644 index 0000000..6d4aa98 --- /dev/null +++ b/scripts/create_issues.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python3 +import sys +from gitea import make_request, REPO_PATH + +issues_data = [ + { + "title": "Faz 0 — Tip Sistemi ve Hata Kayıt Motoru (Type & Diagnostics)", + "body": """### Giriş (Nedir, Neden Yapıyoruz?) +Bu iş paketinde derleyicinin çalışması için en temel iki altyapıyı kuracağız: Tip Sistemi (Type System) ve Hata Kayıt/Diagnostic Motoru. +Tip Sistemi, derleyicinin kaynak koddaki verileri (sayılar, metinler vb.) anlamlandırabilmesi ve tür doğruluğunu denetleyebilmesi için gerekli veri yapısını sağlar. +Hata Kayıt Motoru ise derleme sırasında oluşan hataları (örneğin tip uyuşmazlığı veya tanımsız değişken kullanımı) biriktirip, kullanıcıya hatanın kaynak koddaki tam yerini (dosya, satır, sütun koordinatları) göstererek raporlayan mekanizmadır. Bu yapı sayesinde derleyici ilk bulduğu hatada hemen durmayacak, tüm hataları toplayıp tek seferde kullanıcıya sunacaktır. + +--- + +### Gelişme (Neyi, Nerede ve Nasıl Yapacaksın?) +Aşağıdaki adımları sırasıyla gerçekleştir: +1. **Tip Yapısı:** `src/core/type.hpp` adında yeni bir dosya oluştur. Burada `TypeKind` (Primitive, Array, Struct, Function, Error) enum sınıfını ve `Type` sınıfını tanımla. Primitif türler için `int`, `float`, `double`, `char`, `string`, `bool`, `void` alt tiplerini destekle. Dizi (Array) türü için eleman tipini (`elementType`), fonksiyon için dönüş ve parametre tiplerini taşıyacak alanlar ekle. `equals()` ve `toString()` gibi metotları implement et. +2. **Hata Yapısı:** `src/diagnostic/diagnostic.hpp` dosyasını oluştur. Burada hata seviyelerini (`Error`, `Warning`, `Note`, `Hint`) içeren `DiagLevel` enum sınıfını ve hatanın koordinatlarını tutan `Diagnostic` yapısını tanımla. +3. **Diagnostic Kataloğu:** Aynı dosyada derleyicide oluşabilecek hata kodlarını içeren kataloğu (örneğin `E001` - Tanımsız Değişken, `E002` - Çift Tanım, `E003` - Tip Uyuşmazlığı, `E010` - Döngüsel Struct Tanımı vb.) sabitle. +4. **DiagnosticEngine:** `src/diagnostic/diagnostic_engine.hpp` dosyasını oluştur. `DiagnosticEngine` sınıfı hataları bir vektörde biriktirmeli, `report()` metoduyla yeni hata almalı ve `printAll()` ile bunları ekrana formatlı yazmalıdır. + +*Geliştirme Dalı (Branch):* `feature/faz0-temeller` + +--- + +### Sonuç ve Başarı Kriterleri +Bu işin bittiğini ve başarılı olduğunu şu kriterlerle doğrulayacağız: +1. `Type::equals()` metodu için yazılan birim testler (Unit Tests) farklı tip kombinasyonlarını (örneğin `int` ile `int` eşit, `int` ile `float` veya `int[]` farklı) hatasız doğrulamalıdır. +2. `DiagnosticEngine` sınıfına 3 farklı hata raporlanıp `printAll()` çağrıldığında, çıktıda hata kodları (`E001` vb.) ve kaynak kod satır/sütun koordinatları doğru sırayla ve biçimde ekrana yazılmalıdır. +3. Derleyici uyarısız (`-Wall -Wextra`) derlenmelidir. + +*Mühendis Olmayanlar İçin Analiz:* Bu aşama derleyicinin arka planındaki veri yapılarını kurduğu için görsel bir çıktı üretmez, ancak sonraki tüm aşamaların temelidir. Karmaşıklığı **Düşük**, yapım süresi yaklaşık **1-2 gün**dür. +*İmza/Yorum:* Bu altyapı semantik analizin (Faz 3) hata raporlayabilmesi için kritik önkoşuldur.""" + }, + { + "title": "Faz 1 — AST Hiyerarşisinin Refaktörü (Expression ve Statement Ayrımı)", + "body": """### Giriş (Nedir, Neden Yapıyoruz?) +Bu iş paketinde, derleyicinin kaynak kodu okuduktan sonra hafızada oluşturduğu Soyut Sözdizimi Ağacı (Abstract Syntax Tree - AST) düğümlerini yeniden yapılandıracağız. +Şu anda tüm AST düğümleri tek bir `ASTNode` taban sınıfından türemektedir. Ancak anlamsal olarak iki farklı düğüm türü vardır: +1. **Expression (İfade):** Bir değer üreten yapılar (örneğin `5 + 3` veya değişken isimleri). Bunların bir veri tipi (Type) olur. +2. **Statement (Deyim):** Bir değer üretmeyen, sadece bir iş/eylem yürüten kontrol yapıları (örneğin `if` bloğu, döngüler veya `return`). Bunların tipi yoktur ancak erişilebilirlik (reachability) durumları analiz edilir. +Bu iki yapıyı birbirinden ayırmak, sonraki aşamada tip denetimi yapabilmemiz için zorunludur. + +--- + +### Gelişme (Neyi, Nerede ve Nasıl Yapacaksın?) +Aşağıdaki adımları sırasıyla gerçekleştir: +1. **Ara Taban Sınıflarını Ekle:** `src/parser/ast_node.hpp` dosyasına `ExpressionNode` ve `StatementNode` adında iki yeni sınıf ekle. `ExpressionNode` sınıfına `resolvedType` (çözümlenmiş tip), `isConstant` ve `foldedValue` (optimizasyon için) alanlarını koy. `StatementNode` sınıfına ise `isReachable` (erişilebilirlik bayrağı) alanını ekle. +2. **Düğümleri Güncelle:** `src/parser/nodes/` dizinindeki tüm dosyaları tara. `LiteralNode`, `BinaryExpressionNode`, `IdentifierNode`, `CallExpressionNode` gibi değer üreten tüm sınıfları `ExpressionNode`'dan türet. `IfStatementNode`, `WhileStatementNode`, `ReturnStatementNode` vb. sınıfları ise `StatementNode`'dan türet. +3. **Çocuk Gezintisini Düzelt:** AST taban sınıfındaki `getChildren()` metodunun alt sınıflar tarafından ezilmesini (override) sağla. Örneğin `BinaryExpressionNode` sınıfında `Left` ve `Right` düğümlerini dinamik olarak `getChildren()` içinde döndür. Bu, genel ağaç gezginlerinin (Tree Walker) alt düğümleri eksiksiz taramasını sağlayacaktır. +4. **toJson Modifikasyonu:** `toJson()` metotlarını güncelleyerek yeni alanları (çözümlenmiş tip ve erişilebilirlik bilgileri) JSON çıktısına ekle. + +*Geliştirme Dalı (Branch):* `feature/faz1-ast-refactor` + +--- + +### Sonuç ve Başarı Kriterleri +Bu işin bittiğini ve başarılı olduğunu şu kriterlerle doğrulayacağız: +1. `saqut ast examples/fibonacci.sqt` komutu çalıştırıldığında üretilen JSON çıktısında, ifadeler için `resolvedType` alanı (boş olarak) ve deyimler için `isReachable` alanı (true olarak) görünmelidir. +2. JSON yapısının doğruluğu `python3 -m json.tool` ile test edildiğinde hiçbir parse hatası vermebelidir (regresyon testi). +3. Tüm kodlar uyarısız derlenmelidir. + +*Mühendis Olmayanlar İçin Analiz:* Bu aşama mevcut veri yapısını daha düzenli hale getirir. Dışarıdan bakıldığında JSON çıktısında yeni alanlar görülür. Karmaşıklığı **Düşük-Orta**, yapım süresi yaklaşık **2 gün**dür. +*İmza/Yorum:* Düğüm alanlarındaki `children` vektörü tutarsızlığı bu fazda tamamen çözülmeli, ağaçta yukarı ve aşağı gezinme API'si garanti altına alınmalıdır.""" + }, + { + "title": "Faz 2 — Sembol Tablosu ve İki Geçişli Toplama (Scope & Symbol Table)", + "body": """### Giriş (Nedir, Neden Yapıyoruz?) +Bu iş paketinde derleyicinin \"Hafızası\" sayılan Sembol Tablosunu (Symbol Table) kuracağız. +Sembol Tablosu, kaynak koddaki değişkenlerin, fonksiyonların ve veri yapılarının (struct) tanımlarını, veri tiplerini, hangi kapsamlarda (Scope) geçerli olduklarını ve kodun neresinde kullanıldıklarını (referanslarını) takip eden bir veri yapısıdır. +Dilimiz, tanımlanmadan önce fonksiyon çağrılmasına izin verdiği için (ileri başvuru / forward-reference), sembolleri toplama işlemini iki geçişli bir algoritma ile yapmak zorundayız. + +--- + +### Gelişme (Neyi, Nerede ve Nasıl Yapacaksın?) +Aşağıdaki adımları sırasıyla gerçekleştir: +1. **Sembol ve Kapsam Yapıları:** `src/symbol/` adında yeni bir dizin aç. Burada `Symbol` yapısını tanımla (ad, tür, tip, tanım konumu, referans listesi alanları bulunsun). `Scope` sınıfını iç içe geçebilir ağaç yapısında yaz; her scope bir üst scope'a pointer tutsun. +2. **SymbolTable Yöneticisi:** `src/symbol/symbol_table.hpp` dosyasını oluştur. Scope yığınını yöneten `enterScope()`, `exitScope()`, sembol ekleyen `define()` (aynı scope'ta çift tanım varsa hata üret) ve içten dışa arayan `resolve()` metotlarını yaz. +3. **İki Geçişli Toplayıcı:** `src/symbol/symbol_collector.hpp` ve `.cpp` dosyalarını oluştur. + * **Geçiş 1 (Global Hoisting):** AST'yi tarayarak sadece üst seviye fonksiyon ve struct imzalarını global scope'a kaydet. + * **Geçiş 2 (Local Resolution):** Fonksiyon gövdelerine in. Lokal değişkenleri declare-before-use (kullanmadan önce tanımlama) kuralıyla topla ve Identifier (isim referansı) düğümlerini sembol tablosundaki sembollerle bağla. Global değişken başlatıcılarında declare-before-use kuralını zorunlu kıl. +4. **Döngüsel Struct Kontrolü:** Struct tanımları toplandıktan sonra, pointer olmadığı için birbirini değer olarak içeren döngüsel struct tanımlarını (örn. `struct A { B b; }` ve `struct B { A a; }`) DFS (Derinlik Öncelikli Arama) algoritmasıyla tespit et ve `E010` hatasını raporla. + +*Geliştirme Dalı (Branch):* `feature/faz2-symbols` + +--- + +### Sonuç ve Başarı Kriterleri +Bu işin bittiğini ve başarılı olduğunu şu kriterlerle doğrulayacağız: +1. `saqut symbols examples/fibonacci.sqt` komutu çalıştırıldığında, programdaki fonksiyonlar, parametreler ve lokal değişkenler doğru tipleri ve tüm kullanım koordinatlarıyla (satır/sütun referans listesi) ekrana yazılmalıdır. +2. Aynı isimde iki değişken tanımlandığında `E002` (Çift Tanım), tanımsız bir değişken çağrıldığında veya global başlatıcı sırasında ileri başvuru yapıldığında `E001` (Tanımsız İsim), döngüsel struct tanımlandığında ise `E010` hataları DiagnosticEngine tarafından raporlanmalı ve derleme durmalıdır. + +*Mühendis Olmayanlar İçin Analiz:* Derleyicinin değişken ve fonksiyon isimlerini anlamlandırmaya başladığı aşamadır. Hatalı kod yazıldığında derleyicinin verdiği akıllı uyarıların temelidir. Karmaşıklığı **Yüksek**, yapım süresi yaklaşık **4-5 gün**dür. +*İmza/Yorum:* Bu aşamada pointer ve scope yapıları çok hassas tasarlanmalıdır; bellek sızıntılarını önlemek için akıllı işaretçiler veya net sahiplik modelleri tercih edilmelidir.""" + }, + { + "title": "Faz 3 — Semantik Analiz ve Tip Denetimi (Type Checking)", + "body": """### Giriş (Nedir, Neden Yapıyoruz?) +Bu iş paketinde derleyicinin kurallarını işleten Semantik Analiz (Anlamsal Analiz) ve Tip Denetimi (Type Checking) motorunu yazacağız. +Sözdizimi (Syntax) doğru olan bir kod anlamsal olarak yanlış olabilir (örneğin `int x = \"merhaba\" + 5;` yazmak sözdizimsel olarak geçerlidir ancak mantıksızdır). +Tip Denetimi, ifadelerin veri tiplerinin uyumlu olup olmadığını kontrol eder. Ayrıca dilimizin \"otomatik tip dönüşümü yasaktır\" kuralını işletir. Yapısal doğrulama ise `break`/`continue` deyimlerinin döngü dışında kullanılmasını engeller. + +--- + +### Gelişme (Neyi, Nerede ve Nasıl Yapacaksın?) +Aşağıdaki adımları sırasıyla gerçekleştir: +1. **Tip Denetleyici:** `src/sema/type_checker.hpp` ve `.cpp` dosyalarını oluştur. AST'yi aşağıdan yukarıya (bottom-up) gezerek her `ExpressionNode` düğümünün tipini (`resolvedType`) belirle. +2. **Uyuşmazlık Kuralları:** Atama işlemlerinde (`=`), aritmetik operatörlerde ve fonksiyon çağrılarında tip uyumunu denetle. Gizli değişken-değişken dönüşümlerini yasakla (hata: `E003`). +3. **Literal Uyarlama Kuralı:** Sabit sayı literal'ları için bağlama göre tiplendirme kuralını işlet (Örn: `float x = 1;` geçerli olmalı çünkü `1` kayıpsızca float'a dönüşebilir, ancak `int y = 1.5;` `E003` hatası vermelidir). +4. **Error Tipi:** Bir ifade hatalıysa tipine `ErrorType` ata. Bu sayede, o ifadeyi kullanan üst ifadelerde tekrar tekrar sahte hatalar üretilmez. +5. **Yapısal Doğrulayıcı:** `src/sema/structural_validator.hpp` ve `.cpp` dosyalarını oluştur. Ağacı tırmanarak `break`/`continue` ifadelerinin üstünde bir döngü olup olmadığını (`E004`), `return` ifadesinin bir fonksiyon gövdesinde olup olmadığını (`E005` ve dönüş tipi uyumu için `E006`) denetle. + +*Geliştirme Dalı (Branch):* `feature/faz3-semantic-analysis` + +--- + +### Sonuç ve Başarı Kriterleri +Bu işin bittiğini ve başarılı olduğunu şu kriterlerle doğrulayacağız: +1. Geçerli olan `examples/fibonacci.sqt` dosyası semantik analizden sıfır hatayla geçmeli ve her AST ifadesinin tipi JSON çıktısında (`resolvedType`) görünmelidir. +2. Hatalı bir test dosyası verildiğinde (örneğin döngü dışında `break;` yazıldığında veya `int` değişkene `string` atandığında) derleyici ilgili hata kodlarını (`E003`, `E004` vb.) raporlamalı ve derleme süreci kesilmelidir. + +*Mühendis Olmayanlar İçin Analiz:* Bu aşama, derleyicinin yazılan kodun \"anlamlı\" olup olmadığını kontrol ettiği güvenlik kapısıdır. Karmaşıklığı **Orta-Yüksek**, yapım süresi yaklaşık **3-4 gün**dür. +*İmza/Yorum:* Sabit ifadelerde constant folding istisnasını unutmama kuralları burada işletilecektir.""" + }, + { + "title": "Faz 4 — Optimizasyon Altyapısı ve Kaynak Optimizasyonları (Optimization)", + "body": """### Giriş (Nedir, Neden Yapıyoruz?) +Bu iş paketinde derleyicinin ürettiği kodu daha verimli hale getiren Optimizasyon (Eniyileme) altyapısını ve ilk optimizasyon adımlarını (pass'leri) yazacağız. +Optimizasyon, yazılan kodun anlamını değiştirmeden daha hızlı çalışacak veya daha az yer kaplayacak şekilde dönüştürülmesidir. +saQut'un \"alet çantası\" felsefesi gereği, optimizasyon orijinal kaynak kod görüntüsünü bozmamalıdır. Bu nedenle optimizasyonlar AST'nin bir kopyası (klon) üzerinde gerçekleştirilir. + +--- + +### Gelişme (Neyi, Nerede ve Nasıl Yapacaksın?) +Aşağıdaki adımları sırasıyla gerçekleştir: +1. **Optimizasyon Yöneticisi:** `src/opt/` dizinini oluştur. Soyut `OptimizationPass` sınıfını tanımla. `OptimizationManager` sınıfını yaz; bu sınıf `CompilerConfig` üzerinden aktif edilen pass'leri sırayla çalıştırsın. +2. **Fixpoint Döngüsü:** Pass'lerin birbirini tetiklemesi için (örn. folding sonrası ölü kod oluşması) optimizasyonları bir fixpoint döngüsünde (hiçbir pass değişiklik yapmayana kadar) çalıştır. Monoton olmayan pass'lerin sonsuz döngüye girmemesi için sert bir tur sınırı (`maxFixpointRounds`) ekle. +3. **Ağaç Klonlama ve Remap:** `ASTNode::clone()` metodunu tüm AST düğümleri için yaz. Kopyalanan düğümlerin `parent` pointer'larını yeni ağaca göre bağla. Klonlanan ağaçtaki Identifier (isim referansı) düğümlerinin sembol tablosu bağlarını, klonlanmış yeni bir sembol tablosuna yönlendir (Remapping). +4. **Constant Folding Pass:** `src/opt/constant_folding.hpp` dosyasını oluştur. İki sabit terimin işlemini derleme zamanında hesapla (Örn: `1 + 2` → `3`). Sıfıra bölme varsa katlama yapma, `W002` uyarısı ver. +5. **Dead Code Elimination (DCE) Pass:** `src/opt/dead_code_elim.hpp` dosyasını oluştur. Erişilemez deyimleri (örn. `return` sonrası kodlar, `if(false)` gövdeleri) ve hiç kullanılmayan lokal değişkenleri (`W001`) sil. + +*Geliştirme Dalı (Branch):* `feature/faz4-optimization` + +--- + +### Sonuç ve Başarı Kriterleri +Bu işin bittiğini ve başarılı olduğunu şu kriterlerle doğrulayacağız: +1. `saqut ast examples/fibonacci.sqt --optimized` komutu çalıştırıldığında sabit ifadelerin katlandığı ve varsa ölü kodların silindiği doğrulanmalıdır. +2. `--optimized` bayrağı verilmeden çağrıldığında orijinal (optimize edilmemiş) AST çıktısı elde edilmelidir (Öncesi/Sonrası karşılaştırması). +3. Folding ve DCE işlemlerinin ardışık olarak birbirini beslediği (folding sonucu oluşan ölü kodun DCE tarafından temizlendiği) zincirleme senaryolar tek bir komutla doğrulanmalıdır. + +*Mühendis Olmayanlar İçin Analiz:* Yazdığınız programın gereksiz kısımlarını temizleyen akıllı temizlikçi aşamasıdır. Kodun boyutunu küçültür. Karmaşıklığı **Yüksek**, yapım süresi yaklaşık **4-5 gün**dür. +*İmza/Yorum:* `ASTNode::clone()` implementasyonu bu fazın en kritik ve hata yapmaya açık kısmıdır, parent pointer bağlarına azami dikkat gösterilmelidir.""" + } +] + +for issue in issues_data: + endpoint = f"{REPO_PATH}/issues" + res = make_request(endpoint, method="POST", data=issue) + print(f"Created issue #{res['number']}: {res['title']}") diff --git a/scripts/create_syntax_test_issues.py b/scripts/create_syntax_test_issues.py new file mode 100644 index 0000000..5984980 --- /dev/null +++ b/scripts/create_syntax_test_issues.py @@ -0,0 +1,499 @@ +#!/usr/bin/env python3 +"""Sozdizimi/davranis golden-test senaryolari + CLI/UX + kalite-mimari fikirleri. + +"[Test]" basliklilar: somut .sqt kodu + beklenen cikti/davranis iceren +golden-test taslaklaridir. Derleyici (Faz 0-4 + IR/VM) tamamlandiginda bu +dosyalar `examples/tests/` altina yerlestirilip regresyon testi olarak +kullanilabilir; ayni zamanda "syntax X soyle calismali" spesifikasyonudur - +calismiyorsa ilgili faz/pass'te bugfix konusu acar. + +"[Fikir]" basliklilar onceki script'lerle aynisekilde fikir/backlog kayitlaridir. +""" +from gitea import make_request, REPO_PATH + +L_FIKIR = 66 +L_TEST = 73 +L_CLIUX = 74 +L_KALITE = 75 + +issues_data = [ + # ---------------- Golden-test senaryolari ---------------- + { + "title": "[Test] Temel Aritmetik, Operatör Önceliği ve `print` Çıktısı", + "labels": [L_TEST], + "body": """### Giriş (Nedir, Neden Önemli?) +Bu issue, derleyicinin **en temel** davranışını sabitleyen bir golden-test taslağıdır: sayı literalleri, dört işlem, operatör önceliği (precedence) ve `print` builtin'i. "Fibonacci çalıştı" hedefinden önce bile bu örneğin doğru çalışması gerekir — Pratt parser'ın (zaten yapılı) önceliği doğru uyguladığının kanıtıdır. + +--- + +### Test Kodu (`examples/tests/aritmetik.sqt`) +```c +int main() { + print(1 + 2 * 3); // çarpma toplamadan önce + print((1 + 2) * 3); // parantez önceliği + print(10 - 4 - 3); // soldan-sağa birliktelik (left-assoc) + print(10 / 3); // tamsayı bölmesi (truncation) + print(10 % 3); // mod + print(2 + 3 * 4 - 6 / 2); + return 0; +} +``` + +### Beklenen Çıktı (`saqut run examples/tests/aritmetik.sqt`) +``` +7 +9 +3 +3 +1 +11 +``` + +--- + +### Açık Sorular / Bağlı Fazlar +- Bu test, `saqut run` (IR + VM, ADR-015) tamamlanmadan **AST** seviyesinde de kısmen doğrulanabilir: `saqut ast --optimized` ile constant folding (Faz 4) çalıştığında her `print` argümanı doğrudan tek bir `Literal` düğümüne katlanmalı (örn. `1 + 2 * 3` → `Literal(7)`). +- `10 / 3` → `3` (tamsayı bölmesi) davranışı tip denetiminde (Faz 3) açıkça test edilmeli; `int / int = int` (kayıp olabilir ama bu saQut'ta hata değil, sadece kesme/truncation — ADR-010'daki "kayıpsız literal" kuralından farklı bir konu, karıştırılmamalı). + +*İmza/Yorum:* Bu dosya, "derleyici bitti mi?" sorusuna verilecek **ilk** somut cevaplardan biri olmalı — `examples/fibonacci.sqt`'den önce, daha küçük bir adım.""" + }, + { + "title": "[Test] Döngüler — `while` / `do-while` / `for` Davranış Farkları", + "labels": [L_TEST], + "body": """### Giriş (Nedir, Neden Önemli?) +Üç döngü yapısının (`while`, `do-while`, `for`) **birbirinden farklı** davrandığı noktalar — özellikle `do-while`'ın gövdeyi **en az bir kez** çalıştırması — derleyicide kolayca karıştırılabilecek köşe durumlardır (edge case). Bu issue, bu farkları somut kodla sabitler. + +--- + +### Test Kodu 1 — Üç döngü de aynı sayıları üretmeli (`examples/tests/donguler_temel.sqt`) +```c +int main() { + int i = 0; + while (i < 3) { + print(i); + i = i + 1; + } + + int j = 0; + do { + print(j); + j = j + 1; + } while (j < 3); + + for (int k = 0; k < 3; k = k + 1) { + print(k); + } + return 0; +} +``` + +### Beklenen Çıktı +``` +0 +1 +2 +0 +1 +2 +0 +1 +2 +``` + +--- + +### Test Kodu 2 — `do-while` koşulu en baştan yanlışsa bile gövde bir kez çalışır (`examples/tests/do_while_en_az_bir.sqt`) +```c +int main() { + int x = 5; + do { + print(x); + x = x + 1; + } while (x < 0); // baştan yanlış! + return 0; +} +``` + +### Beklenen Çıktı +``` +5 +``` +(Eğer çıktı **boş** ise — yani `do-while`, `while` gibi davranıyorsa — bu bir **bug**'dır: `do-while`'ın AST düğümü/IR alçaltması `while` ile aynı koddan üretilmiş ve gövdeyi koşuldan **sonra** kontrol etmiyor olabilir.) + +--- + +### Açık Sorular / Bağlı Fazlar +- `for` döngüsünün üç parçası (`init; condition; step`) ayrı ayrı `AST` düğümlerinde mi tutuluyor, yoksa `while`'a "alçaltılıyor" (desugar) mu? İkinci durumda, `for (int k = 0; ...)` içindeki `k`'nın scope'u (sadece `for` bloğuna özel mi?) Faz 2'de doğru kurulmalı. +- `break`/`continue` (E004 ile ilişkili) bu üç döngü türünde de test edilmeli — ayrı bir test dosyası (`donguler_break_continue.sqt`) eklenebilir. + +*İmza/Yorum:* `do-while`/`while` karışıklığı, "derleyici neredeyse bitti ama syntax X yanlış davranıyor" tarzı klasik bug'lardandır — bu test erken yazılırsa erken yakalanır.""" + }, + { + "title": "[Test] Bit Düzeyi (Bitwise) İşlemler — `&`, `|`, `^`, `~`, `<<`, `>>`", + "labels": [L_TEST], + "body": """### Giriş (Nedir, Neden Önemli?) +Tokenizer'da `&`, `|`, `^`, `~`, `<<`, `>>` token'ları zaten tanımlı (`src/tokenizer/tokenizer.hpp`). Ama bu operatörlerin **Pratt parser'da doğru öncelik** ile ayrıştırıldığı ve **tip denetiminde** (Faz 3, sadece `int` üzerinde tanımlı) doğru ele alındığı henüz doğrulanmadı. Bu issue, "karmaşık bit işlemleri" için bir golden-test taslağıdır. + +--- + +### Test Kodu (`examples/tests/bit_islemleri.sqt`) +```c +int main() { + int a = 12; // 0b1100 + int b = 10; // 0b1010 + + print(a & b); // bitwise AND + print(a | b); // bitwise OR + print(a ^ b); // bitwise XOR + print(~a); // bitwise NOT (iki's complement) + print(a << 2); // sola kaydır + print(a >> 2); // sağa kaydır + + // Operatör önceliği: << ve >>, + ve - 'dan düşük öncelikli olmalı (C kuralı) + print(1 << 2 + 1); // (2+1)=3 -> 1 << 3 = 8, yoksa (1<<2)+1=5 olur + print(a & b | b); // & , | 'dan önce: (a&b) | b = 8 | 10 = 10 + return 0; +} +``` + +### Beklenen Çıktı +``` +8 +14 +6 +-13 +48 +3 +8 +10 +``` + +--- + +### Açık Sorular / Bağlı Fazlar +- `~a` için `-13` beklentisi, `int`'in **iki's complement (ikiye tümleyen) imzalı 32-bit** temsiline dayanır — bu, `src/core/type.hpp`'de `int`'in tam temsilinin (bit genişliği) **şimdiden** dokümante edilmesini gerektirir (Faz 0'a not). +- `1 << 2 + 1` örneği **kasıtlı olarak kafa karıştırıcı** — C'de `<<`/`>>` aritmetik operatörlerden (`+`/`-`) daha düşük önceliklidir. saQut Pratt parser'ı bu sırayı C ile aynı mı tutacak, yoksa daha "şaşırtmasız" bir öncelik mi tanımlayacak? **Karar ne olursa olsun docs'a yazılmalı**, çünkü bu tip kararlar "sessiz" kalırsa en çok şikayet edilen bug kaynağı olur. +- Bu operatörler sadece `int` için tanımlı olmalı; `bool & bool` veya `float << 1` gibi kullanımlar `E003` üretmeli (Faz 3'e not). + +*İmza/Yorum:* "Karmaşık byte işlemleri" testi olarak istenen tam da bu — bit-manipülasyonu doğru çalışmayan bir derleyici, gerçek programlar (hash, sıkıştırma, bayrak/flag kümeleri) için kullanılamaz hale gelir.""" + }, + { + "title": "[Test] Builtin Fonksiyonların Kullanım Örnekleri (`print`, `len`, `toString`, `parseInt`, ...)", + "labels": [L_TEST], + "body": """### Giriş (Nedir, Neden Önemli?) +`print` dışındaki builtin'ler henüz yazılmadı (bkz. "[Fikir] Builtin Fonksiyon Kataloğu", #89), ama bu issue **hedefin son hâlini** somut kodla göstermek için var — yani "builtin kataloğu" tamamlandığında bu dosyanın **aynen bu çıktıyı** vermesi beklenir. Erken yazmanın faydası: builtin imzaları (parametre/dönüş tipleri) bu örnekten geriye doğru türetilebilir. + +--- + +### Test Kodu (`examples/tests/builtin_fonksiyonlar.sqt`) +```c +int main() { + // print: farklı tiplerde çalışmalı + print(42); + print(3.14); + print("merhaba"); + print(true); + + // toString: sayıdan string'e + print(toString(123)); // "123" + + // parseInt / parseFloat: string'den sayıya + print(parseInt("45") + 5); // 50 + print(parseFloat("2.5") * 2.0); // 5.0 + + // len: string ve array uzunluğu + print(len("saqut")); // 5 + + int[] sayilar = {10, 20, 30}; + print(len(sayilar)); // 3 + + return 0; +} +``` + +### Beklenen Çıktı +``` +42 +3.14 +merhaba +true +123 +50 +5.0 +5 +3 +``` + +--- + +### Açık Sorular / Bağlı Fazlar +- `print(true)` çıktısı `true`/`false` mi yoksa `1`/`0` mı olmalı? saQut'ta `bool` ayrı bir tip olduğu için (ADR-010, gizli int↔bool dönüşümü de yok varsayımıyla) `true`/`false` **daha tutarlı** görünüyor — ama bu kararın `print`'in builtin tablosuna (#89) not edilmesi gerekir. +- `int[] sayilar = {10, 20, 30};` — array literal sözdizimi (`{...}`) şu an dilde **tanımlı mı**? Eğer değilse, bu issue aynı zamanda "array literal sözdizimi eklenmeli" şeklinde bir alt-konu açar (Faz 1/parser'a not). +- `parseFloat("2.5") * 2.0` → `5.0` çıktısının `5` değil `5.0` (ondalık nokta korunarak) basılması, `print`'in `float` biçimlendirmesi için bir kural gerektirir — bu kural baştan netleşmeli (örn. her zaman en az bir ondalık basamak). + +*İmza/Yorum:* Bu dosya, builtin kataloğu (#89) ve minimal stdlib (#90) issue'larının "kabul testi" (acceptance test) gibi düşünülebilir.""" + }, + { + "title": "[Test] Struct + Array Birlikte Kullanım Senaryosu", + "labels": [L_TEST], + "body": """### Giriş (Nedir, Neden Önemli?) +`struct` ve `int[]` dil kimliğinde "var" olarak işaretli ama bu ikisinin **birlikte** kullanıldığı (struct içinde array, array of struct) bir örnek henüz yazılmadı. Bu kombinasyon, value-semantics (değer semantiği) kopyalama davranışını (bkz. #79 "Array ve Struct'ların Runtime Bellek Düzeni") en çok zorlayan senaryodur. + +--- + +### Test Kodu (`examples/tests/struct_array.sqt`) +```c +struct Ogrenci { + string ad; + int notlar[3]; +} + +int toplaNotlar(Ogrenci o) { + int toplam = 0; + for (int i = 0; i < 3; i = i + 1) { + toplam = toplam + o.notlar[i]; + } + return toplam; +} + +int main() { + Ogrenci ali; + ali.ad = "Ali"; + ali.notlar[0] = 70; + ali.notlar[1] = 85; + ali.notlar[2] = 90; + + print(ali.ad); + print(toplaNotlar(ali)); + + // value semantics: kopya degisse de orijinal degismemeli + Ogrenci kopya = ali; + kopya.notlar[0] = 0; + print(toplaNotlar(ali)); // değişmemeli: 245 + print(toplaNotlar(kopya)); // değişmeli: 175 + + return 0; +} +``` + +### Beklenen Çıktı +``` +Ali +245 +245 +175 +``` + +--- + +### Açık Sorular / Bağlı Fazlar +- `int notlar[3];` sözdizimi (struct alanı olarak sabit-boyutlu array) — parser bunu destekliyor mu, yoksa `int[3] notlar;` mı olmalı? Dil kimliğinde array sözdizimi `int[]` olarak yazılmış ama boyutlu hali (`[3]`) henüz örneklenmemiş — bu issue, sözdizimini netleştirme ihtiyacını da gösterir. +- `Ogrenci kopya = ali;` satırının **gerçekten derin kopya** yapması (struct içindeki array dahil) — bu, #79'daki "struct kopyalama IR'de alan-alan mı genişler" sorusunun **somut test vakasıdır**. Eğer `kopya.notlar[0] = 0;` satırı `ali.notlar[0]`'ı da değiştirirse (yüzeysel kopya/shallow copy), bu **value semantics kuralının ihlalidir** — kritik bir bug. + +*İmza/Yorum:* Bu test, "value semantics" kilitli kararının (dil kimliği tablosu) en sıkı sınandığı yer — diğer tüm testler geçse bile bu test başarısızsa, dilin temel garantisi bozulmuş demektir.""" + }, + # ---------------- Optimizasyon test senaryolari ---------------- + { + "title": "[Test] Optimizasyon — Constant Folding Doğrulama (`--optimized` Öncesi/Sonrası)", + "labels": [L_TEST], + "body": """### Giriş (Nedir, Neden Önemli?) +Faz 4'ün constant folding pass'i, sabit ifadeleri derleme zamanında hesaplayıp `Literal` düğümüyle değiştirmeli (bkz. roadmap Faz 4). Bu issue, "öncesi/sonrası" AST karşılaştırmasının **tam olarak nasıl görünmesi gerektiğini** somutlaştırır. + +--- + +### Test Kodu (`examples/tests/opt_constant_folding.sqt`) +```c +int main() { + int x = 2 + 3 * 4; // sabit ifade -> 14 + int y = (10 - 4) / 2; // sabit ifade -> 3 + int z = x + y; // x, y sabit olduğu için z de katlanabilir -> 17 + int w = 10 / 0; // sıfıra bölme: KATLANMAZ, W002 uyarısı + print(z); + print(w); + return 0; +} +``` + +### Beklenen Davranış +- `saqut ast examples/tests/opt_constant_folding.sqt` (bayraksız): orijinal AST — `x`'in initializer'ı `BinaryExpression(2, +, BinaryExpression(3, *, 4))` olarak **değişmeden** görünür. +- `saqut ast examples/tests/opt_constant_folding.sqt --optimized`: klonlanmış AST'de: + - `x`'in initializer'ı → `Literal(14)` + - `y`'nin initializer'ı → `Literal(3)` + - `z`'nin initializer'ı → `Literal(17)` (**zincirleme**: `x` ve `y` önce katlanmalı, sonra `z = x + y` de katlanabilmeli — bu, fixpoint döngüsünün gerekliliğinin kanıtıdır) + - `w`'nin initializer'ı → **değişmez** (`10 / 0` kalır), ve diagnostic çıktısında `W002` (sıfıra bölme) uyarısı görünür. +- `saqut run examples/tests/opt_constant_folding.sqt` çıktısı (VM tamamlandığında): `17` ve ardından `10 / 0` çalışma-zamanı hatası (bu son satır, IR/VM tasarımına `E0xx`/runtime-error kategorisi notu olarak düşülmeli). + +--- + +### Açık Sorular / Bağlı Fazlar +- "Zincirleme katlama" (`z = x + y`, `x` ve `y` kendileri katlanmış sabitlerden geliyor) tek bir fixpoint turunda mı yoksa birden fazla turda mı gerçekleşmeli — bu, ADR-009'daki fixpoint/iterasyon-tavanı kararının **somut test sayısı** olabilir (örn. "bu örnek 2 turda kararlı hale gelmeli"). +- `10 / 0` ifadesinin **derleme zamanında uyarı, çalışma zamanında hata** ayrımı IR/VM tasarımına (#74-78) açıkça not edilmeli. + +*İmza/Yorum:* Bu test dosyası, Faz 4'ün "bitti" tanımının resmi kanıtı olabilir — roadmap'teki "Doğrulama" bölümüne doğrudan eklenebilir.""" + }, + { + "title": "[Test] Optimizasyon — Dead Code Elimination Doğrulama (Ölü Kod Temizliği)", + "labels": [L_TEST], + "body": """### Giriş (Nedir, Neden Önemli?) +Faz 4'ün DCE (Dead Code Elimination, Ölü Kod Eleme) pass'i, erişilemez kodu ve kullanılmayan değişkenleri temizlemeli. Bu issue, "ölü kod" sayılan **farklı durumların** her birini ayrı ayrı örnekler — DCE'nin sadece "return sonrası kod" ile sınırlı kalmaması gerektiğini gösterir. + +--- + +### Test Kodu (`examples/tests/opt_dead_code.sqt`) +```c +int hesapla(int n) { + int kullanilmayan = 99; // hiç kullanılmıyor -> W001 + + if (n > 0) { + return n * 2; + print(n); // return sonrası -> erişilemez, W003 + } + + return -1; + + int olu = 5; // fonksiyonun erişilemez kuyruğu -> W003 + return olu; +} + +int main() { + print(hesapla(5)); + return 0; +} +``` + +### Beklenen Davranış +- `saqut ast examples/tests/opt_dead_code.sqt --optimized` çıktısında: + - `int kullanilmayan = 99;` satırı **silinmiş** olmalı (referans sayısı 0 → Faz 2'nin `references` listesi boş). + - `print(n);` (return sonrası) **silinmiş** olmalı. + - `int olu = 5; return olu;` (fonksiyonun son `return -1;`'inden sonraki erişilemez kuyruk) **silinmiş** olmalı. +- Diagnostic çıktısında **3 uyarı** görünmeli: `W001` (kullanılmayan değişken), iki adet `W003` (erişilemez kod) — konum bilgileriyle (satır/sütun) birlikte. +- `saqut ast examples/tests/opt_dead_code.sqt` (bayraksız, optimize edilmemiş): **hiçbir satır silinmemiş**, ama uyarılar yine de raporlanabilir (uyarı raporlama optimizasyondan bağımsız olabilir — bu ayrım netleştirilmeli). +- `saqut run examples/tests/opt_dead_code.sqt` çıktısı (optimize edilsin/edilmesin aynı olmalı — **DCE anlamı değiştirmez**, sadece temizler): `10` + +--- + +### Açık Sorular / Bağlı Fazlar +- "Kullanılmayan değişken" (`W001`) tespiti Faz 2'nin `references` sayacına dayanır — ama bu sayaç **optimize edilmemiş orijinal AST'de** mi tutulur, yoksa her fixpoint turunda klon üzerinde yeniden mi hesaplanır (ADR-009, "flow-bound analiz her turda klon üzerinde yeniden hesaplanır")? Bu örnek, o kararın doğru uygulanıp uygulanmadığının testi. +- Fonksiyonun "erişilemez kuyruğu" (son `return`'den sonraki kod) ile "if içindeki return sonrası kod" aynı `isReachable=false` mekanizmasıyla mı işaretleniyor — yoksa farklı kod yolları mı? + +*İmza/Yorum:* "deadcode elimination eklenecek" değil, tam olarak kullanıcının istediği gibi: "optimizasyonlu/optimizasyonsuz çıktı karşılaştırıldığında gereksiz kod gözlemlenene kadar" çalışılacak somut hedef budur.""" + }, + # ---------------- CLI / UX ---------------- + { + "title": "[Fikir] CLI'da AST Görüntüleme — Ağaç (Tree), Tablo ve `--format=dot` Seçenekleri", + "labels": [L_FIKIR, L_CLIUX], + "body": """### Giriş (Nedir, Neden Önemli?) +Şu an `saqut ast` ham JSON basıyor. JSON, makineler için ideal ama bir insanın "bu kod nasıl bir ağaca dönüşmüş" sorusuna hızlı cevap vermesi için **okunması zor**. "Programlanabilir derleyici" felsefesi hem makine-okur (JSON) hem **insan-okur** çıktıyı hak ediyor. + +--- + +### Gelişme (Olası Yaklaşımlar) +- `saqut ast file --format=json` (mevcut, varsayılan kalabilir), `--format=tree`: terminalde girintili/kutu-çizgili bir ağaç (örn. `tree` komutunun çıktısına benzer: `├──`, `└──`). +- `--format=dot`: Graphviz DOT formatı — `saqut ast file --format=dot | dot -Tpng -o ast.png` ile görsel AST diyagramı üretilebilir (#43'te zaten "AST görselleştirme" fikri vardı, bu onun somut hâli). +- `--format=table`: her düğümü satır olarak basan, `tip | konum | değer` kolonlarına sahip düz bir tablo — `grep`/`awk` ile script'lenmesi kolay bir ara format. +- Renkli terminal çıktısı (`--color`): düğüm tipine göre (Expression mavi, Statement sarı, Literal yeşil gibi) ANSI renk kodları — `--optimized` ile birlikte kullanılırsa, **silinen düğümler kırmızı/üstü çizili** gösterilebilir (DCE'nin görsel kanıtı). + +--- + +### Açık Sorular +- `--format=tree`/`table`/`dot` çıktıları AST'nin **tam** bilgisini mi taşır (her alan), yoksa "özet" mi (sadece tip + konum + kısa değer)? Tam JSON her zaman `--format=json` ile erişilebilir kalmalı — diğerleri "insan için özet" olabilir. +- Bu format seçenekleri `saqut symbols` ve ileride `saqut ir` için de **aynı bayrak isimleriyle** tutarlı olmalı mı (örn. her komut `--format=tree/json/dot/table` desteklesin — CLI'da tek bir ortak altyapı, `src/cli/format.hpp` gibi)? + +*İmza/Yorum:* `--format=dot` özellikle düşük efor / yüksek "vitrin" değeri taşıyor — bir blog yazısında/README'de "işte saQut'un AST'si" diye gösterilebilecek bir görsel üretir.""" + }, + { + "title": "[Fikir] CLI Komut Seti Genişletme Önerileri (`check`, `explain`, `watch`)", + "labels": [L_FIKIR, L_CLIUX], + "body": """### Giriş (Nedir, Neden Önemli?) +Mevcut/planlanan komutlar (`tokens`, `ast`, `symbols`, `run`, ileride `ir`, `fmt`, `lsp`) hep "bir aşamanın çıktısını göster" mantığında. Bu issue, geliştirici deneyimini iyileştirecek **birleşik/yardımcı** komutları tartışır. + +--- + +### Gelişme (Olası Yaklaşımlar) +- **`saqut check file`**: sadece derleme hatalarını (Faz 0-3 diagnostic'leri) raporlar, **hiçbir çıktı üretmez/çalıştırmaz** — "bu kod derlenir mi?" sorusuna hızlı cevap. CI'larda (otomatik test sistemlerinde) kullanışlı. Çıkış kodu (exit code) `0` = hatasız, `1` = hata var. +- **`saqut explain E003`**: bir hata kodunun ne anlama geldiğini, **neden** var olduğunu (ilgili ADR'ye atıfla) ve örnek doğru/yanlış kod gösteren bir açıklama basar — hata kataloğunun (roadmap'teki tablo) CLI'dan erişilebilir hâli. "[Fikir] Akıllı Diagnostic" (#98) ile doğrudan ilişkili. +- **`saqut watch file --run`**: dosya her kaydedildiğinde otomatik olarak `check`/`run` çalıştırır, sonucu terminalde gösterir — hızlı geri-bildirim döngüsü (`cargo watch` benzeri). v0 için basit bir dosya-değişikliği izleme (polling veya `inotify`) yeterli. +- **`saqut --version` / `saqut --help`**: temel ama unutulmaması gereken iskelet komutlar — her CLI aracının beklediği standart. + +--- + +### Açık Sorular +- `saqut explain` kataloğu, hata mesajlarının içine gömülü mü olacak (örn. her hata "detaylar için: `saqut explain E003`" diye bitiyor), yoksa ayrı statik bir JSON/Markdown kataloğundan mı okunacak? +- `saqut watch`, LSP (#91) ile fonksiyonel olarak örtüşüyor — ikisi de "kodu değiştirdikçe geri bildirim" sağlıyor. `watch` LSP'den **önce**, basit/terminal-tabanlı bir "ara çözüm" olarak mı konumlanmalı? + +*İmza/Yorum:* `saqut check` ve `saqut explain`, düşük maliyetli ama günlük kullanımda en çok hissedilecek iyileştirmeler — Faz 0'ın `DiagnosticEngine`'i bittiği anda `check` neredeyse bedavaya gelir.""" + }, + # ---------------- Kalite / Mimari tavsiyeler ---------------- + { + "title": "[Fikir] Performans için C Tarzı Tasarım Kararları (Hız Önceliksiz Ama Bilinçli)", + "labels": [L_FIKIR, L_KALITE], + "body": """### Giriş (Nedir, Neden Önemli?) +ADR-015 "öncelik determinizm + incelenebilirlik, ham hız değil" diyor — bu **doğru** bir karar. Ama "hız öncelik değil" ile "gereksiz yere yavaş" aynı şey değildir. Bu issue, **mimariyi karmaşıklaştırmadan** (yeni soyutlama eklemeden) elde edilebilecek "bedava" performans kazanımlarını listeler — C'nin "ne kadar az iş, o kadar hızlı" felsefesinden ilham alarak. + +--- + +### Gelişme (Tavsiyeler) +- **Gereksiz kopyalama'dan kaçın:** AST düğümleri ve `Type`/`Symbol` nesneleri `std::string` gibi alanlar taşıyor — bunlar fonksiyonlara **referans/`const&`** ile geçilmeli, değer ile değil. Bu, "header-only" (ADR-003) ile çatışmaz, sadece dikkatli imza yazımı gerektirir. +- **`std::unique_ptr` ile sahiplik (ownership) net olsun** (#44'te bahsedilen issue tipi) — bellek sahipliği belirsizse hem bug hem performans kaybı (gereksiz `shared_ptr`/kopya) olur. +- **Tokenizer/Lexer tek geçişte (single-pass) çalışıyor mu** — kaynak dosya birden fazla kez taranıyorsa (örn. önce tokenize, sonra tekrar karakter-karakter konum hesaplama), bu birleştirilebilir. +- **IR/VM tasarımında (ileride):** yığın-tabanlı VM'de (#76) gereksiz push/pop zincirleri, basit "peephole" (göz ucu) optimizasyonlarla (örn. `push X; pop` → hiçbir şey) IR seviyesinde temizlenebilir — bu, Faz 4'ün constant folding'ine **benzer** ama IR'e özel, küçük bir ek pass olabilir. +- **Derleme zamanı (`saqut` binary'sinin kendi derlenme hızı):** header-only + agresif template kullanımı derleme süresini şişirebilir — `-Wall -Wextra` yanında zaman zaman derleme süresi de (örn. `time cmake --build`) izlenmeli. + +--- + +### Açık Sorular +- "Bedava" optimizasyonlar (kopya azaltma, peephole) ile "erken optimizasyon yapma" ilkesi (roadmap'teki "önce dikey dilim") arasındaki çizgi nerede? Önerim: **mimariyi değiştirmeyen, sadece imza/kopya düzeltmeleri** her zaman yapılabilir; **yeni pass/altyapı gerektirenler** (peephole gibi) Faz 4 sonrasına bırakılır. + +*İmza/Yorum:* "C gibi hızlı olmak", saQut için "C kadar hızlı VM" anlamına gelmek zorunda değil — "gereksiz iş yapmayan, dikkatli yazılmış C++ kodu" anlamına gelebilir; bu, ADR-015 ile çatışmaz.""" + }, + { + "title": "[Fikir] Güvenlik ve Stabilite için Java Tarzı Tasarım Kararları (Sınır Kontrolü, Hata İzolasyonu)", + "labels": [L_FIKIR, L_KALITE], + "body": """### Giriş (Nedir, Neden Önemli?) +saQut'ta kullanıcıya açık pointer yok (dil kimliği) — bu, C'nin en büyük güvenlik açığı kaynağı olan "pointer aritmetiği"ni baştan eliyor. Ama Java'nın asıl gücü bundan da fazlası: **her hata kontrollü bir şekilde yakalanır, programın geri kalanı çökmeden devam edebilir** (exception/hata izolasyonu) ve **dizi sınırları her zaman kontrol edilir**. Bu issue, bu ilkelerin saQut'a nasıl yansıyacağını tartışır. + +--- + +### Gelişme (Tavsiyeler) +- **Array sınır kontrolü (bounds checking):** `int[3] notlar; notlar[5] = 1;` gibi bir erişim — eğer boyut derleme zamanında biliniyorsa (`E009` zaten "array boyutu sabit değil" hatasını kapsıyor, ama "sabit boyut + sınır-dışı indeks" ayrı bir konu) **derleme zamanında** `E0xx` ile yakalanmalı; eğer indeks çalışma zamanı değeriyse (`notlar[i]`, `i` döngü değişkeni), **VM çalışma zamanında kontrol etmeli** ve kontrollü bir "runtime error" üretmeli (C'deki sessiz bellek bozulmasının tam tersi). +- **Çalışma zamanı hatalarının kategorize edilmesi:** sıfıra bölme (Faz 4'te `W002` derleme-zamanı uyarısı var, ama çalışma zamanında gerçek bir bölme `10 / x` ile `x=0` olursa ne olur?), dizi sınır taşması, derinlik taşması (call stack overflow, #78) — bunların hepsi **aynı "RuntimeError" ailesinde**, konum bilgisiyle (hangi `print`/satırda patladı) raporlanmalı; VM **segfault** ile çökmemeli. +- **"Programın bir kısmı patlasın, derleyici/VM çökmesin":** VM'in kendi C++ kodunda `assert`/exception kullanımı, kullanıcı programındaki bir hatayı (örn. sınır-dışı erişim) **VM crash'ine** dönüştürmemeli — bu, VM geliştirilirken her runtime-error noktasında "bu durum kullanıcıya nasıl raporlanır" sorusunun sorulması demektir. +- **Tip sisteminin sıkılığı (ADR-010) zaten "Java tarzı" bir güvenlik katmanı** — gizli dönüşüm yok kuralı, C'deki "implicit int→pointer" gibi klasik hata sınıflarını zaten önlüyor. Bu issue bunu **devam ettirme** çağrısıdır, yeni bir şey eklemiyor. + +--- + +### Açık Sorular +- Çalışma zamanı hataları (array sınır taşması vb.) için **yeni bir diagnostic kategorisi** (`R001`, `R002`... "Runtime" öneki ile, `E`/`W`'den ayrı) mı açılmalı — IR/VM tasarım issue'larına (#74-78) not edilmeli. +- Sınır kontrolü **her zaman** mı açık olacak, yoksa "release modu"nda (varsa böyle bir kavram) kapatılabilir mi — ADR-015'in "determinizm > hız" ilkesi düşünülürse, **her zaman açık** olması daha tutarlı görünüyor. + +*İmza/Yorum:* "Güvenli dil" derken kastedilen genelde "bellek güvenliği" — saQut bunu zaten pointer'sızlıkla büyük ölçüde kazandı; kalan iş, **çalışma zamanı hatalarını zarif bir şekilde raporlamak**.""" + }, + { + "title": "[Fikir] Modernlik için Go Tarzı Tasarım Kararları (Basitlik, Hızlı Geri-Bildirim, Tek Binary)", + "labels": [L_FIKIR, L_KALITE], + "body": """### Giriş (Nedir, Neden Önemli?) +Go'nun başarısının çoğu **dil özelliklerinden değil, geliştirici deneyiminden** geliyor: çok hızlı derleme, yerleşik formatter (`gofmt`), tek-binary dağıtım, anlaşılır hata mesajları, "az ama öz" bir standart kütüphane. saQut zaten küçük/basit bir dil — bu issue, Go'nun **araç zinciri (toolchain) felsefesini** saQut'a nasıl taşıyabileceğimizi listeler. + +--- + +### Gelişme (Tavsiyeler) +- **Tek binary, sıfır bağımlılık:** `saqut` CLI'sı tüm komutları (`tokens`, `ast`, `symbols`, ileride `run`, `fmt`, `lsp`) **tek bir çalıştırılabilir dosyada** barındırır — kullanıcı hiçbir ek paket/runtime kurmaz. Header-only C++ (ADR-003) bu hedefe zaten doğal olarak uygun; bu issue sadece **bunu bir hedef olarak yazıya dökmek**. +- **Hızlı derleme = hızlı geri-bildirim:** Go'nun derleme hızı, "kodu yaz → hemen çalıştır" döngüsünü mümkün kılıyor. saQut için bu, `saqut run` (IR+VM) ile birleşince **"saQut programını derleyip çalıştırmak, C++ programını derlemekten çok daha hızlı olmalı"** gibi somut bir hedef olabilir — VM yorumlayıcı olduğu için bu zaten doğal bir avantaj. +- **`gofmt` zaten bir issue olarak var (#93, `saqut fmt`)** — Go'nun "tartışmasız tek doğru format" felsefesi: format ayarlanabilir **olmamalı** (yapılandırma dosyası yok), bu da formatter'ın tasarımını basitleştirir. +- **Anlaşılır hata mesajları (#98 ile ilişkili):** Go'nun hata mesajları kısa ve doğrudandır (`undefined: x`). saQut'un hata kataloğu (E001 vb.) zaten bu yönde — bu issue, mesaj **dilinin** (Türkçe/İngilizce) ve **tonunun** (kısa cümle + örnek) standartlaştırılmasını önerir. +- **Yerleşik test çalıştırıcı (#96 ile ilişkili)** ve **modül sistemi (#81-83)** — Go'nun `go test` ve `go mod`'u, dilin "etrafına" değil **içine** gömülü araçlar. saQut'un CLI'sı da bu felsefeyle büyümeli: her yeni özellik (test, format, modül) **ayrı bir 3. parti araç değil, `saqut` alt-komutu** olmalı. + +--- + +### Açık Sorular +- "Tek binary" hedefi, FFI (#88) ile gerilim yaratabilir mi — kullanıcı kendi C++ host fonksiyonlarını eklemek isterse, bu "tek binary"yi nasıl etkiler (dinamik kütüphane yükleme mi, yeniden derleme mi)? +- Hata mesajı dili: şu anki dokümantasyon Türkçe — CLI çıktısı da Türkçe mi olacak, yoksa İngilizce + Türkçe `explain` (#issue) mi? Bu, uluslararası kullanıcı kitlesi hedefleniyorsa önemli bir erken karar. + +*İmza/Yorum:* saQut'un "alet çantası" kimliği ile Go'nun "az şey, ama hepsi birlikte ve iyi çalışıyor" felsefesi doğal bir eşleşme — bu issue, var olan diğer issue'ları (#91-98) tek bir "araç zinciri vizyonu" şemsiyesi altında toplama denemesidir.""" + }, +] + +for issue in issues_data: + endpoint = f"{REPO_PATH}/issues" + res = make_request(endpoint, method="POST", data=issue) + print(f"Created issue #{res['number']}: {res['title']}")