- 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. |
||
|---|---|---|
| build | ||
| docs | ||
| examples | ||
| scripts | ||
| src | ||
| .gitignore | ||
| CMakeLists.txt | ||
| readme.md | ||
readme.md
saQut
Programlanabilir, incelenebilir bir derleyici — bir "alet çantası" (toolbox).
saQut'un asıl varlık sebebi dilin kendisinden çok, derleme sürecinin her aşamasının dışarıdan görülebilir ve müdahale edilebilir olmasıdır. Token'lar, AST, sembol tablosu, optimizasyonun öncesi/sonrası ve IR — hepsi ayrı ayrı incelenebilir. Dil, bu aletin üzerinde çalıştığı küçük, prosedürel bir örnektir; vitrin değil, alet.
Uygulama dili C++'tır (header-only eğilimli, bkz. docs/fikirler.md ADR-003).
Şu an ne çalışıyor, ne çalışmıyor
Belgeler planlanan ile yapılanı net ayırır. Bugünkü gerçek durum:
✅ Çalışıyor (built)
- Lexer — karakter seviyesi tarama, konum takibi.
- Tokenizer — token üretimi (6 token tipi), yorum satırı desteği.
- Pratt parser — ifade (Pratt) + statement (recursive descent) ayrıştırma.
- AST — fonksiyon, blok, değişken tanımı, if/for/while/do-while/return, ifade node'ları.
- AST'nin JSON serileştirmesi —
saqut astile incelenebilir. - CLI komut yapısı —
tokens,ast,symbols,runiskeletleri. - Kaynak konum takibi (SourceLocation) — offset → (satır, sütun).
- Minimal IR deneyi — basit aritmetiği düşürür (örn.
1 + (7/3)→ kısa doğrusal komut dizisi). Henüz tam bir backend değil, bir deneydir.
🚧 Henüz yok (planned)
- Sembol tablosu
- Semantik analiz
- Tip sistemi
- Diagnostic (hata raporlama) motoru
- Optimizasyon
- IR + bytecode VM ile çalıştırma
feature/frontend-analysisdalı şu an yalnızca bu yapılmamış işin tasarım belgelerini içerir, kodunu değil.
Birinci kilometre taşı ("bitti" tanımı): derleyici fibonacci'yi
(recursive + iterative) ve basit matematik/döngü programlarını derleyip
çalıştırabilmeli. Referans program: examples/fibonacci.sqt.
Dil kimliği (kilitli)
Prosedürel, C ailesi sözdizimi, value semantics. İlk ifade doğrudan bir
işlem/tanım olabilir; zorunlu class/main boilerplate'i yoktur (Java'nın aksine).
| Özellik | Karar |
|---|---|
| Class / OOP / kalıtım | Yok |
| Closure | Yok |
| Generic | Yok |
Kullanıcıya açık pointer (* / &) |
Yok — derleyici/runtime içeride pointer'ı serbestçe kullanır |
struct |
Var |
| Tipli fonksiyonlar (dönüş + parametre) | Var |
Array (int[]) |
Var |
interface |
Ertelendi (v0 değil — gerekçe ADR-018) |
auto / tip çıkarımı |
Yok |
| Gizli int↔float dönüşümü | Yok (tek istisna: sabit folding) |
Gerekçe: prosedürel tasarım semantik karmaşıklığı en aza indirir ve hedeflerle
(fibonacci, matematik, sıralama, ayrıştırma) örtüşür. Standart C'de class
yoktur (o C++'tır); C, struct + fonksiyonun yettiğini kanıtlar.
Çalıştırma modeli (kilitli): IR + bytecode VM
saQut, kendi IR'sine derler ve bu IR'yi bir yorumlayıcı döngü (bytecode VM) ile çalıştırır.
- Tree-walker DEĞİL (çok yavaş).
- Gerçek makine-kodu JIT DEĞİL. Makine kodu üretimi (register allocation,
ABI/çağırma sözleşmeleri, çalıştırılabilir
mmapbellek) kapsam dışıdır — tek faydası ham hızdır ve hız burada öncelik değildir. Öncelikler determinizm ve incelenebilirliktir; bytecode VM ikisini de doğrudan sağlar. - Bellek bu modelde kolaydır: host (C++) heap'i kullanılır; v0 için özel runtime allocator gerekmez.
- C'ye transpile, geçerli bir İKİNCİ backend olarak ileride kalır (frontend backend-bağımsızdır — middle-end ayrımının amacı budur, ADR-006). İleride makine kodu istenirse elle code generator yazmak yerine libgccjit / LLVM'e bağlanılır — ama bu çok uzak gelecektir.
Eski belge/konuşmalarda geçen "JIT" terimi yanlış yönlendiricidir; doğru çerçeve IR + VM'dir.
Mimari hatlar
KAYNAK KOD
│ lexer
▼
TOKEN'LAR ────────────── saqut tokens
│ parser (Pratt + recursive descent)
▼
AST ──────────────────── saqut ast
│ sembol toplama (iki geçişli) ┐
▼ │
SEMBOL TABLOSU ───────── saqut symbols │ FRONTEND
│ semantik analiz (annotation) │ (yapı + anlam)
▼ │
ANNOTATE EDİLMİŞ AST ─── saqut ast ┘
│ optimizasyon (opsiyonel, klon üstünde) ── MIDDLE-END
▼
IR ───────────────────── (planlanan) ┐
│ bytecode VM / yorumlayıcı döngü │ BACKEND
▼ │ (çalıştırma + FFI seam)
ÇALIŞTIRMA / ÇIKTI ───── saqut run ┘
- Frontend yapıyı ve anlamı modeller (tip, scope, dataflow).
- "Hangi çekirdek, hangi cihaz, ne zaman, hangi çıktı formatı" runtime/backend meselesidir — frontend'e yüklenmez.
CLI (mevcut + planlanan)
# --- çalışıyor ---
saqut tokens file:kaynak.sqt # token listesi
saqut ast file:kaynak.sqt # AST (JSON)
saqut symbols file:kaynak.sqt # sembol tablosu (iskelet)
# --- planlanan ---
saqut run file:kaynak.sqt # IR üret + bytecode VM ile çalıştır
saqut ast file:kaynak.sqt --optimized # klon, optimize edilmiş AST (öncesi/sonrası)
saqut transpile file:kaynak.sqt -o prog.c # ikinci backend (ileride)
Tasarım gereği her aşamanın çıktısı erken bir noktada dosyalanabilir/loglanabilir (programlanabilir derleyici). Token, ham AST, optimize AST ve IR ayrı ayrı kaydedilebilir.
Batteries / stdlib — kuzey yıldızı, ertelendi
Gerçek bir genel sürüm pil ile gelmeli (sıralama, sıkıştırma, kripto, JSON/XML/HTML ayrıştırma). Ama bu bugünün işi ve v0.1 değildir.
Mimari çerçeve (monolit korkusunu önler): derleyici pilleri çekirdeğine
gömmez. Bunun yerine küçük bir gerçek builtin kümesi (print, temel
zorunlular) + gerisi kütüphane/FFI ile gelir. "Batteries" sorunu aslında
bir sınır (FFI/link seam) sorunudur, "zlib'i yeniden yaz" sorunu değil.
Sınır bir kez çizilir, piller üstünde sonsuza dek birikir.
- JSON/XML/HTML ayrıştırıcıları saQut'un kendisinde yazılabilir (string + struct + fonksiyon + kontrol akışı yeter). İlk gerçek demo programları.
- Sıkıştırma/kripto: denenmiş C kütüphanelerine FFI ile bağlan. Kripto asla elle yazılmaz.
- Bugüne tek yansıması: IR/runtime tasarlanırken bilinçli bir FFI seam
("host fonksiyonu çağır" deliği) bırakılır.
printbunu zaten zorlar — bunu kaza değil, kasıtlı bir mekanizma yapıyoruz (ADR-016).
Belge haritası
| Belge | İçerik |
|---|---|
docs/fikirler.md |
ADR-001…005: backend stratejisi, parser, header-only, token, IR |
docs/adr-frontend-analiz.md |
ADR-006…019: frontend, analiz/optimizasyon, çalıştırma modeli, FFI, interface, bellek |
docs/roadmap-frontend.md |
Faz-faz uygulama planı (sembol tablosu → fibonacci) |
docs/transkript-frontend-tasarim.md |
Tasarım oturumunun transkripti |
examples/fibonacci.sqt |
Geçerli referans program (semantik + kod üretimi fixture'ı) |
examples/parser-stress/ |
Yalnızca parser'ı zorlayan, geçerli olmayan fixture'lar |
İlke
Bir şey çalışmadan önce çerçeve inşa etmekten kaçın. Önce uçtan uca tek bir
dikey dilim çalıştır (kaynak → IR → çalıştır; tamsayı aritmetiği + değişken +
kontrol akışı + tek bir print). Modülerlik bir kuzey yıldızıdır, v0.1
gereksinimi değil; ihtiyaç doğmadan eklenen her soyutlama daha az değil, daha
çok karmaşıklıktır.