Compare commits

..

7 Commits

183 changed files with 1451 additions and 129348 deletions

9
.gitignore vendored
View File

@ -9,12 +9,3 @@ saqut
*.swp
*.swo
*~
# Parola içerebilen yerel API istemcisi - asla commit edilmez
scripts/gitea.py
# Python bytecode cache
__pycache__/
# CMake versiyona özgü dosyalar (otomatik üretilir, her güncellemede değişir)
build/*

160
CLAUDE.md
View File

@ -1,160 +0,0 @@
# CLAUDE.md — saQut Proje Bağlamı
> Bu dosya her oturumda yüklenir. Amaç: projenin kimliğini, kilitli kararları,
> mevcut durumu ve çalışma konvansiyonlarını hızlıca hatırlatmak.
## İletişim
- **Kullanıcıyla TÜM yazışmalar Türkçe.** (Sahibi: Abdussamed ULUTAŞ.)
## Proje nedir?
saQut, **programlanabilir ve incelenebilir bir derleyici** — bir "alet çantası"
(toolbox). Asıl varlık sebebi dilin kendisi değil, **derleme sürecinin her
aşamasının dışarıdan görülebilir/müdahale edilebilir olması**: token'lar, AST,
sembol tablosu, optimizasyon öncesi/sonrası ve IR ayrı ayrı incelenebilir.
Uygulama dili **C++** (header-only eğilimli, ADR-003). CMake + Ninja. `build/`
git'te izlenir.
## Kilitli kararlar (değiştirme — gerekçeler ADR'lerde)
- **Çalıştırma modeli: IR + bytecode VM (yorumlayıcı döngü).** Tree-walker DEĞİL,
gerçek makine-kodu JIT DEĞİL (kapsam dışı; öncelik determinizm + incelenebilirlik,
ham hız değil). C'ye transpile ileride geçerli 2. backend. İleride makine kodu
gerekirse libgccjit/LLVM'e bağlanılır (çok uzak). Bellek = host C++ heap; özel
allocator yok. (ADR-015)
- **Dil kimliği:** prosedürel, C-ailesi sözdizimi, zorunlu class/main boilerplate
yok. **Semantik (ADR-020):** primitive (`int`/`float`/`bool`) = **değer**;
bileşik (`struct`/`array`/`string`) = **referans** (JS/Java/C# modeli). "Pointer
yok" = kullanıcıya `&`/`*` **sözdizimi** verilmez; derleyici/runtime içeride ve
çalışma zamanında referansı sonuna kadar kullanır. **Yok:** OOP, closure,
generic, auto/tip çıkarımı, gizli int↔float (tek istisna sabit folding). **Var:**
struct, tipli fonksiyonlar, array (`int[]`). `class`/`function` sözdizimsel
**rezerve** (semantik ileride). `interface` **ertelendi** (ADR-018).
⚠️ Referans semantiği döngüsel-referans **sızıntısını** açtı → GC/döngü
toplayıcı borcu (**#56**, `karar-gerekli`).
- **Null güvenliği (ADR-021, REVİZE):** varsayılan non-null; nullable açıkça `Type?`
(Kotlin/Swift). `null` yalnızca `T?`'ye atanır; `T?` üstünde doğrudan erişim derleme
hatası. **Atama kuralı `T <: T?`** (notnull→nullable serbest, nullable→notnull yasak).
**Katı operand kuralı:** non-null bağlamda her operand statik non-null olmalı
(`int a=b+c+d`, biri nullable → hata). Aklama **yalnızca görünür `if` narrowing**
(nested + sıralı guard + `&&`; alias takibi yok). ⚠️ **`a!`/`??`/`?.` YASAK** (gizli
runtime null-aklama yok). Runtime maliyeti **sıfır**; frontend kesin çözer (backend
yeniden analiz etmez) → runtime null-deref esasen FFI backstop'u. SSA gerekmez (#2).
- **Bellek/GC (ADR-022):** **basit, taşımasız, stop-the-world, deterministik
mark-sweep** (döngüleri toplar, "cage" korunur). **`shared_ptr`'ı kalıcı model
YAPMA** (refcount döngüde sızar = topuğa-sıkma). Kural: nesne modelini **baştan
GC-hazır** kur (header: tip+mark biti+liste; VM kök sayar; nesne çocuk
referansları sayar). v1: toplamasız (arena); v2: aynı model üstünde mark-sweep.
Asıl perf-katili GC kararı → basit tutarak de-risk edildi.
- **Eşitlik (ADR-023):** `==` primitive'de değer, referans (struct/array) **kimlik**
(aynı nesne). Derin/yapısal eşitlik **asla** `==`'e bağlanmaz → ayrı görünür
`deepEquals()` (PHP `==`/`===`/`clone` ailesi gibi). **String istisnası:** `==`
**içerik** olmalı (Java gotcha'sından kaçın) → string'i immutable değer-tipi
modelle (#40). `obj==obj`'i hata yapmak + kullanıcı-tanımlı eşitlik = uzak gelecek.
- **String (ADR-024):** **immutable değer-tipi, iç temsil UTF-8.** `s = s + "x"`
yeni string üretir; `==` içerik (ADR-023). Bayt/scalar/grapheme erişimi açıkça
ayrı (sahte O(1) karakter indeksi YOK). Verimli birleştirme için ileride builder.
Çözdüğü: #40 (yüzey), #9 (iç temsil). Mevcut `Value` string'i inline tutuyor —
immutable olduğu için bu yeterli; heap/object-model'e taşımak zorunlu değil.
- **Hata yönetimi (ADR-025, #57):** **Swift-tarzı** yakalanabilir, **struct-tabanlı**
hata — OOP/extend YOK. Standart `Error { line; char; message; trace; code }`
(message=W/E metni, code=W/E kodu). **Klasik `try{}catch{}` bloğu, UNCHECKED**
(Java/C#/JS usulü): fonksiyon işaretlenmez (`noexcept`/`constexpr` tarzı YOK),
çağrıda `try f()` yok — developer'a güven, alışkanlık bozulmaz. Runtime null-deref
(NPE analoğu), array OOB, /0, `a!` patlaması → yakalanabilir hata (ADR-021'in runtime
backstop'u). `throw` ile kullanıcı da kaldırır. Deterministik stacktrace (IR satır
tablosu önkoşul). **Tuple → ertelendi** (ADR-014'teki "yok" gevşedi). `finally` yerine
ileride `defer`.
- **Tip dönüşümü (ADR-026, #42):**ık **`as`** (infix, sola-bağlı): `x as int`.
Yalnızca **skaler + string** arası; **struct/array cast YOK** (elle yapıcı fonksiyon —
derleyiciyi sade tutar, sessiz alan kaybı önlenir). Başarısızlık **hedef tipin
nullable'lığıyla:** `as int``Error` fırlatır; `as int?``null`. Ayrı `as?` YOK.
`float→int` sıfıra kırpar (NaN/Inf/taşma fallible). `int(x)` fonksiyon-stili reddedildi.
- **Analiz vs Optimizasyon:** Analiz orijinal AST üstünde annotation; optimizasyon
**klon** üstünde dönüşüm. `ASTNode::clone()` yük taşıyan merkezi bileşen
(parent pointer'lar + sembol tablosu remap edilir, ADR-007). Fixpoint döngüsü +
iterasyon tavanı (`maxFixpointRounds`, ADR-009).
- **Literal/tip kuralı:** tamsayı literali bağlama-göre tiplenir (`float x = 1;`
geçerli; `int y = 1.5;`→E003; değişken→değişken gizli dönüşüm yok). Döngüsel
by-value struct → E010 (⚠️ ADR-020 ile revize: referansla tutulan struct alanı
artık döngü kurabilir, `Node next` meşru). (ADR-010/011)
- **FFI seam:** kasıtlı "host fonksiyonu çağır" mekanizması (`callhost`); `print`
ilk müşteri (ADR-016). Batteries = sınır/FFI problemi, "zlib'i yeniden yaz"
değil; kripto asla elle yazılmaz (ADR-017).
## Mevcut durum (yapılan vs planlanan)
- **✅ Birinci kilometre taşı AŞILDI:** `examples/fibonacci.sqt`
(recursive + iterative) `saqut run` ile çalışıyor → `55\n55`.
- **Çalışıyor (tam pipeline):**
- Lexer, tokenizer, Pratt parser, AST + JSON serileştirmesi
- Sembol tablosu (iki-geçişli toplayıcı, döngüsel struct tespiti)
- Tip sistemi (`src/core/type.hpp`) + diagnostic motoru (`src/diagnostic/`)
- Tip denetleyici + yapısal doğrulayıcı (`src/semantic/`)
- Optimizasyon: constant folding (int/bool/logical) + dead code elimination
- IR üreteci (3-adresli, slot tabanlı) + bytecode VM (yorumlayıcı döngü)
- CLI: `tokens` / `ast` / `symbols` / `check` / `ir` / `run` (6 komut)
- **Henüz YOK (bilinen eksikler):**
- float/double codegen (tip sistemi var, IR opcode'u yok)
- struct IR (parse/semantik var, codegen yok)
- array IR (parse/semantik var, codegen yok)
- `%=` operatörü IR'da eksik (#37)
- Global değişken IR üretimi sessizce atlıyor (#38)
- W003 ölü kod uyarısı üretilmiyor (#36)
- DCE silinen düğümleri `delete` etmiyor — bellek sızıntısı (#35)
- **İlke:** Önce uçtan uca tek **dikey dilim**, sonra çerçeve. Erken soyutlamadan kaçın.
## Belge haritası
- `readme.md` — toolbox çerçevesi, built-vs-planned, dil kimliği, çalıştırma modeli.
- `docs/fikirler.md` — ADR-001…005 (backend stratejisi, parser, header-only, token, IR).
- `docs/adr-frontend-analiz.md` — ADR-006…026 (frontend, analiz/optimizasyon,
çalıştırma modeli, FFI, interface, bellek, **değer/referans semantiği, null
güvenliği, mark-sweep GC, eşitlik, string, hata yönetimi, tip dönüşümü**).
- `docs/sonnet-handoff.md`**Sonnet için uygulama promptu** (ADR-020…024'ü koda
döken sıralı görev planı; ilk görev: GC-hazır nesne modeli + array runtime).
- `docs/roadmap-frontend.md` — faz-faz uygulama planı (Faz 04 → fibonacci).
- `docs/transkript-frontend-tasarim.md` — tasarım oturumu transkripti.
- `examples/fibonacci.sqt` — geçerli referans program.
- `examples/parser-stress/` — yalnızca parser'ı zorlayan, **geçerli olmayan** fixture'lar.
## Gitea issue yönetimi
- Repo: `git.saqut.com/saqut/saqut-compiler` (Gitea). Cloudflare, Python-urllib
User-Agent'ını banlıyor → tarayıcı User-Agent'ı şart.
- `scripts/gitea.py` — API istemcisi (`~/.git-credentials`'tan kimlik okur).
Komutlar: `list/get/create/edit/comment`. Toplu issue üretimi:
`scripts/create_issues.py`, `create_future_issues.py`, `create_syntax_test_issues.py`.
- **Issue yapısı (bu oturumda kuruldu):**
- **#6973** `faz-plani` — Faz 04 (Tip+Diagnostic, AST refactor, Symbol Table,
Semantik Analiz, Optimizasyon). Format: Giriş/Gelişme/Sonuç-Başarı Kriterleri +
mühendis-olmayan analiz.
- **#7498, #111** `fikir` — IR/VM tasarımı, modül/import, tip genişletmeleri
(decimal/date/enum/string), FFI/builtin/stdlib, tooling (LSP/highlight/fmt),
gelecek vizyonu (time-travel debug, WASM playground, test bloğu, paket yöneticisi).
Format: Giriş/Gelişme/**Açık Sorular** (başarı kriteri YOK).
- **#99105** `test-senaryosu` — kaynak kod + beklenen çıktı içeren golden-test'ler.
- **#106110** `cli-ux`/`kalite-mimari` — CLI fikirleri, C/Java/Go tarzı tavsiyeler.
- LSP (#91) ve CLI (#107) **Tier 04** katmanlı yetenek haritası olarak yazıldı;
#111 ekosistem bağımlılık sırası.
## Lisans (LICENSE.md — bu oturumda yeniden yazıldı)
- **Model:** "Kaynağıık — Ticari Kullanımı Kısıtlı" (açık kaynak ama **özgür
yazılım değil**). Önceki GPL-tarzı copyleft metin niyetle çelişiyordu, değiştirildi.
- **Çekirdek ilke:** Gelir saQut'un **ürettiği Çıktıdan** elde edilir, **saQut'un
kendisinden değil.**
- **Serbest (ticari dahil):** kod yazmak/derlemek, üretilen programları/exe/işlenmiş
veriyi satmak, derleyiciyi özel araç olarak iç kullanım.
- **İzin gerektirir (telif sahibinden):** derleyiciyi 3. tarafa kurup ücret almak,
Web-IDE/derleme servisi, canlı backend motoru, otomasyon/AI aracı, alt-bileşen
gömme, iç parçaları (AST/optimizatör) ticari yeniden kullanım. Runtime'a bağımlı
sürümlerde sunucu-tarafı ticari kullanım da bu kapsamda.
- **Maddeler:** §7 Katkı (PR herkese açık, **merge kararı yalnızca Abdussamed
ULUTAŞ**; katkı sahipleri ticari lisanslama dâhil hakları telif sahibine verir),
§8 Patent (lisans + dava açana otomatik fesih), §9 Marka ("saQut" adı korunur),
§11 Fesih (ihlalde otomatik + 30 gün düzeltme; edinilmiş Çıktı korunur).
- Üç dilde (TR/EN/DE), TR esas. Ticari lisans iletişimi: saqutsoftware+gitea@gmail.com
- **Not:** Bespoke lisans; ciddi ticari aşamada hukukçu gözden geçirmesi önerilir.
Telif yalnızca kodu/belgeyi korur, **fikri/tasarımı değil** (sıfırdan yeniden
yazım engellenemez); isim ise marka ile korunur.
## Çalışma konvansiyonları
- Commit mesajları sonunda: `Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>`.
- Ana dal `0.1.0`; `master` branch yok. commit/push kullanıcı isteyince yapılır.
- Wiki API'si Gitea'da REST üzerinden çalışmadı; wiki içeriği `wiki.md`'ye yazılıp
kullanıcı tarafından elle yapıştırılıyor.

View File

@ -20,99 +20,3 @@ file(GLOB_RECURSE SOURCES "src/*.cpp")
add_executable(saqut ${SOURCES})
target_include_directories(saqut PRIVATE src)
# Testler
enable_testing()
set(SAQUT_BINARY "${CMAKE_BINARY_DIR}/saqut")
set(GOLDEN_SCRIPT "${CMAKE_SOURCE_DIR}/cmake/run_golden.cmake")
# Birim testleri (tests/run.sh)
add_test(
NAME unit_tests
COMMAND bash "${CMAKE_SOURCE_DIR}/tests/run.sh"
)
# Golden testleri tests/golden/**/*.sqt dosyalarını otomatik keşfet.
# Her .sqt için iki olası expected dosyası kontrol edilir:
# BASE.expected saqut run (siyah-kutu çıktı testi)
# BASE.ir_opt.expected saqut ir --optimized (beyaz-kutu IR testi)
file(GLOB_RECURSE ALL_GOLDEN_SQT CONFIGURE_DEPENDS
"${CMAKE_SOURCE_DIR}/tests/golden/*.sqt"
)
foreach(SQT_FILE ${ALL_GOLDEN_SQT})
file(RELATIVE_PATH REL "${CMAKE_SOURCE_DIR}/tests/golden" "${SQT_FILE}")
string(REPLACE ".sqt" "" BASE "${REL}")
string(REPLACE "/" "_" TNAME "${BASE}")
# Siyah-kutu: saqut run çıktısı
set(RUN_EXPECTED "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.expected")
if(EXISTS "${RUN_EXPECTED}")
add_test(
NAME "golden_${TNAME}"
COMMAND ${CMAKE_COMMAND}
-DBINARY=${SAQUT_BINARY}
-DSOURCE=${SQT_FILE}
-DEXPECTED=${RUN_EXPECTED}
-P "${GOLDEN_SCRIPT}"
)
endif()
# Beyaz-kutu: saqut ir --optimized çıktısı
set(IR_OPT_EXPECTED "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.ir_opt.expected")
if(EXISTS "${IR_OPT_EXPECTED}")
add_test(
NAME "golden_${TNAME}_ir_opt"
COMMAND ${CMAKE_COMMAND}
-DBINARY=${SAQUT_BINARY}
-DSOURCE=${SQT_FILE}
-DEXPECTED=${IR_OPT_EXPECTED}
-DCOMMAND=ir
-DOPTIMIZED=1
-P "${GOLDEN_SCRIPT}"
)
endif()
# Doğruluk kalkanı: saqut run --optimized çıktısı == beklenen golden değer
# "Optimizasyon oldu" değil, "optimize IR doğru sonuç verdi" testleri.
set(RUN_OPT_EXPECTED "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.run_opt.expected")
if(EXISTS "${RUN_OPT_EXPECTED}")
add_test(
NAME "golden_${TNAME}_run_opt"
COMMAND ${CMAKE_COMMAND}
-DBINARY=${SAQUT_BINARY}
-DSOURCE=${SQT_FILE}
-DEXPECTED=${RUN_OPT_EXPECTED}
-DOPTIMIZED=1
-P "${GOLDEN_SCRIPT}"
)
endif()
# Negatif test: .compile_error derleme hatası beklenen golden testler.
# Dosya içeriği stderr'de aranır (regex/düz dize).
set(COMPILE_ERROR_EXPECTED "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.compile_error")
if(EXISTS "${COMPILE_ERROR_EXPECTED}")
add_test(
NAME "golden_${TNAME}_compile_error"
COMMAND ${CMAKE_COMMAND}
-DBINARY=${SAQUT_BINARY}
-DSOURCE=${SQT_FILE}
-DEXPECTED=${COMPILE_ERROR_EXPECTED}
-P "${CMAKE_SOURCE_DIR}/cmake/run_golden_error.cmake"
)
endif()
# Negatif test: .runtime_error çalışma zamanı hatası beklenen golden testler.
# Aynı altyapı: exit code != 0 + stderr içeriği kontrolü.
set(RUNTIME_ERROR_EXPECTED "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.runtime_error")
if(EXISTS "${RUNTIME_ERROR_EXPECTED}")
add_test(
NAME "golden_${TNAME}_runtime_error"
COMMAND ${CMAKE_COMMAND}
-DBINARY=${SAQUT_BINARY}
-DSOURCE=${SQT_FILE}
-DEXPECTED=${RUNTIME_ERROR_EXPECTED}
-P "${CMAKE_SOURCE_DIR}/cmake/run_golden_error.cmake"
)
endif()
endforeach()

View File

@ -1,234 +0,0 @@
## Lisans / License / Lizenz
[Türkçe Sürüm](#türkçe-lisans-sürümü) | [English Version](#english-license-version) | [Deutsche Version](#deutsche-lizenzversion)
> Bu lisans üç dilde sunulmuştur. Yorum farklılıklarında **Türkçe sürüm esas alınır.**
> This license is provided in three languages. In case of any discrepancy, the **Turkish version prevails.**
---
### Türkçe Lisans Sürümü
# saQut Lisansı (Sürüm 1.0)
**Kaynağıık — Ticari Kullanımı Kısıtlı Lisans**
Telif Hakkı (c) 2026, Abdussamed ULUTAŞ (ve saQut Katkıda Bulunanları). Tüm hakları saklıdır.
Bu lisans; saQut derleyicisini, kaynak kodlarını, derleme betiklerini (build scripts), tüm backend bileşenlerini (yorumlayıcı, bytecode VM, derleyici ve transpiler) ve beraberindeki dokümantasyon ile mimari tasarımı (ADR belgeleri dâhil) — toplu olarak "Yazılım" olarak anılacaktır — kapsar.
saQut açık kaynaklı (kaynağı görülebilir) bir projedir; ancak **özgür yazılım (free/libre software) değildir.** Yazılımın incelenmesi ve değiştirilmesi serbestken, ticari kullanımı işbu lisansın koşullarına ve telif hakkı sahibinin iznine tabidir.
#### 1. Temel Felsefe (Alet Çantası Kuralı)
saQut; programlanabilir ve incelenebilir bir derleyici alet çantası (toolbox) olarak tasarlanmıştır. Varlık sebebi, derleme sürecinin her aşamasının — token'lar, Soyut Sözdizimi Ağacı (AST), sembol tabloları ve Ara Temsil (IR) — dışarıdan şeffaf ve görülebilir kalmasıdır. Yazılımın her türlü yeniden dağıtımı ve üzerinde yapılacak değişiklikler bu şeffaflık ilkesini korumakla yükümlüdür.
#### 2. Tanımlar
- **Yazılım:** Yukarıda tanımlanan saQut derleyicisi ve tüm bileşenleri (kaynak kod, yorumlayıcı, bytecode VM, derleyici ve transpiler backend'leri, dokümantasyon ve mimari tasarım).
- **Çıktı:** Yazılım kullanılarak üretilen her şey; saQut dilinde yazılmış kaynak kodlar (`.sqt` dosyaları), token/AST/sembol tablosu dökümleri, üretilen bytecode, transpile edilmiş kaynak kod, bağımsız çalıştırılabilir dosyalar ve Yazılımın işlediği verilerden elde edilen sonuçlar.
- **Ticari Kullanım:** Yazılımın kendisinden doğrudan veya dolaylı olarak gelir elde edilmesi; Yazılımın bir ürün, hizmet, motor, bileşen veya otomasyon aracı olarak Üçüncü Taraflara sunulması, kurulması ya da onlar adına işletilmesi.
- **Üçüncü Taraf:** Yazılımı kullanan kişi veya kurum dışında kalan müşteri, son kullanıcı ya da diğer taraflar.
#### 3. İnceleme, Değiştirme ve Ticari Olmayan Kullanım İzni
İşbu lisans kapsamında herkese, ücretsiz olarak aşağıdaki haklar tanınır:
- Yazılımı kişisel, eğitsel ve ticari olmayan amaçlarla kullanmak, incelemek ve çalıştırmak.
- Yazılımın kaynak kodunu incelemek ve değiştirmek.
- Değiştirilmiş veya değiştirilmemiş kopyaları ticari olmayan koşullarda dağıtmak. Ancak dağıtılan her kopya; (a) işbu lisansa tabi kalmalı, (b) kaynağıık (source-available) kalmalı ve (c) aşağıdaki Atıf Şartı'na uymalıdır.
#### 4. Çıktı ve Sonuç İstisnası (KRİTİK)
Yazılımı kullanan geliştiricilerin özgürlüğünü güvence altına almak amacıyla:
- **Çıktı sizindir.** Bölüm 2'de tanımlanan tüm Çıktı, işbu lisansın kısıtlamalarına **tabi değildir.** Geliştiriciler kendi Çıktılarını diledikleri gibi kullanma, kapatma (kapalı kaynak yapma), lisanslama ve **ticari olarak satma** hakkına tam olarak sahiptir.
- **Gelir, Çıktıdan elde edilir.** Yazılımı kendi makinenizde (kişisel veya kurumsal) özel bir araç olarak kullanıp ürettiğiniz programları, bağımsız çalıştırılabilir dosyaları veya işlenmiş verileri (örneğin bir Excel raporu veya bir veritabanı sonucu) satmanız serbesttir. Bu durumda Üçüncü Taraf, Yazılımı değil yalnızca sonucu alır.
#### 5. Ticari Kısıtlamalar
Aşağıdaki kullanımlar, Yazılımın bizzat kendisinden gelir elde edilmesi anlamına geldiğinden, telif hakkı sahibinin önceden yazılı izni olmaksızın yapılamaz:
- Yazılımı bir Üçüncü Taraf'ın sunucusuna veya cihazına kurup çalıştırılması karşılığında ücret almak (örneğin bir müşteri için `saqut run yedek.sql` komutunu çalıştırıp ücret talep etmek).
- Yazılımı çevrimiçi bir hizmet olarak sunmak (Web tabanlı IDE, çevrimiçi derleme veya çalıştırma servisi).
- Yazılımı, Üçüncü Tarafların canlı istekleriyle işleyen ticari bir hizmetin backend'i veya motoru hâline getirmek.
- Yazılımı ticari bir otomasyon/iş hattının (pipeline) aracı olarak işletmek ya da bir yapay zekâ sistemine araç olarak sağlamak.
- Yazılımı ticari bir ürünün alt bileşeni olarak gömmek (embed).
- Yazılımın iç bileşenlerini veya mimari tasarımını (örneğin AST görüntüleme veya optimizasyon algoritmaları) ticari bir özellik ya da ürün olarak yeniden kullanmak.
**Sunucu ve sürüm notu:** Yazılım çalışmak için saQut çalışma zamanına (yorumlayıcı / bytecode VM) ihtiyaç duyduğu sürece, sunucu tarafındaki her ticari kullanım fiilen Yazılımı sunucuya yerleştirmek anlamına gelir ve bu nedenle yukarıdaki kısıtlamalara tabidir. Yazılımın, saQut çalışma zamanına ihtiyaç duymayan bağımsız çalıştırılabilir dosyalar üreten backend'i kullanıma sunulduğunda; bu tür bağımsız Çıktıların sunucuda ticari olarak çalıştırılması Bölüm 4 kapsamında serbesttir.
#### 6. İzin ve Ticari Lisans
Bölüm 5'te sayılan kısıtlamaların tamamı yalnızca telif hakkı sahibine aittir ve istisna tanıma yetkisi münhasıran ona aittir. Bu kullanımlardan herhangi birini gerçekleştirmek isteyen kişi veya kurum, telif hakkı sahibinden (Abdussamed ULUTAŞ) önceden yazılı izin talep edebilir; izin verildiği takdirde ilgili kullanım serbest hâle gelir.
İletişim (ticari lisans talepleri): saqutsoftware+gitea@gmail.com
#### 7. Katkılar (Contributions)
saQut'a katkı herkese açık bir öneri sürecidir; ancak nihai karar münhasıran telif hakkı sahibine aittir.
- Herhangi biri değişiklik önerisi (Pull Request / PR) açabilir. Bir katkının projeye dâhil edilip edilmeyeceğine ve birleştirilip (merge) birleştirilmeyeceğine **yalnızca Abdussamed ULUTAŞ karar verir.** Hiç kimsenin, bir katkısını projeye dâhil ettirme yönünde bir hakkı yoktur.
- Bir katkıyı (kod, belge, tasarım veya başka bir materyal) gönderen kişi, bu katkıyı göndermekle telif hakkı sahibine (Abdussamed ULUTAŞ); katkı üzerinde **dünya çapında, süresiz, geri alınamaz, ücretsiz ve alt-lisans verilebilir** bir kullanma, çoğaltma, değiştirme, dağıtma ve **ticari olarak lisanslama** hakkı tanır. Bu hak, telif hakkı sahibinin katkıyı içeren Yazılımı Bölüm 6 kapsamında ticari olarak lisanslayabilmesini güvence altına alır.
- Katkıda bulunan; gönderdiği materyalin kendi eseri olduğunu veya gerekli haklara sahip bulunduğunu ve bu izni vermeye yetkili olduğunu beyan eder. Katkıda bulunanlar, kendi katkıları üzerindeki telif haklarını korur; yukarıdaki izin bu haklara ek olarak verilir.
#### 8. Patent Hakları
- **Patent lisansı:** İşbu lisans kapsamında Yazılımı kullanma hakkına sahip olan her kişiye; telif hakkı sahibi ve katkıda bulunanlar tarafından sahip olunan ve Yazılımın bu lisansça izin verilen biçimde kullanılması için zorunlu olarak ihlal edilen patent istemleri bakımından, ücretsiz ve (aşağıdaki fesih hükmü saklı kalmak kaydıyla) geri alınamaz bir patent lisansı tanınır.
- **Patent misillemesi (otomatik fesih):** Eğer bir kişi veya kurum, Yazılımın bu lisansça izin verilen kullanımının bir patenti ihlal ettiğini ileri sürerek telif hakkı sahibine veya herhangi bir katkıda bulunana karşı **patent davası** açarsa, işbu lisans kapsamında o kişiye/kuruma tanınan tüm haklar (patent lisansı dâhil) **otomatik olarak sona erer.**
#### 9. Marka ve İsim Hakları
İşbu lisans; "saQut" adı, logosu veya ilgili marka unsurları üzerinde **hiçbir hak tanımaz.** Özellikle:
- Yazılımın değiştirilmiş bir sürümünü dağıtırsanız, bu sürümü "saQut" adıyla veya bu adı çağrıştıracak ya da karıştırılmaya yol açabilecek bir adla adlandıramazsınız.
- Telif hakkı sahibinin önceden yazılı izni olmadan, "saQut" adını ürünlerinizde, hizmetlerinizde veya tanıtımlarınızda bir onay/destek ima edecek biçimde kullanamazsınız.
- Yazılımın kaynağına ve telif hakkı sahibine yapılan dürüst ve tanımlayıcı atıflar (örneğin "saQut tabanlıdır") bu maddenin kapsamı dışındadır.
#### 10. Atıf Şartı
Orijinal telif hakkı bildirimi ile işbu izin bildirimi, Yazılımın tüm kopyalarına veya önemli parçalarına dâhil edilmelidir.
#### 11. Fesih (Termination)
- İşbu lisansın koşullarından herhangi birini ihlal etmeniz hâlinde, lisans kapsamında size tanınan tüm haklar **otomatik olarak sona erer.**
- İhlaliniz düzeltilebilir nitelikteyse ve ihlali öğrendikten sonra **30 (otuz) gün** içinde giderirseniz — telif hakkı sahibi bu süre içinde lisansııkça feshetmemiş olmak kaydıyla — haklarınız yeniden yürürlüğe girer. Aynı kişinin tekrarlayan ihlallerinde bu düzeltme imkânı uygulanmaz.
- Haklarınızın sona ermesi, daha önce işbu lisansa uygun olarak edindiğiniz Çıktı (Bölüm 4) üzerindeki haklarınızı etkilemez.
- Garanti reddi ve sorumluluk sınırlamaları, fesihten sonra da yürürlükte kalmaya devam eder.
#### 12. Garanti Reddi
YAZILIM "OLDUĞU GİBİ" SUNULMAKTADIR; TİCARETE UYGUNLUK, BELİRLİ BİR AMACA UYGUNLUK VE İHLAL ETMEME GARANTİLERİ DAHİL ANCAK BUNLARLA SINIRLI OLMAMAK ÜZERE, AÇIK VEYA ZIMNİ HİÇBİR GARANTİ VERİLMEMEKTEDİR. YAZARLAR VEYA TELİF HAKKI SAHİPLERİ, YAZILIMLA VEYA YAZILIMIN KULLANIMIYLA YA DA DİĞER İŞLEMLERLE BAĞLANTILI OLARAK ORTAYA ÇIKAN SÖZLEŞME, HAKSIZ FİİL VEYA DİĞER DURUMLARDAKİ HİÇBİR TALEP, TAZMİNAT VEYA DİĞER YÜKÜMLÜLÜKLERDEN SORUMLU TUTULAMAZ.
---
### English License Version
# The saQut License (Version 1.0)
**Source-Available — Commercial-Use Restricted License**
Copyright (c) 2026, Abdussamed ULUTAŞ (and saQut Contributors). All rights reserved.
This license applies to the saQut compiler, its source code, build scripts, all backend components (the interpreter, the bytecode VM, the compiler, and the transpiler), and the accompanying documentation and architectural design (including the ADR documents) — collectively referred to as "the Software".
saQut is an open-source (source-available) project; however, it is **not free/libre software.** While inspecting and modifying the Software is permitted, its commercial use is subject to the terms of this license and to the permission of the copyright holder.
#### 1. Core Philosophy (The Toolbox Rule)
saQut is designed as a programmable, inspectable compiler toolbox. Its reason for existence is to keep every stage of the compilation process — tokens, the Abstract Syntax Tree (AST), symbol tables, and the Intermediate Representation (IR) — transparent and observable from the outside. Any redistribution or modification of the Software must preserve this principle of transparency.
#### 2. Definitions
- **The Software:** The saQut compiler and all of its components as defined above (source code, interpreter, bytecode VM, compiler and transpiler backends, documentation, and architectural design).
- **Output:** Anything produced using the Software; source code written in the saQut language (`.sqt` files), token/AST/symbol-table dumps, generated bytecode, transpiled source code, standalone executables, and any results derived from data processed by the Software.
- **Commercial Use:** Deriving revenue, directly or indirectly, from the Software itself; offering, deploying, or operating the Software as a product, service, engine, component, or automation tool for or on behalf of Third Parties.
- **Third Party:** Any customer, end user, or other party other than the person or organization using the Software.
#### 3. Permission to Inspect, Modify, and Use Non-Commercially
This license grants everyone, free of charge, the following rights:
- To use, inspect, and run the Software for personal, educational, and non-commercial purposes.
- To inspect and modify the source code of the Software.
- To distribute modified or unmodified copies under non-commercial terms, provided that each distributed copy (a) remains under this license, (b) remains source-available, and (c) complies with the Attribution Requirement below.
#### 4. The Output & Results Exception (CRITICAL)
To safeguard the freedom of developers using the Software:
- **Your Output is yours.** All Output as defined in Section 2 is **not** subject to the restrictions of this license. Developers retain the full right to use, close (make proprietary), license, and **sell commercially** their own Output.
- **Revenue is earned from the Output.** You are free to use the Software as a private tool on your own machine (personal or corporate) and to sell the programs, standalone executables, or processed data you produce (for example, an Excel report or a database result). In such cases the Third Party receives only the result, not the Software.
#### 5. Commercial Restrictions
Because the following uses amount to deriving revenue from the Software itself, they may not be carried out without the prior written permission of the copyright holder:
- Installing the Software on a Third Party's server or device and charging for its execution (for example, running `saqut run backup.sql` for a customer for a fee).
- Offering the Software as an online service (a web-based IDE, or an online compilation or execution service).
- Making the Software the backend or engine of a commercial service that is driven by the live requests of Third Parties.
- Operating the Software as a tool within a commercial automation pipeline, or providing it as a tool to an artificial-intelligence system.
- Embedding the Software as a sub-component of a commercial product.
- Repurposing the internal components or architectural design of the Software (for example, its AST visualization or optimization algorithms) as a commercial feature or product.
**Server and version note:** As long as the Software requires the saQut runtime (the interpreter / bytecode VM) in order to run, any commercial server-side use effectively places the Software on the server and is therefore subject to the restrictions above. Once a backend that produces standalone executables not requiring the saQut runtime becomes available, running such standalone Output commercially on a server is permitted under Section 4.
#### 6. Permission and Commercial Licensing
All restrictions listed in Section 5 belong solely to the copyright holder, who has the exclusive authority to grant exceptions. Any person or organization wishing to carry out any of these uses may request prior written permission from the copyright holder (Abdussamed ULUTAŞ); once granted, the relevant use becomes permitted.
Contact (commercial-license requests): saqutsoftware+gitea@gmail.com
#### 7. Contributions
Contributing to saQut is an open proposal process; however, the final decision rests solely with the copyright holder.
- Anyone may open a change proposal (a Pull Request / PR). Whether a contribution is included in the project and whether it is merged is decided **solely by Abdussamed ULUTAŞ.** No one has any right to have their contribution included in the project.
- By submitting a contribution (code, documentation, design, or other material), the contributor grants the copyright holder (Abdussamed ULUTAŞ) a **worldwide, perpetual, irrevocable, royalty-free, and sublicensable** right to use, reproduce, modify, distribute, and **license commercially** that contribution. This right ensures that the copyright holder may license the Software including the contribution on a commercial basis under Section 6.
- The contributor represents that the submitted material is their own work or that they hold the necessary rights, and that they are authorized to grant this permission. Contributors retain copyright in their own contributions; the permission above is granted in addition to those rights.
#### 8. Patent Rights
- **Patent license:** Subject to this license, each person who has the right to use the Software is granted a royalty-free and (except as stated in the termination provision below) irrevocable patent license, under those patent claims owned by the copyright holder and contributors that are necessarily infringed by using the Software in the manner permitted by this license.
- **Patent retaliation (automatic termination):** If any person or entity initiates **patent litigation** against the copyright holder or any contributor, alleging that the use of the Software as permitted by this license infringes a patent, then all rights granted to that person or entity under this license (including the patent license) **terminate automatically.**
#### 9. Trademark and Name Rights
This license grants **no rights** in the "saQut" name, logo, or related trademark elements. In particular:
- If you distribute a modified version of the Software, you may not name that version "saQut" or use a name that evokes or is confusingly similar to it.
- You may not use the "saQut" name in your products, services, or promotions in a way that implies endorsement, without the prior written permission of the copyright holder.
- Honest, descriptive references to the origin of the Software and to the copyright holder (for example, "based on saQut") fall outside the scope of this section.
#### 10. Attribution Requirement
The original copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#### 11. Termination
- Upon your breach of any of the terms of this license, all rights granted to you under it **terminate automatically.**
- If your breach is curable and you cure it within **30 (thirty) days** of becoming aware of it — provided the copyright holder has not expressly terminated the license during that period — your rights are reinstated. This cure opportunity does not apply to repeated breaches by the same person.
- Termination of your rights does not affect your rights in any Output (Section 4) you previously obtained in compliance with this license.
- The disclaimer of warranty and the limitations of liability survive termination.
#### 12. Disclaimer of Warranty
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Deutsche Lizenzversion
# Die saQut-Lizenz (Version 1.0)
**Quelloffene Lizenz mit eingeschränkter kommerzieller Nutzung**
Copyright (c) 2026, Abdussamed ULUTAŞ (und saQut-Mitwirkende). Alle Rechte vorbehalten.
Diese Lizenz gilt für den saQut-Compiler, seinen Quellcode, die Build-Skripte, alle Backend-Komponenten (den Interpreter, die Bytecode-VM, den Compiler und den Transpiler) sowie die dazugehörige Dokumentation und den architektonischen Entwurf (einschließlich der ADR-Dokumente) — zusammenfassend als „die Software" bezeichnet.
saQut ist ein quelloffenes (einsehbares) Projekt; es ist jedoch **keine freie Software (Free/Libre Software).** Während das Einsehen und Verändern der Software gestattet ist, unterliegt ihre kommerzielle Nutzung den Bedingungen dieser Lizenz und der Genehmigung des Urheberrechtsinhabers.
#### 1. Die Kernphilosophie (Die Toolbox-Regel)
saQut ist als programmierbare, inspizierbare Compiler-Toolbox konzipiert. Ihr Daseinszweck ist es, jede Phase des Kompilierungsprozesses — Tokens, den Abstrakten Syntaxbaum (AST), Symboltabellen und die Zwischendarstellung (IR) — von außen transparent und einsehbar zu halten. Jede Weitergabe oder Veränderung der Software muss diesen Grundsatz der Transparenz wahren.
#### 2. Definitionen
- **Die Software:** Der oben definierte saQut-Compiler und alle seine Komponenten (Quellcode, Interpreter, Bytecode-VM, Compiler- und Transpiler-Backends, Dokumentation und architektonischer Entwurf).
- **Ausgabe:** Alles, was mithilfe der Software erzeugt wird; in der saQut-Sprache geschriebener Quellcode (`.sqt`-Dateien), Token-/AST-/Symboltabellen-Ausgaben, erzeugter Bytecode, transpilierter Quellcode, eigenständige ausführbare Dateien sowie alle Ergebnisse, die aus von der Software verarbeiteten Daten gewonnen werden.
- **Kommerzielle Nutzung:** Das direkte oder indirekte Erzielen von Einnahmen aus der Software selbst; das Anbieten, Bereitstellen oder Betreiben der Software als Produkt, Dienst, Engine, Komponente oder Automatisierungswerkzeug für oder im Auftrag von Dritten.
- **Dritte:** Jeder Kunde, Endnutzer oder sonstige Partei außer der Person oder Organisation, die die Software nutzt.
#### 3. Genehmigung zum Einsehen, Verändern und zur nicht-kommerziellen Nutzung
Diese Lizenz gewährt jeder Person kostenlos die folgenden Rechte:
- Die Software zu persönlichen, schulischen/bildenden und nicht-kommerziellen Zwecken zu nutzen, einzusehen und auszuführen.
- Den Quellcode der Software einzusehen und zu verändern.
- Veränderte oder unveränderte Kopien unter nicht-kommerziellen Bedingungen weiterzugeben, sofern jede weitergegebene Kopie (a) dieser Lizenz unterstellt bleibt, (b) quelloffen (source-available) bleibt und (c) der nachstehenden Namensnennung-Bedingung entspricht.
#### 4. Die Ausnahme für Ausgabe und Ergebnisse (KRITISCH)
Um die Freiheit der Entwickler zu gewährleisten, die die Software nutzen:
- **Ihre Ausgabe gehört Ihnen.** Die gesamte in Abschnitt 2 definierte Ausgabe unterliegt **nicht** den Beschränkungen dieser Lizenz. Entwickler behalten das uneingeschränkte Recht, ihre eigene Ausgabe zu nutzen, zu schließen (proprietär zu machen), zu lizenzieren und **kommerziell zu verkaufen.**
- **Einnahmen werden aus der Ausgabe erzielt.** Es steht Ihnen frei, die Software als privates Werkzeug auf Ihrem eigenen Rechner (privat oder geschäftlich) zu nutzen und die von Ihnen erzeugten Programme, eigenständigen ausführbaren Dateien oder verarbeiteten Daten (etwa einen Excel-Bericht oder ein Datenbankergebnis) zu verkaufen. In diesem Fall erhält der Dritte nur das Ergebnis, nicht die Software.
#### 5. Kommerzielle Beschränkungen
Da die folgenden Nutzungen darauf hinauslaufen, Einnahmen aus der Software selbst zu erzielen, dürfen sie ohne vorherige schriftliche Genehmigung des Urheberrechtsinhabers nicht vorgenommen werden:
- Die Software auf dem Server oder Gerät eines Dritten zu installieren und für ihre Ausführung ein Entgelt zu verlangen (zum Beispiel das Ausführen von `saqut run backup.sql` für einen Kunden gegen Bezahlung).
- Die Software als Online-Dienst anzubieten (eine webbasierte IDE oder einen Online-Kompilier- oder -Ausführungsdienst).
- Die Software zum Backend oder zur Engine eines kommerziellen Dienstes zu machen, der durch die Live-Anfragen Dritter angetrieben wird.
- Die Software als Werkzeug innerhalb einer kommerziellen Automatisierungs-Pipeline zu betreiben oder sie einem System künstlicher Intelligenz als Werkzeug bereitzustellen.
- Die Software als Unterkomponente eines kommerziellen Produkts einzubetten (embedden).
- Die internen Komponenten oder den architektonischen Entwurf der Software (zum Beispiel ihre AST-Visualisierung oder Optimierungsalgorithmen) als kommerzielles Merkmal oder Produkt wiederzuverwenden.
**Server- und Versionshinweis:** Solange die Software zur Ausführung die saQut-Laufzeitumgebung (den Interpreter / die Bytecode-VM) benötigt, bedeutet jede kommerzielle serverseitige Nutzung faktisch das Platzieren der Software auf dem Server und unterliegt daher den obigen Beschränkungen. Sobald ein Backend verfügbar ist, das eigenständige ausführbare Dateien erzeugt, die die saQut-Laufzeitumgebung nicht benötigen, ist das kommerzielle Ausführen einer solchen eigenständigen Ausgabe auf einem Server gemäß Abschnitt 4 gestattet.
#### 6. Genehmigung und kommerzielle Lizenzierung
Alle in Abschnitt 5 aufgeführten Beschränkungen stehen ausschließlich dem Urheberrechtsinhaber zu, der allein befugt ist, Ausnahmen zu gewähren. Jede Person oder Organisation, die eine dieser Nutzungen vornehmen möchte, kann beim Urheberrechtsinhaber (Abdussamed ULUTAŞ) eine vorherige schriftliche Genehmigung beantragen; nach deren Erteilung wird die betreffende Nutzung gestattet.
Kontakt (Anfragen für kommerzielle Lizenzen): saqutsoftware+gitea@gmail.com
#### 7. Beiträge (Contributions)
Das Beitragen zu saQut ist ein offener Vorschlagsprozess; die endgültige Entscheidung liegt jedoch ausschließlich beim Urheberrechtsinhaber.
- Jede Person kann einen Änderungsvorschlag (einen Pull Request / PR) einreichen. Ob ein Beitrag in das Projekt aufgenommen und ob er zusammengeführt (gemerged) wird, entscheidet **allein Abdussamed ULUTAŞ.** Niemand hat ein Recht darauf, dass sein Beitrag in das Projekt aufgenommen wird.
- Mit der Einreichung eines Beitrags (Code, Dokumentation, Entwurf oder sonstiges Material) gewährt der Beitragende dem Urheberrechtsinhaber (Abdussamed ULUTAŞ) ein **weltweites, unbefristetes, unwiderrufliches, gebührenfreies und unterlizenzierbares** Recht, diesen Beitrag zu nutzen, zu vervielfältigen, zu verändern, zu verbreiten und **kommerziell zu lizenzieren.** Dieses Recht stellt sicher, dass der Urheberrechtsinhaber die Software einschließlich des Beitrags gemäß Abschnitt 6 kommerziell lizenzieren kann.
- Der Beitragende sichert zu, dass das eingereichte Material sein eigenes Werk ist oder dass er über die erforderlichen Rechte verfügt und befugt ist, diese Genehmigung zu erteilen. Die Beitragenden behalten das Urheberrecht an ihren eigenen Beiträgen; die obige Genehmigung wird zusätzlich zu diesen Rechten erteilt.
#### 8. Patentrechte
- **Patentlizenz:** Im Rahmen dieser Lizenz wird jeder Person, die zur Nutzung der Software berechtigt ist, eine gebührenfreie und (vorbehaltlich der nachstehenden Kündigungsbestimmung) unwiderrufliche Patentlizenz an denjenigen Patentansprüchen gewährt, die im Eigentum des Urheberrechtsinhabers und der Beitragenden stehen und die durch die nach dieser Lizenz gestattete Nutzung der Software notwendigerweise verletzt werden.
- **Patentvergeltung (automatische Kündigung):** Leitet eine Person oder Organisation einen **Patentrechtsstreit** gegen den Urheberrechtsinhaber oder einen Beitragenden ein und macht dabei geltend, dass die nach dieser Lizenz gestattete Nutzung der Software ein Patent verletzt, so **erlöschen automatisch** alle dieser Person oder Organisation nach dieser Lizenz gewährten Rechte (einschließlich der Patentlizenz).
#### 9. Marken- und Namensrechte
Diese Lizenz gewährt **keinerlei Rechte** an dem Namen „saQut", dem Logo oder verwandten Markenbestandteilen. Insbesondere:
- Wenn Sie eine veränderte Version der Software verbreiten, dürfen Sie diese Version nicht „saQut" nennen oder einen Namen verwenden, der daran erinnert oder verwechslungsfähig ähnlich ist.
- Sie dürfen den Namen „saQut" ohne vorherige schriftliche Genehmigung des Urheberrechtsinhabers nicht in Ihren Produkten, Diensten oder Werbemaßnahmen in einer Weise verwenden, die eine Billigung suggeriert.
- Ehrliche, beschreibende Hinweise auf den Ursprung der Software und auf den Urheberrechtsinhaber (zum Beispiel „basiert auf saQut") fallen nicht unter diesen Abschnitt.
#### 10. Namensnennung-Bedingung
Der ursprüngliche Urheberrechtshinweis und dieser Genehmigungshinweis müssen in allen Kopien oder wesentlichen Teilen der Software enthalten sein.
#### 11. Kündigung (Termination)
- Bei einem Verstoß gegen eine der Bedingungen dieser Lizenz **erlöschen automatisch** alle Ihnen darunter gewährten Rechte.
- Ist Ihr Verstoß heilbar und beheben Sie ihn innerhalb von **30 (dreißig) Tagen**, nachdem Sie davon Kenntnis erlangt haben — sofern der Urheberrechtsinhaber die Lizenz in diesem Zeitraum nicht ausdrücklich gekündigt hat —, so werden Ihre Rechte wiederhergestellt. Diese Heilungsmöglichkeit gilt nicht für wiederholte Verstöße derselben Person.
- Das Erlöschen Ihrer Rechte berührt nicht Ihre Rechte an einer Ausgabe (Abschnitt 4), die Sie zuvor in Übereinstimmung mit dieser Lizenz erlangt haben.
- Der Haftungsausschluss und die Haftungsbeschränkungen gelten auch nach der Kündigung fort.
#### 12. Haftungsausschluss
DIE SOFTWARE WIRD „WIE BESEHEN" (AS IS) OHNE JEGLICHE AUSDRÜCKLICHE ODER STILLSCHWEIGENDE GEWÄHRLEISTUNG ZUR VERFÜGUNG GESTELLT, EINSCHLIESSLICH, ABER NICHT BESCHRÄNKT AUF DIE GEWÄHRLEISTUNG DER MARKTGÄNGIGKEIT, DER EIGNUNG FÜR EINEN BESTIMMTEN ZWECK UND DER NICHTVERLETZUNG VON RECHTEN DRITTER. IN KEINEM FALL SIND DIE AUTOREN ODER URHEBERRECHTSINHABER FÜR ANSPRÜCHE, SCHÄDEN ODER ANDERE HAFTUNGEN HAFTBAR, SEI ES IN FOLGE EINES VERTRAGES, EINER UNERLAUBTEN HANDLUNG ODER AUF ANDERE WEISE, DIE SICH AUS ODER IM ZUSAMMENHANG MIT DER SOFTWARE ODER DER NUTZUNG ODER DEM UMGANG MIT DER SOFTWARE ERGEBEN.

139
TODO.md
View File

@ -1,139 +0,0 @@
# TODO — Teknik Borçlar ve Ertelenen Kararlar
Bu dosya, kasıtlı olarak ertelenen teknik kararları ve ileride ele alınması gereken
tasarım noktalarını tutar. Her giriş hangi issue'ya bağlı olduğunu belirtir.
---
## ✅ TAMAMLANDI — GC-hazır nesne modeli + array runtime (2026-06-20)
ADR-020…024 (değer/referans semantiği, null güvenliği, mark-sweep GC, eşitlik)
doğrultusunda uçtan uca array çalışıyor:
- `src/vm/object.hpp` — Object, ArrayObject, Heap (v1: toplama yok, GC-hazır header)
- `src/vm/value.hpp` — ValueKind::Ref + Null eklendi (dil anahtar sözcüğü `null`, `nil` DEĞİL)
- `src/ir/instruction.hpp` — ARRAY_NEW/GET/SET/LEN eklendi
- Array literal parser (`[1,2,3]`), `int[]` tip sözdizimi (Java/C# stili)
- Referans semantiği, kimlik `==` (ADR-023), sınır kontrolü
- Golden test: `tests/golden/array/ref_semantics.sqt`
## ✅ TAMAMLANDI — Struct runtime + E010 revizyonu (2026-06-20)
ADR-020 doğrultusunda struct referans semantiğiyle uçtan uca çalışıyor:
- `src/vm/object.hpp` — StructObject : Object, alan erişimi (GC-hazır header)
- `src/vm/value.hpp` — ValueKind::Null eklendi (dil anahtar sözcüğü `null`)
- E010 revizyonu: referansla tutulan `struct Node { Node next; }` artık meşru
(döngü kurulabilir, GC v2 ile toplanacak)
## ✅ TAMAMLANDI — float/double aritmetik runtime (#44) (2026-06-20)
- `src/vm/value.hpp` — ValueKind::Float + floatValue alanı
- IR opcode'ları: FADD/FSUB/FMUL/FDIV + float karşılaştırma
- Literal bağlama-göre tipleme korundu (sabit folding dahil)
## ✅ TAMAMLANDI — String cilası (ADR-024) (2026-06-20)
- `src/core/type.hpp``isString()` yüklem yardımcısı eklendi
- `src/ir/instruction.hpp``STRING_CONCAT` opcode eklendi
- `src/semantic/type_checker.cpp``+` string için izin (her iki taraf `string` → sonuç `string`)
- `src/ir/ir_generator.cpp``generateBinaryArithmetic` string tespiti: `ADD``STRING_CONCAT`; `+=` için de `STRING_CONCAT`
- `src/vm/interpreter.cpp``STRING_CONCAT` case: `stringValue + stringValue`
- `tests/golden/string/concat.sqt` — concat, `+=`, içerik `==` golden testi
- İçerik `==` / `!=` VM'de zaten vardı (ADR-023/024); `print(string)` zaten çalışıyordu
## ✅ TAMAMLANDI — Hata yönetimi (ADR-025, #57) (2026-06-20)
- `src/parser/ast_node.hpp``TryStatement`, `ThrowStatement` ASTKind eklendi
- `src/parser/nodes/statements.hpp/.cpp``TryStatementNode`, `ThrowStatementNode`
- `src/parser/parser_base.hpp` + `parser.cpp``parseTryStatement()`, `parseThrowStatement()`
- `src/ir/instruction.hpp``ENTER_TRY`, `LEAVE_TRY`, `THROW` opcode'ları
- `src/ir/ir_generator.cpp` — try/catch/throw IR üretimi
- `src/vm/interpreter.hpp``TryFrame` struct, `tryStack_`, `pendingThrow_`, `makeErrorValue()`
- `src/vm/interpreter.cpp` — ENTER_TRY/LEAVE_TRY/THROW VM uygulaması; runtime hataları
(DIV/0, array OOB) `pendingThrow_` üzerinden Error nesnesi olarak yakalanabilir hale getirildi
- `src/symbol/symbol_collector.cpp``Error` builtin struct kaydı (alan sırası: line,col,message,trace,code)
- `src/semantic/type_checker.cpp` — TryStatement/ThrowStatement tip kontrolü (unchecked)
- `tests/golden/error/basic_catch.sqt` — sıfıra bölme yakalama
- `tests/golden/error/throw_and_nested.sqt` — iç içe fonksiyon unwind + array OOB + throw
- **Not:** IR satır tablosu (stacktrace doldurma) ertelendi — trace alanı boş kalıyor
## ✅ TAMAMLANDI — Null akış-analizi (ADR-021) (2026-06-20)
- `src/core/type.hpp``bool nullable` alanı; `asNullable()`, `asNonNull()`, `equalsBase()`, `isNullLiteral()` yardımcıları; `fromName("int?")` desteği; `toString()``int?`
- `src/parser/parser.cpp``?` suffix ayrıştırma (değişken, parametre, dönüş tipi); dispatch'te `int? f()``parseFunctionDecl()` yönlendirmesi düzeltildi
- `src/ir/instruction.hpp``LOAD_NULL` opcode eklendi
- `src/ir/ir_generator.cpp``LiteralType::BOŞ``LOAD_NULL`
- `src/vm/interpreter.cpp``LOAD_NULL` case → `Value::null()`
- `src/semantic/type_checker.hpp``narrowedNonNull_` set; `extractNullCheck()`, `alwaysExits()` yardımcıları
- `src/semantic/type_checker.cpp`:
- `checkAssign`: `T? ← null` OK; `T ← T?` hata (E003); `T? ← T` OK (widening)
- `checkExpr Literal BOŞ`: null sentinel tipi (`Void+nullable`)
- `checkExpr Identifier`: `narrowedNonNull_`'dan non-null olduğu bilinenlerde nullable flag'i kaldırılıyor
- `checkExpr BinaryExpression`: `&&` sağ taraf narrowing; nullable operand hatası (E003)
- `checkExpr MemberAccess`: nullable nesne üstünde doğrudan erişim hatası
- `checkStmt Block`: guard pattern (`if (a == null) return;` → sonrasında `a` non-null)
- `checkStmt IfStatement`: nested narrowing (`if (a != null)` → then'de non-null, `if (a == null)` → else'de non-null)
- `tests/golden/null/narrowing.sqt` — nested + guard narrowing, `int?` dönüş tipi ✓
- `tests/golden/null/nullable_assign_error.sqt``T? → T` atama E003 ✓
- `tests/golden/null/nullable_operand_error.sqt` — nullable aritmetik operand E003 ✓
- `tests/golden/null/and_narrowing.sqt``&&` sağ taraf narrowing ✓
## 🚀 SIRADAKİ İŞ
1. **mark-sweep GC v2 (#56)** — en son; özellik bloklamaz, en karmaşık. Trigger basit
"her N tahsiste" yeter; nesne modeli zaten GC-hazır.
ık mimari borçlar: **#56** (döngüsel referans → mark-sweep GC v2), **#57** (hata
modeli görünürlük alt-ekseni).
> ⚠️ **Terminoloji kilidi (Sonnet):** anlaşılan isimleri değiştirme/icat etme.
> Dil anahtar sözcüğü **`null`** (`nil` değil), array literal **`[...]`** (`{...}` değil),
> hata tipi **`Error`**. İsmi belirsizse **icat etme, Opus'a sor.** Ayrıntı:
> `docs/sonnet-handoff.md` Bölüm 6 (terminoloji kilidi).
---
## #modül-scope — IRFunction.moduleId: Modül-düzeyi değişken izolasyonu
**Etkilenen dosyalar:**
- `src/ir/instruction.hpp``LOAD_GLOBAL` / `STORE_GLOBAL` yorumları
- `src/ir/ir_program.hpp``globalCount`, `globalNames`
- `src/vm/interpreter.hpp``globalSlots_`
- `src/vm/interpreter.cpp``LOAD_GLOBAL` / `STORE_GLOBAL` case'leri
**Mevcut durum (tek dosya):**
`LOAD_GLOBAL dest, N``globalSlots_[N]` — düz vektör, tek modül varsayımı.
Tek dosyada bu doğru çalışır; `globalSlots_[0]` her zaman bu dosyanın 0. modül-değişkenidir.
**Çok modüllü derlemede yapılması gereken:**
Her `IRFunction`'a `std::string moduleId` (veya `int moduleIndex`) alanı ekle.
`Interpreter`'da `globalSlots_` yerine `std::unordered_map<std::string, std::vector<Value>> moduleSlots_` tut.
`LOAD_GLOBAL` çalışırken `frame.function->moduleId` ile doğru modülün slot alanına bak.
```
// Hedef tasarım (modül sistemi gelince):
case Opcode::LOAD_GLOBAL:
frame.slots[instr.dest] = moduleSlots_[frame.function->moduleId][instr.intValue];
break;
```
**Ne zaman:** Modül sistemi issue'ları (#3 import sözdizimi, #4 görünürlük, #5 çoklu dosya)
ele alınırken bu değişikliği de kapsama al.
---
## #sembol-modül — Symbol.sourceModule: Sembol tablosunda açık modül kimliği
**Etkilenen dosyalar:**
- `src/symbol/symbol.hpp``Symbol` struct
**Mevcut durum:**
`Symbol.definitionLoc.filePath` dosya yolunu tutuyor — modül bilgisi dolaylı olarak var.
Ama doğrudan `moduleId` / `moduleName` alanı yok; filtre/lookup için her seferinde
`definitionLoc.filePath`'i ayrıştırmak gerekir.
**Yapılması gereken:**
`Symbol` struct'ına `std::string sourceModule` alanı ekle (modül adı veya dosya yolu).
Özellikle cross-module sembol çözümleme, LSP "tanıma git" ve hata mesajlarında
"hangi modülden geldi" bilgisi için kritik.
**Ne zaman:** `#3` (import sözdizimi) veya `#4` (görünürlük) issue'larında.

Binary file not shown.

View File

@ -1,34 +1,16 @@
# ninja log v7
1 9 1781900092189939762 /home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/cmake.verify_globs 1813c41e0f312d7e
10 1691 1781900092199402809 CMakeFiles/saqut.dir/src/ir/ir_program.cpp.o d681b36458a6e5f5
10 1957 1781900092199188672 CMakeFiles/saqut.dir/src/ir/ir_function.cpp.o 85cbc174284792d4
10 5411 1781900092199511505 CMakeFiles/saqut.dir/src/lexer/lexer.cpp.o 90eeec811f2137e6
10 5413 1781900092198939716 CMakeFiles/saqut.dir/src/core/sourcefile.cpp.o da6f5fc90e87e6b1
10 6729 1781900092199847028 CMakeFiles/saqut.dir/src/parser/nodes/declarations.cpp.o b6c56f04a257f685
15 7732 1781900092203939691 CMakeFiles/saqut.dir/src/parser/nodes/expressions.cpp.o 4057e3d63c63a1ab
10 8908 1781900092199302769 CMakeFiles/saqut.dir/src/ir/ir_generator.cpp.o 84c9f816f969cfa7
10 9701 1781900092199743167 CMakeFiles/saqut.dir/src/parser/nodes/binary_expr.cpp.o d2e2bb2f8a63c6d2
1709 9770 1781900093898639567 CMakeFiles/saqut.dir/src/parser/nodes/literal.cpp.o 78f2c4da7c9b2281
15 10364 1781900092204948414 CMakeFiles/saqut.dir/src/parser/nodes/identifier.cpp.o eb96bb4b1eb4ad80
1957 11871 1781900094145929879 CMakeFiles/saqut.dir/src/parser/nodes/program.cpp.o ac5bbcd74d87561a
9770 11899 1781900101958890478 CMakeFiles/saqut.dir/src/vm/interpreter.cpp.o 88078036625564ef
5413 11959 1781900097601912436 CMakeFiles/saqut.dir/src/parser/parser.cpp.o 2c65b7be26cead32
10 12284 1781900092199621706 CMakeFiles/saqut.dir/src/main.cpp.o 110c26cb1d0c3a23
6729 13187 1781900098917905800 CMakeFiles/saqut.dir/src/semantic/structural_validator.cpp.o 4bfec8abc0e9893e
5412 13356 1781900097601088348 CMakeFiles/saqut.dir/src/parser/nodes/statements.cpp.o b5c20724bbf3648c
7733 14099 1781900099922227854 CMakeFiles/saqut.dir/src/semantic/type_checker.cpp.o 15f44776b9c3e26d
9701 14179 1781900101889890826 CMakeFiles/saqut.dir/src/tokenizer/tokenizer.cpp.o a01677f8bb4f4dbc
8908 14635 1781900101096894819 CMakeFiles/saqut.dir/src/symbol/symbol_collector.cpp.o 3348f498f369213d
14635 14953 1781900106823866003 saqut 8f3d7184b374150b
2 17 1781900144964675644 /home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/cmake.verify_globs 1813c41e0f312d7e
18 4193 1781900144981580253 CMakeFiles/saqut.dir/src/semantic/structural_validator.cpp.o 4bfec8abc0e9893e
18 4260 1781900144981478187 CMakeFiles/saqut.dir/src/parser/parser.cpp.o 2c65b7be26cead32
18 4852 1781900144981695435 CMakeFiles/saqut.dir/src/semantic/type_checker.cpp.o 15f44776b9c3e26d
18 4914 1781900144981374397 CMakeFiles/saqut.dir/src/parser/nodes/declarations.cpp.o b6c56f04a257f685
18 5211 1781900144980675565 CMakeFiles/saqut.dir/src/ir/ir_generator.cpp.o 84c9f816f969cfa7
18 5324 1781900144981813038 CMakeFiles/saqut.dir/src/symbol/symbol_collector.cpp.o 3348f498f369213d
18 6912 1781900144981279910 CMakeFiles/saqut.dir/src/main.cpp.o 110c26cb1d0c3a23
6912 7184 1781900151874641436 saqut 8f3d7184b374150b
1 8 1781900314792856660 /home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/cmake.verify_globs 1813c41e0f312d7e
9 4869 1781900314800856623 CMakeFiles/saqut.dir/src/main.cpp.o 110c26cb1d0c3a23
4869 5168 1781900319660833784 saqut 8f3d7184b374150b
1 1875 1779866878396024286 CMakeFiles/saqut.dir/src/parser/nodes/identifier.cpp.o eb96bb4b1eb4ad80
1 1743 1779866878396133191 CMakeFiles/saqut.dir/src/parser/nodes/literal.cpp.o 78f2c4da7c9b2281
1 1835 1779866851291850429 CMakeFiles/saqut.dir/src/parser/nodes/binary_expr.cpp.o d2e2bb2f8a63c6d2
3 1976 1779866851293202930 CMakeFiles/saqut.dir/src/parser/nodes/program.cpp.o ac5bbcd74d87561a
1 1828 1779866851291959426 CMakeFiles/saqut.dir/src/parser/nodes/declarations.cpp.o b6c56f04a257f685
1 1991 1779866851292085983 CMakeFiles/saqut.dir/src/parser/nodes/expressions.cpp.o 4057e3d63c63a1ab
6 2108 1779866851296202934 CMakeFiles/saqut.dir/src/parser/nodes/statements.cpp.o b5c20724bbf3648c
1 2478 1779866878395241768 CMakeFiles/saqut.dir/src/main.cpp.o 110c26cb1d0c3a23
2967 3100 1779866359829193015 saqut 78d8bacf305cfc59
1 1450 1779866851291202927 CMakeFiles/saqut.dir/src/lexer/lexer.cpp.o 90eeec811f2137e6
0 1481 1779866851290202926 CMakeFiles/saqut.dir/src/core/sourcefile.cpp.o da6f5fc90e87e6b1
1 1410 1779866878396365249 CMakeFiles/saqut.dir/src/tokenizer/tokenizer.cpp.o a01677f8bb4f4dbc
1 1579 1779866878396233551 CMakeFiles/saqut.dir/src/parser/parser.cpp.o 2c65b7be26cead32
1 1163 1779866916763301383 CMakeFiles/saqut.dir/src/parser/parser.cpp.o 2c65b7be26cead32
1163 1283 1779866917925303269 saqut 89052e51305cb697

View File

@ -24,8 +24,8 @@ CMAKE_AR:FILEPATH=/usr/bin/ar
// MinSizeRel ...
CMAKE_BUILD_TYPE:STRING=Debug
//No help, variable specified on the command line.
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++
//CXX compiler
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++
//A wrapper around 'ar' adding the appropriate '--plugin' option
// for the GCC compiler
@ -50,9 +50,6 @@ CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
//Flags used by the CXX compiler during RELWITHDEBINFO builds.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//No help, variable specified on the command line.
CMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc
//Path to a program.
CMAKE_DLLTOOL:FILEPATH=CMAKE_DLLTOOL-NOTFOUND
@ -74,8 +71,8 @@ CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Enable/Disable output of build database during the build.
CMAKE_EXPORT_BUILD_DATABASE:BOOL=
//No help, variable specified on the command line.
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE
//Enable/Disable output of compile commands during generation.
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=
//Value Computed by CMake.
CMAKE_FIND_PACKAGE_REDIRECTS_DIR:STATIC=/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/pkgRedirects
@ -238,7 +235,7 @@ CMAKE_CACHE_MAJOR_VERSION:INTERNAL=4
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=3
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=3
CMAKE_CACHE_PATCH_VERSION:INTERNAL=2
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
//Path to cpack program executable.

View File

@ -0,0 +1,102 @@
set(CMAKE_CXX_COMPILER "/usr/bin/c++")
set(CMAKE_CXX_COMPILER_ARG1 "")
set(CMAKE_CXX_COMPILER_ID "GNU")
set(CMAKE_CXX_COMPILER_VERSION "16.1.1")
set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "")
set(CMAKE_CXX_COMPILER_WRAPPER "")
set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "20")
set(CMAKE_CXX_EXTENSIONS_COMPUTED_DEFAULT "ON")
set(CMAKE_CXX_STANDARD_LATEST "26")
set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17;cxx_std_20;cxx_std_23;cxx_std_26")
set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters")
set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates")
set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates")
set(CMAKE_CXX17_COMPILE_FEATURES "cxx_std_17")
set(CMAKE_CXX20_COMPILE_FEATURES "cxx_std_20")
set(CMAKE_CXX23_COMPILE_FEATURES "cxx_std_23")
set(CMAKE_CXX26_COMPILE_FEATURES "cxx_std_26")
set(CMAKE_CXX_PLATFORM_ID "Linux")
set(CMAKE_CXX_SIMULATE_ID "")
set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "GNU")
set(CMAKE_CXX_COMPILER_APPLE_SYSROOT "")
set(CMAKE_CXX_SIMULATE_VERSION "")
set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID "x86_64")
set(CMAKE_AR "/usr/bin/ar")
set(CMAKE_CXX_COMPILER_AR "/usr/bin/gcc-ar")
set(CMAKE_RANLIB "/usr/bin/ranlib")
set(CMAKE_CXX_COMPILER_RANLIB "/usr/bin/gcc-ranlib")
set(CMAKE_LINKER "/usr/bin/ld")
set(CMAKE_LINKER_LINK "")
set(CMAKE_LINKER_LLD "")
set(CMAKE_CXX_COMPILER_LINKER "/usr/bin/ld")
set(CMAKE_CXX_COMPILER_LINKER_ID "GNU")
set(CMAKE_CXX_COMPILER_LINKER_VERSION 2.46.0)
set(CMAKE_CXX_COMPILER_LINKER_FRONTEND_VARIANT GNU)
set(CMAKE_MT "")
set(CMAKE_TAPI "CMAKE_TAPI-NOTFOUND")
set(CMAKE_COMPILER_IS_GNUCXX 1)
set(CMAKE_CXX_COMPILER_LOADED 1)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_CXX_ABI_COMPILED TRUE)
set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
set(CMAKE_CXX_COMPILER_ID_RUN 1)
set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;mpp;CPP;ixx;cppm;ccm;cxxm;c++m)
set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
foreach (lang IN ITEMS C OBJC OBJCXX)
if (CMAKE_${lang}_COMPILER_ID_RUN)
foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS)
list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension})
endforeach()
endif()
endforeach()
set(CMAKE_CXX_LINKER_PREFERENCE 30)
set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
set(CMAKE_CXX_LINKER_DEPFILE_SUPPORTED TRUE)
set(CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED TRUE)
set(CMAKE_CXX_LINKER_PUSHPOP_STATE_SUPPORTED TRUE)
# Save compiler ABI information.
set(CMAKE_CXX_SIZEOF_DATA_PTR "8")
set(CMAKE_CXX_COMPILER_ABI "ELF")
set(CMAKE_CXX_BYTE_ORDER "LITTLE_ENDIAN")
set(CMAKE_CXX_LIBRARY_ARCHITECTURE "")
if(CMAKE_CXX_SIZEOF_DATA_PTR)
set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
endif()
if(CMAKE_CXX_COMPILER_ABI)
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
endif()
if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
set(CMAKE_LIBRARY_ARCHITECTURE "")
endif()
set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "")
if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX)
set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}")
endif()
set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include/c++/16.1.1;/usr/include/c++/16.1.1/x86_64-pc-linux-gnu;/usr/include/c++/16.1.1/backward;/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/include;/usr/local/include;/usr/include")
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;gcc_s;gcc;atomic_asneeded;c;gcc_s;gcc")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1;/usr/lib;/lib")
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
set(CMAKE_CXX_COMPILER_CLANG_RESOURCE_DIR "")
set(CMAKE_CXX_COMPILER_IMPORT_STD "")
set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "Experimental `import std` support not enabled when detecting toolchain; it must be set before `CXX` is enabled (usually a `project()` call)")
set(CMAKE_CXX_STDLIB_MODULES_JSON "")

Binary file not shown.

View File

@ -0,0 +1,15 @@
set(CMAKE_HOST_SYSTEM "Linux-7.0.9-1-MANJARO")
set(CMAKE_HOST_SYSTEM_NAME "Linux")
set(CMAKE_HOST_SYSTEM_VERSION "7.0.9-1-MANJARO")
set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64")
set(CMAKE_SYSTEM "Linux-7.0.9-1-MANJARO")
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_VERSION "7.0.9-1-MANJARO")
set(CMAKE_SYSTEM_PROCESSOR "x86_64")
set(CMAKE_CROSSCOMPILING "FALSE")
set(CMAKE_SYSTEM_LOADED 1)

View File

@ -0,0 +1,949 @@
/* This source file must have a .cpp extension so that all C++ compilers
recognize the extension without flags. Borland does not know .cxx for
example. */
#ifndef __cplusplus
# error "A C compiler has been selected for C++."
#endif
#if !defined(__has_include)
/* If the compiler does not have __has_include, pretend the answer is
always no. */
# define __has_include(x) 0
#endif
/* Version number components: V=Version, R=Revision, P=Patch
Version date components: YYYY=Year, MM=Month, DD=Day */
#if defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# if defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
except that a few beta releases use the old format with V=2021. */
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
# if defined(__INTEL_COMPILER_UPDATE)
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
# else
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
# endif
# else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
/* The third version component from --version is an update index,
but no macro is provided for it. */
# define COMPILER_VERSION_PATCH DEC(0)
# endif
# if defined(__INTEL_COMPILER_BUILD_DATE)
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
# endif
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
# define COMPILER_ID "IntelLLVM"
#if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
#endif
#if defined(__GNUC__)
# define SIMULATE_ID "GNU"
#endif
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
* VVVV is no smaller than the current year when a version is released.
*/
#if __INTEL_LLVM_COMPILER < 1000000L
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
#else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
#endif
#if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
#endif
#if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
#elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
#endif
#if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
#endif
#if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
#endif
#elif defined(__PATHCC__)
# define COMPILER_ID "PathScale"
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
# if defined(__PATHCC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
# endif
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
# define COMPILER_ID "Embarcadero"
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
#elif defined(__BORLANDC__)
# define COMPILER_ID "Borland"
/* __BORLANDC__ = 0xVRR */
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
# define COMPILER_ID "Watcom"
/* __WATCOMC__ = VVRR */
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__WATCOMC__)
# define COMPILER_ID "OpenWatcom"
/* __WATCOMC__ = VVRP + 1100 */
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__SUNPRO_CC)
# define COMPILER_ID "SunPro"
# if __SUNPRO_CC >= 0x5100
/* __SUNPRO_CC = 0xVRRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# else
/* __SUNPRO_CC = 0xVRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# endif
#elif defined(__HP_aCC)
# define COMPILER_ID "HP"
/* __HP_aCC = VVRRPP */
# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
#elif defined(__DECCXX)
# define COMPILER_ID "Compaq"
/* __DECCXX_VER = VVRRTPPPP */
# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
#elif defined(__IBMCPP__) && defined(__COMPILER_VER__)
# define COMPILER_ID "zOS"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__open_xl__) && defined(__clang__)
# define COMPILER_ID "IBMClang"
# define COMPILER_VERSION_MAJOR DEC(__open_xl_version__)
# define COMPILER_VERSION_MINOR DEC(__open_xl_release__)
# define COMPILER_VERSION_PATCH DEC(__open_xl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__open_xl_ptf_fix_level__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(__ibmxl__) && defined(__clang__)
# define COMPILER_ID "XLClang"
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800
# define COMPILER_ID "XL"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800
# define COMPILER_ID "VisualAge"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__NVCOMPILER)
# define COMPILER_ID "NVHPC"
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
# if defined(__NVCOMPILER_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
# endif
#elif defined(__PGI)
# define COMPILER_ID "PGI"
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
# if defined(__PGIC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
# endif
#elif defined(__clang__) && defined(__cray__)
# define COMPILER_ID "CrayClang"
# define COMPILER_VERSION_MAJOR DEC(__cray_major__)
# define COMPILER_VERSION_MINOR DEC(__cray_minor__)
# define COMPILER_VERSION_PATCH DEC(__cray_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(_CRAYC)
# define COMPILER_ID "Cray"
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__TI_COMPILER_VERSION__)
# define COMPILER_ID "TI"
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
#elif defined(__CLANG_FUJITSU)
# define COMPILER_ID "FujitsuClang"
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(__FUJITSU)
# define COMPILER_ID "Fujitsu"
# if defined(__FCC_version__)
# define COMPILER_VERSION __FCC_version__
# elif defined(__FCC_major__)
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# endif
# if defined(__fcc_version)
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
# elif defined(__FCC_VERSION)
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
# endif
#elif defined(__ghs__)
# define COMPILER_ID "GHS"
/* __GHS_VERSION_NUMBER = VVVVRP */
# ifdef __GHS_VERSION_NUMBER
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
# endif
#elif defined(__TASKING__)
# define COMPILER_ID "Tasking"
# define COMPILER_VERSION_MAJOR DEC(__VERSION__/1000)
# define COMPILER_VERSION_MINOR DEC(__VERSION__ % 100)
# define COMPILER_VERSION_INTERNAL DEC(__VERSION__)
#elif defined(__ORANGEC__)
# define COMPILER_ID "OrangeC"
# define COMPILER_VERSION_MAJOR DEC(__ORANGEC_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__ORANGEC_MINOR__)
# define COMPILER_VERSION_PATCH DEC(__ORANGEC_PATCHLEVEL__)
#elif defined(__RENESAS__)
# define COMPILER_ID "Renesas"
/* __RENESAS_VERSION__ = 0xVVRRPP00 */
# define COMPILER_VERSION_MAJOR HEX(__RENESAS_VERSION__ >> 24 & 0xFF)
# define COMPILER_VERSION_MINOR HEX(__RENESAS_VERSION__ >> 16 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__RENESAS_VERSION__ >> 8 & 0xFF)
#elif defined(__SCO_VERSION__)
# define COMPILER_ID "SCO"
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
# define COMPILER_ID "ARMCC"
#if __ARMCC_VERSION >= 1000000
/* __ARMCC_VERSION = VRRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#else
/* __ARMCC_VERSION = VRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#endif
#elif defined(__clang__) && defined(__apple_build_version__)
# define COMPILER_ID "AppleClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
# define COMPILER_ID "ARMClang"
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION/100 % 100)
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
#elif defined(__clang__) && defined(__ti__)
# define COMPILER_ID "TIClang"
# define COMPILER_VERSION_MAJOR DEC(__ti_major__)
# define COMPILER_VERSION_MINOR DEC(__ti_minor__)
# define COMPILER_VERSION_PATCH DEC(__ti_patchlevel__)
# define COMPILER_VERSION_INTERNAL DEC(__ti_version__)
#elif defined(__clang__)
# define COMPILER_ID "Clang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
#elif defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__))
# define COMPILER_ID "LCC"
# define COMPILER_VERSION_MAJOR DEC(__LCC__ / 100)
# define COMPILER_VERSION_MINOR DEC(__LCC__ % 100)
# if defined(__LCC_MINOR__)
# define COMPILER_VERSION_PATCH DEC(__LCC_MINOR__)
# endif
# if defined(__GNUC__) && defined(__GNUC_MINOR__)
# define SIMULATE_ID "GNU"
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
# endif
#elif defined(__GNUC__) || defined(__GNUG__)
# define COMPILER_ID "GNU"
# if defined(__GNUC__)
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
# else
# define COMPILER_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(_MSC_VER)
# define COMPILER_ID "MSVC"
/* _MSC_VER = VVRR */
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
# if defined(_MSC_FULL_VER)
# if _MSC_VER >= 1400
/* _MSC_FULL_VER = VVRRPPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
# else
/* _MSC_FULL_VER = VVRRPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
# endif
# endif
# if defined(_MSC_BUILD)
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
# endif
#elif defined(_ADI_COMPILER)
# define COMPILER_ID "ADSP"
#if defined(__VERSIONNUM__)
/* __VERSIONNUM__ = 0xVVRRPPTT */
# define COMPILER_VERSION_MAJOR DEC(__VERSIONNUM__ >> 24 & 0xFF)
# define COMPILER_VERSION_MINOR DEC(__VERSIONNUM__ >> 16 & 0xFF)
# define COMPILER_VERSION_PATCH DEC(__VERSIONNUM__ >> 8 & 0xFF)
# define COMPILER_VERSION_TWEAK DEC(__VERSIONNUM__ & 0xFF)
#endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"
# if defined(__VER__) && defined(__ICCARM__)
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# endif
#elif defined(__DCC__) && defined(_DIAB_TOOL)
# define COMPILER_ID "Diab"
# define COMPILER_VERSION_MAJOR DEC(__VERSION_MAJOR_NUMBER__)
# define COMPILER_VERSION_MINOR DEC(__VERSION_MINOR_NUMBER__)
# define COMPILER_VERSION_PATCH DEC(__VERSION_ARCH_FEATURE_NUMBER__)
# define COMPILER_VERSION_TWEAK DEC(__VERSION_BUG_FIX_NUMBER__)
/* These compilers are either not known or too old to define an
identification macro. Try to identify the platform and guess that
it is the native compiler. */
#elif defined(__hpux) || defined(__hpua)
# define COMPILER_ID "HP"
#else /* unknown compiler */
# define COMPILER_ID ""
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
#ifdef SIMULATE_ID
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
#endif
#ifdef __QNXNTO__
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
#elif defined(__MSYS__)
# define PLATFORM_ID "MSYS"
#elif defined(__CYGWIN__)
# define PLATFORM_ID "Cygwin"
#elif defined(__MINGW32__)
# define PLATFORM_ID "MinGW"
#elif defined(__APPLE__)
# define PLATFORM_ID "Darwin"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define PLATFORM_ID "Windows"
#elif defined(__FreeBSD__) || defined(__FreeBSD)
# define PLATFORM_ID "FreeBSD"
#elif defined(__NetBSD__) || defined(__NetBSD)
# define PLATFORM_ID "NetBSD"
#elif defined(__OpenBSD__) || defined(__OPENBSD)
# define PLATFORM_ID "OpenBSD"
#elif defined(__sun) || defined(sun)
# define PLATFORM_ID "SunOS"
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
# define PLATFORM_ID "AIX"
#elif defined(__hpux) || defined(__hpux__)
# define PLATFORM_ID "HP-UX"
#elif defined(__HAIKU__)
# define PLATFORM_ID "Haiku"
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
# define PLATFORM_ID "BeOS"
#elif defined(__QNX__) || defined(__QNXNTO__)
# define PLATFORM_ID "QNX"
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
# define PLATFORM_ID "Tru64"
#elif defined(__riscos) || defined(__riscos__)
# define PLATFORM_ID "RISCos"
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
# define PLATFORM_ID "SINIX"
#elif defined(__UNIX_SV__)
# define PLATFORM_ID "UNIX_SV"
#elif defined(__bsdos__)
# define PLATFORM_ID "BSDOS"
#elif defined(_MPRAS) || defined(MPRAS)
# define PLATFORM_ID "MP-RAS"
#elif defined(__osf) || defined(__osf__)
# define PLATFORM_ID "OSF1"
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
# define PLATFORM_ID "SCO_SV"
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
# define PLATFORM_ID "ULTRIX"
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
#elif defined(__WATCOMC__)
# if defined(__LINUX__)
# define PLATFORM_ID "Linux"
# elif defined(__DOS__)
# define PLATFORM_ID "DOS"
# elif defined(__OS2__)
# define PLATFORM_ID "OS2"
# elif defined(__WINDOWS__)
# define PLATFORM_ID "Windows3x"
# elif defined(__VXWORKS__)
# define PLATFORM_ID "VxWorks"
# else /* unknown platform */
# define PLATFORM_ID
# endif
#elif defined(__INTEGRITY)
# if defined(INT_178B)
# define PLATFORM_ID "Integrity178"
# else /* regular Integrity */
# define PLATFORM_ID "Integrity"
# endif
# elif defined(_ADI_COMPILER)
# define PLATFORM_ID "ADSP"
#else /* unknown platform */
# define PLATFORM_ID
#endif
/* For windows compilers MSVC and Intel we can determine
the architecture of the compiler being used. This is because
the compilers do not have flags that can change the architecture,
but rather depend on which compiler is being used
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(_M_IA64)
# define ARCHITECTURE_ID "IA64"
# elif defined(_M_ARM64EC)
# define ARCHITECTURE_ID "ARM64EC"
# elif defined(_M_X64) || defined(_M_AMD64)
# define ARCHITECTURE_ID "x64"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM64)
# define ARCHITECTURE_ID "ARM64"
# elif defined(_M_ARM)
# if _M_ARM == 4
# define ARCHITECTURE_ID "ARMV4I"
# elif _M_ARM == 5
# define ARCHITECTURE_ID "ARMV5I"
# else
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
# elif defined(_M_SH)
# define ARCHITECTURE_ID "SHx"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__WATCOMC__)
# if defined(_M_I86)
# define ARCHITECTURE_ID "I86"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# if defined(__ICCARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__ICCRH850__)
# define ARCHITECTURE_ID "RH850"
# elif defined(__ICCRL78__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__ICCRISCV__)
# define ARCHITECTURE_ID "RISCV"
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__ICCV850__)
# define ARCHITECTURE_ID "V850"
# elif defined(__ICC8051__)
# define ARCHITECTURE_ID "8051"
# elif defined(__ICCSTM8__)
# define ARCHITECTURE_ID "STM8"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__ghs__)
# if defined(__PPC64__)
# define ARCHITECTURE_ID "PPC64"
# elif defined(__ppc__)
# define ARCHITECTURE_ID "PPC"
# elif defined(__ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__x86_64__)
# define ARCHITECTURE_ID "x64"
# elif defined(__i386__)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__clang__) && defined(__ti__)
# if defined(__ARM_ARCH)
# define ARCHITECTURE_ID "ARM"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__TI_COMPILER_VERSION__)
# if defined(__TI_ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__MSP430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__TMS320C28XX__)
# define ARCHITECTURE_ID "TMS320C28x"
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
# define ARCHITECTURE_ID "TMS320C6x"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
# elif defined(__ADSPSHARC__)
# define ARCHITECTURE_ID "SHARC"
# elif defined(__ADSPBLACKFIN__)
# define ARCHITECTURE_ID "Blackfin"
#elif defined(__TASKING__)
# if defined(__CTC__) || defined(__CPTC__)
# define ARCHITECTURE_ID "TriCore"
# elif defined(__CMCS__)
# define ARCHITECTURE_ID "MCS"
# elif defined(__CARM__) || defined(__CPARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__CARC__)
# define ARCHITECTURE_ID "ARC"
# elif defined(__C51__)
# define ARCHITECTURE_ID "8051"
# elif defined(__CPCP__)
# define ARCHITECTURE_ID "PCP"
# else
# define ARCHITECTURE_ID ""
# endif
#elif defined(__RENESAS__)
# if defined(__CCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__CCRL__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__CCRH__)
# define ARCHITECTURE_ID "RH850"
# else
# define ARCHITECTURE_ID ""
# endif
#else
# define ARCHITECTURE_ID
#endif
/* Convert integer to decimal digit literals. */
#define DEC(n) \
('0' + (((n) / 10000000)%10)), \
('0' + (((n) / 1000000)%10)), \
('0' + (((n) / 100000)%10)), \
('0' + (((n) / 10000)%10)), \
('0' + (((n) / 1000)%10)), \
('0' + (((n) / 100)%10)), \
('0' + (((n) / 10)%10)), \
('0' + ((n) % 10))
/* Convert integer to hex digit literals. */
#define HEX(n) \
('0' + ((n)>>28 & 0xF)), \
('0' + ((n)>>24 & 0xF)), \
('0' + ((n)>>20 & 0xF)), \
('0' + ((n)>>16 & 0xF)), \
('0' + ((n)>>12 & 0xF)), \
('0' + ((n)>>8 & 0xF)), \
('0' + ((n)>>4 & 0xF)), \
('0' + ((n) & 0xF))
/* Construct a string literal encoding the version number. */
#ifdef COMPILER_VERSION
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
/* Construct a string literal encoding the version number components. */
#elif defined(COMPILER_VERSION_MAJOR)
char const info_version[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
COMPILER_VERSION_MAJOR,
# ifdef COMPILER_VERSION_MINOR
'.', COMPILER_VERSION_MINOR,
# ifdef COMPILER_VERSION_PATCH
'.', COMPILER_VERSION_PATCH,
# ifdef COMPILER_VERSION_TWEAK
'.', COMPILER_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct a string literal encoding the internal version number. */
#ifdef COMPILER_VERSION_INTERNAL
char const info_version_internal[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
'i','n','t','e','r','n','a','l','[',
COMPILER_VERSION_INTERNAL,']','\0'};
#elif defined(COMPILER_VERSION_INTERNAL_STR)
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
#endif
/* Construct a string literal encoding the version number components. */
#ifdef SIMULATE_VERSION_MAJOR
char const info_simulate_version[] = {
'I', 'N', 'F', 'O', ':',
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
SIMULATE_VERSION_MAJOR,
# ifdef SIMULATE_VERSION_MINOR
'.', SIMULATE_VERSION_MINOR,
# ifdef SIMULATE_VERSION_PATCH
'.', SIMULATE_VERSION_PATCH,
# ifdef SIMULATE_VERSION_TWEAK
'.', SIMULATE_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
#define CXX_STD_98 199711L
#define CXX_STD_11 201103L
#define CXX_STD_14 201402L
#define CXX_STD_17 201703L
#define CXX_STD_20 202002L
#define CXX_STD_23 202302L
#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG)
# if _MSVC_LANG > CXX_STD_17
# define CXX_STD _MSVC_LANG
# elif _MSVC_LANG == CXX_STD_17 && defined(__cpp_aggregate_paren_init)
# define CXX_STD CXX_STD_20
# elif _MSVC_LANG > CXX_STD_14 && __cplusplus > CXX_STD_17
# define CXX_STD CXX_STD_20
# elif _MSVC_LANG > CXX_STD_14
# define CXX_STD CXX_STD_17
# elif defined(__INTEL_CXX11_MODE__) && defined(__cpp_aggregate_nsdmi)
# define CXX_STD CXX_STD_14
# elif defined(__INTEL_CXX11_MODE__)
# define CXX_STD CXX_STD_11
# else
# define CXX_STD CXX_STD_98
# endif
#elif defined(_MSC_VER) && defined(_MSVC_LANG)
# if _MSVC_LANG > __cplusplus
# define CXX_STD _MSVC_LANG
# else
# define CXX_STD __cplusplus
# endif
#elif defined(__NVCOMPILER)
# if __cplusplus == CXX_STD_17 && defined(__cpp_aggregate_paren_init)
# define CXX_STD CXX_STD_20
# else
# define CXX_STD __cplusplus
# endif
#elif defined(__INTEL_COMPILER) || defined(__PGI)
# if __cplusplus == CXX_STD_11 && defined(__cpp_namespace_attributes)
# define CXX_STD CXX_STD_17
# elif __cplusplus == CXX_STD_11 && defined(__cpp_aggregate_nsdmi)
# define CXX_STD CXX_STD_14
# else
# define CXX_STD __cplusplus
# endif
#elif (defined(__IBMCPP__) || defined(__ibmxl__)) && defined(__linux__)
# if __cplusplus == CXX_STD_11 && defined(__cpp_aggregate_nsdmi)
# define CXX_STD CXX_STD_14
# else
# define CXX_STD __cplusplus
# endif
#elif __cplusplus == 1 && defined(__GXX_EXPERIMENTAL_CXX0X__)
# define CXX_STD CXX_STD_11
#else
# define CXX_STD __cplusplus
#endif
const char* info_language_standard_default = "INFO" ":" "standard_default["
#if CXX_STD > CXX_STD_23
"26"
#elif CXX_STD > CXX_STD_20
"23"
#elif CXX_STD > CXX_STD_17
"20"
#elif CXX_STD > CXX_STD_14
"17"
#elif CXX_STD > CXX_STD_11
"14"
#elif CXX_STD >= CXX_STD_11
"11"
#else
"98"
#endif
"]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \
defined(__TI_COMPILER_VERSION__) || defined(__RENESAS__)) && \
!defined(__STRICT_ANSI__)
"ON"
#else
"OFF"
#endif
"]";
/*--------------------------------------------------------------------------*/
int main(int argc, char* argv[])
{
int require = 0;
require += info_compiler[argc];
require += info_platform[argc];
require += info_arch[argc];
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
#if defined(COMPILER_VERSION_INTERNAL) || defined(COMPILER_VERSION_INTERNAL_STR)
require += info_version_internal[argc];
#endif
#ifdef SIMULATE_ID
require += info_simulate[argc];
#endif
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
require += info_cray[argc];
#endif
require += info_language_standard_default[argc];
require += info_language_extensions_default[argc];
(void)argv;
return require;
}

View File

@ -1,269 +1,4 @@
---
events:
-
kind: "message-v1"
backtrace:
- "/usr/share/cmake-3.28/Modules/CMakeDetermineSystem.cmake:233 (message)"
- "CMakeLists.txt:2 (project)"
message: |
The system is: Linux - 6.18.5 - x86_64
-
kind: "message-v1"
backtrace:
- "/usr/share/cmake-3.28/Modules/CMakeDetermineCompilerId.cmake:17 (message)"
- "/usr/share/cmake-3.28/Modules/CMakeDetermineCompilerId.cmake:64 (__determine_compiler_id_test)"
- "/usr/share/cmake-3.28/Modules/CMakeDetermineCXXCompiler.cmake:126 (CMAKE_DETERMINE_COMPILER_ID)"
- "CMakeLists.txt:2 (project)"
message: |
Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded.
Compiler: /usr/bin/c++
Build flags:
Id flags:
The output was:
0
Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out"
The CXX compiler identification is GNU, found in:
/home/user/saqut/build/CMakeFiles/3.28.3/CompilerIdCXX/a.out
-
kind: "try_compile-v1"
backtrace:
- "/usr/share/cmake-3.28/Modules/CMakeDetermineCompilerABI.cmake:57 (try_compile)"
- "/usr/share/cmake-3.28/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
- "CMakeLists.txt:2 (project)"
checks:
- "Detecting CXX compiler ABI info"
directories:
source: "/home/user/saqut/build/CMakeFiles/CMakeScratch/TryCompile-6ljCUz"
binary: "/home/user/saqut/build/CMakeFiles/CMakeScratch/TryCompile-6ljCUz"
cmakeVariables:
CMAKE_CXX_FLAGS: ""
CMAKE_CXX_FLAGS_DEBUG: "-g"
CMAKE_EXE_LINKER_FLAGS: ""
buildResult:
variable: "CMAKE_CXX_ABI_COMPILED"
cached: true
stdout: |
Change Dir: '/home/user/saqut/build/CMakeFiles/CMakeScratch/TryCompile-6ljCUz'
Run Build Command(s): /usr/bin/ninja -v cmTC_b1346
[1/2] /usr/bin/c++ -v -o CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-3.28/Modules/CMakeCXXCompilerABI.cpp
Using built-in specs.
COLLECT_GCC=/usr/bin/c++
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04.1' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-EldibY/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-EldibY/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04.1)
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b1346.dir/'
/usr/libexec/gcc/x86_64-linux-gnu/13/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /usr/share/cmake-3.28/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_b1346.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccKBrizP.s
GNU C++17 (Ubuntu 13.3.0-6ubuntu2~24.04.1) version 13.3.0 (x86_64-linux-gnu)
compiled by GNU C version 13.3.0, GMP version 6.3.0, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.26-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/13"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/include-fixed/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/13
/usr/include/x86_64-linux-gnu/c++/13
/usr/include/c++/13/backward
/usr/lib/gcc/x86_64-linux-gnu/13/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
Compiler executable checksum: 7896445e4990772fdae9dc0659a99266
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b1346.dir/'
as -v --64 -o CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccKBrizP.s
GNU assembler version 2.42 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.42
COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.'
[2/2] : && /usr/bin/c++ -v CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_b1346 && :
Using built-in specs.
COLLECT_GCC=/usr/bin/c++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04.1' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-EldibY/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-EldibY/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04.1)
COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_b1346' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_b1346.'
/usr/libexec/gcc/x86_64-linux-gnu/13/collect2 -plugin /usr/libexec/gcc/x86_64-linux-gnu/13/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper -plugin-opt=-fresolution=/tmp/cci1AaX8.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_b1346 /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/13/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/13 -L/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/13/../../.. CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/13/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crtn.o
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_b1346' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_b1346.'
exitCode: 0
-
kind: "message-v1"
backtrace:
- "/usr/share/cmake-3.28/Modules/CMakeDetermineCompilerABI.cmake:127 (message)"
- "/usr/share/cmake-3.28/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
- "CMakeLists.txt:2 (project)"
message: |
Parsed CXX implicit include dir info: rv=done
found start of include info
found start of implicit include info
add: [/usr/include/c++/13]
add: [/usr/include/x86_64-linux-gnu/c++/13]
add: [/usr/include/c++/13/backward]
add: [/usr/lib/gcc/x86_64-linux-gnu/13/include]
add: [/usr/local/include]
add: [/usr/include/x86_64-linux-gnu]
add: [/usr/include]
end of search list found
collapse include dir [/usr/include/c++/13] ==> [/usr/include/c++/13]
collapse include dir [/usr/include/x86_64-linux-gnu/c++/13] ==> [/usr/include/x86_64-linux-gnu/c++/13]
collapse include dir [/usr/include/c++/13/backward] ==> [/usr/include/c++/13/backward]
collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/13/include] ==> [/usr/lib/gcc/x86_64-linux-gnu/13/include]
collapse include dir [/usr/local/include] ==> [/usr/local/include]
collapse include dir [/usr/include/x86_64-linux-gnu] ==> [/usr/include/x86_64-linux-gnu]
collapse include dir [/usr/include] ==> [/usr/include]
implicit include dirs: [/usr/include/c++/13;/usr/include/x86_64-linux-gnu/c++/13;/usr/include/c++/13/backward;/usr/lib/gcc/x86_64-linux-gnu/13/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include]
-
kind: "message-v1"
backtrace:
- "/usr/share/cmake-3.28/Modules/CMakeDetermineCompilerABI.cmake:159 (message)"
- "/usr/share/cmake-3.28/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
- "CMakeLists.txt:2 (project)"
message: |
Parsed CXX implicit link information:
link line regex: [^( *|.*[/\\])(ld|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\\]+-)?ld|collect2)[^/\\]*( |$)]
ignore line: [Change Dir: '/home/user/saqut/build/CMakeFiles/CMakeScratch/TryCompile-6ljCUz']
ignore line: []
ignore line: [Run Build Command(s): /usr/bin/ninja -v cmTC_b1346]
ignore line: [[1/2] /usr/bin/c++ -v -o CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-3.28/Modules/CMakeCXXCompilerABI.cpp]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/c++]
ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa]
ignore line: [OFFLOAD_TARGET_DEFAULT=1]
ignore line: [Target: x86_64-linux-gnu]
ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04.1' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c ada c++ go d fortran objc obj-c++ m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-EldibY/gcc-13-13.3.0/debian/tmp-nvptx/usr amdgcn-amdhsa=/build/gcc-13-EldibY/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2]
ignore line: [Thread model: posix]
ignore line: [Supported LTO compression algorithms: zlib zstd]
ignore line: [gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04.1) ]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b1346.dir/']
ignore line: [ /usr/libexec/gcc/x86_64-linux-gnu/13/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /usr/share/cmake-3.28/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_b1346.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccKBrizP.s]
ignore line: [GNU C++17 (Ubuntu 13.3.0-6ubuntu2~24.04.1) version 13.3.0 (x86_64-linux-gnu)]
ignore line: [ compiled by GNU C version 13.3.0 GMP version 6.3.0 MPFR version 4.2.1 MPC version 1.3.1 isl version isl-0.26-GMP]
ignore line: []
ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
ignore line: [ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/13"]
ignore line: [ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"]
ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/include-fixed/x86_64-linux-gnu"]
ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/include-fixed"]
ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include"]
ignore line: [#include "..." search starts here:]
ignore line: [#include <...> search starts here:]
ignore line: [ /usr/include/c++/13]
ignore line: [ /usr/include/x86_64-linux-gnu/c++/13]
ignore line: [ /usr/include/c++/13/backward]
ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/13/include]
ignore line: [ /usr/local/include]
ignore line: [ /usr/include/x86_64-linux-gnu]
ignore line: [ /usr/include]
ignore line: [End of search list.]
ignore line: [Compiler executable checksum: 7896445e4990772fdae9dc0659a99266]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b1346.dir/']
ignore line: [ as -v --64 -o CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccKBrizP.s]
ignore line: [GNU assembler version 2.42 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.42]
ignore line: [COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.']
ignore line: [[2/2] : && /usr/bin/c++ -v CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_b1346 && :]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/c++]
ignore line: [COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper]
ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa]
ignore line: [OFFLOAD_TARGET_DEFAULT=1]
ignore line: [Target: x86_64-linux-gnu]
ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04.1' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c ada c++ go d fortran objc obj-c++ m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-EldibY/gcc-13-13.3.0/debian/tmp-nvptx/usr amdgcn-amdhsa=/build/gcc-13-EldibY/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2]
ignore line: [Thread model: posix]
ignore line: [Supported LTO compression algorithms: zlib zstd]
ignore line: [gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04.1) ]
ignore line: [COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_b1346' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_b1346.']
link line: [ /usr/libexec/gcc/x86_64-linux-gnu/13/collect2 -plugin /usr/libexec/gcc/x86_64-linux-gnu/13/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper -plugin-opt=-fresolution=/tmp/cci1AaX8.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_b1346 /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/13/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/13 -L/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/13/../../.. CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/13/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crtn.o]
arg [/usr/libexec/gcc/x86_64-linux-gnu/13/collect2] ==> ignore
arg [-plugin] ==> ignore
arg [/usr/libexec/gcc/x86_64-linux-gnu/13/liblto_plugin.so] ==> ignore
arg [-plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper] ==> ignore
arg [-plugin-opt=-fresolution=/tmp/cci1AaX8.res] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-lc] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [--build-id] ==> ignore
arg [--eh-frame-hdr] ==> ignore
arg [-m] ==> ignore
arg [elf_x86_64] ==> ignore
arg [--hash-style=gnu] ==> ignore
arg [--as-needed] ==> ignore
arg [-dynamic-linker] ==> ignore
arg [/lib64/ld-linux-x86-64.so.2] ==> ignore
arg [-pie] ==> ignore
arg [-znow] ==> ignore
arg [-zrelro] ==> ignore
arg [-o] ==> ignore
arg [cmTC_b1346] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/Scrt1.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/Scrt1.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crti.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crti.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/13/crtbeginS.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/13/crtbeginS.o]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/13] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/13]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib]
arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu]
arg [-L/lib/../lib] ==> dir [/lib/../lib]
arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu]
arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/13/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/13/../../..]
arg [CMakeFiles/cmTC_b1346.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore
arg [-lstdc++] ==> lib [stdc++]
arg [-lm] ==> lib [m]
arg [-lgcc_s] ==> lib [gcc_s]
arg [-lgcc] ==> lib [gcc]
arg [-lc] ==> lib [c]
arg [-lgcc_s] ==> lib [gcc_s]
arg [-lgcc] ==> lib [gcc]
arg [/usr/lib/gcc/x86_64-linux-gnu/13/crtendS.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/13/crtendS.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crtn.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crtn.o]
collapse obj [/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/Scrt1.o] ==> [/usr/lib/x86_64-linux-gnu/Scrt1.o]
collapse obj [/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crti.o] ==> [/usr/lib/x86_64-linux-gnu/crti.o]
collapse obj [/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crtn.o] ==> [/usr/lib/x86_64-linux-gnu/crtn.o]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/13] ==> [/usr/lib/gcc/x86_64-linux-gnu/13]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib] ==> [/usr/lib]
collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu]
collapse library dir [/lib/../lib] ==> [/lib]
collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu]
collapse library dir [/usr/lib/../lib] ==> [/usr/lib]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/13/../../..] ==> [/usr/lib]
implicit libs: [stdc++;m;gcc_s;gcc;c;gcc_s;gcc]
implicit objs: [/usr/lib/x86_64-linux-gnu/Scrt1.o;/usr/lib/x86_64-linux-gnu/crti.o;/usr/lib/gcc/x86_64-linux-gnu/13/crtbeginS.o;/usr/lib/gcc/x86_64-linux-gnu/13/crtendS.o;/usr/lib/x86_64-linux-gnu/crtn.o]
implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/13;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib]
implicit fwks: []
...
---
events:
-
@ -285,6 +20,7 @@ events:
names:
- "uname"
candidate_directories:
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/usr/bin/"
@ -297,13 +33,13 @@ events:
- "/usr/bin/vendor_perl/"
- "/usr/bin/core_perl/"
searched_directories:
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/uname"
- "/home/saqut/.local/bin/uname"
- "/usr/local/bin/uname"
found: "/usr/bin/uname"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -321,7 +57,7 @@ events:
- "/usr/share/cmake/Modules/CMakeDetermineSystem.cmake:212 (message)"
- "CMakeLists.txt:2 (project)"
message: |
The system is: Linux - 7.0.10-1-MANJARO - x86_64
The system is: Linux - 7.0.9-1-MANJARO - x86_64
-
kind: "find-v1"
backtrace:
@ -343,6 +79,7 @@ events:
- "ninja"
- "samu"
candidate_directories:
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/usr/bin/"
@ -355,6 +92,9 @@ events:
- "/usr/bin/vendor_perl/"
- "/usr/bin/core_perl/"
searched_directories:
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/ninja-build"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/ninja"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/samu"
- "/home/saqut/.local/bin/ninja-build"
- "/home/saqut/.local/bin/ninja"
- "/home/saqut/.local/bin/samu"
@ -365,8 +105,7 @@ events:
found: "/usr/bin/ninja"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -407,6 +146,7 @@ events:
- "icx"
- "clang++"
candidate_directories:
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/usr/bin/"
@ -419,13 +159,13 @@ events:
- "/usr/bin/vendor_perl/"
- "/usr/bin/core_perl/"
searched_directories:
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/c++"
- "/home/saqut/.local/bin/c++"
- "/usr/local/bin/c++"
found: "/usr/bin/c++"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -464,8 +204,7 @@ events:
found: "/usr/share/cmake/Modules/CMakeCXXCompilerId.cpp.in"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -497,7 +236,7 @@ events:
Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out"
The CXX compiler identification is GNU, found in:
/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/4.3.3/CompilerIdCXX/a.out
/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/4.3.2/CompilerIdCXX/a.out
-
kind: "find-v1"
@ -520,6 +259,7 @@ events:
- "ar"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -533,8 +273,7 @@ events:
found: "/usr/bin/ar"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -567,6 +306,7 @@ events:
- "ranlib"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -580,8 +320,7 @@ events:
found: "/usr/bin/ranlib"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -614,6 +353,7 @@ events:
- "strip"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -627,8 +367,7 @@ events:
found: "/usr/bin/strip"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -661,6 +400,7 @@ events:
- "ld"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -674,8 +414,7 @@ events:
found: "/usr/bin/ld"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -708,6 +447,7 @@ events:
- "nm"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -721,8 +461,7 @@ events:
found: "/usr/bin/nm"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -755,6 +494,7 @@ events:
- "objdump"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -768,8 +508,7 @@ events:
found: "/usr/bin/objdump"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -802,6 +541,7 @@ events:
- "objcopy"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -815,8 +555,7 @@ events:
found: "/usr/bin/objcopy"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -849,6 +588,7 @@ events:
- "readelf"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -862,8 +602,7 @@ events:
found: "/usr/bin/readelf"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -896,6 +635,7 @@ events:
- "dlltool"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -908,6 +648,7 @@ events:
- "/usr/bin/core_perl/"
searched_directories:
- "/usr/bin/dlltool"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/dlltool"
- "/home/saqut/.local/bin/dlltool"
- "/usr/local/bin/dlltool"
- "/bin/dlltool"
@ -921,8 +662,7 @@ events:
found: false
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -955,6 +695,7 @@ events:
- "addr2line"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -968,8 +709,7 @@ events:
found: "/usr/bin/addr2line"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -1002,6 +742,7 @@ events:
- "tapi"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -1014,6 +755,7 @@ events:
- "/usr/bin/core_perl/"
searched_directories:
- "/usr/bin/tapi"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/tapi"
- "/home/saqut/.local/bin/tapi"
- "/usr/local/bin/tapi"
- "/bin/tapi"
@ -1027,8 +769,7 @@ events:
found: false
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -1064,6 +805,7 @@ events:
- "gcc-ar"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -1076,6 +818,7 @@ events:
- "/usr/bin/core_perl/"
searched_directories:
- "/usr/bin/gcc-ar-16.1"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/gcc-ar-16.1"
- "/home/saqut/.local/bin/gcc-ar-16.1"
- "/usr/local/bin/gcc-ar-16.1"
- "/bin/gcc-ar-16.1"
@ -1087,6 +830,7 @@ events:
- "/usr/bin/vendor_perl/gcc-ar-16.1"
- "/usr/bin/core_perl/gcc-ar-16.1"
- "/usr/bin/gcc-ar-16"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/gcc-ar-16"
- "/home/saqut/.local/bin/gcc-ar-16"
- "/usr/local/bin/gcc-ar-16"
- "/bin/gcc-ar-16"
@ -1098,6 +842,7 @@ events:
- "/usr/bin/vendor_perl/gcc-ar-16"
- "/usr/bin/core_perl/gcc-ar-16"
- "/usr/bin/gcc-ar16"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/gcc-ar16"
- "/home/saqut/.local/bin/gcc-ar16"
- "/usr/local/bin/gcc-ar16"
- "/bin/gcc-ar16"
@ -1111,8 +856,7 @@ events:
found: "/usr/bin/gcc-ar"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -1148,6 +892,7 @@ events:
- "gcc-ranlib"
candidate_directories:
- "/usr/bin/"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/"
- "/home/saqut/.local/bin/"
- "/usr/local/bin/"
- "/bin/"
@ -1160,6 +905,7 @@ events:
- "/usr/bin/core_perl/"
searched_directories:
- "/usr/bin/gcc-ranlib-16.1"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/gcc-ranlib-16.1"
- "/home/saqut/.local/bin/gcc-ranlib-16.1"
- "/usr/local/bin/gcc-ranlib-16.1"
- "/bin/gcc-ranlib-16.1"
@ -1171,6 +917,7 @@ events:
- "/usr/bin/vendor_perl/gcc-ranlib-16.1"
- "/usr/bin/core_perl/gcc-ranlib-16.1"
- "/usr/bin/gcc-ranlib-16"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/gcc-ranlib-16"
- "/home/saqut/.local/bin/gcc-ranlib-16"
- "/usr/local/bin/gcc-ranlib-16"
- "/bin/gcc-ranlib-16"
@ -1182,6 +929,7 @@ events:
- "/usr/bin/vendor_perl/gcc-ranlib-16"
- "/usr/bin/core_perl/gcc-ranlib-16"
- "/usr/bin/gcc-ranlib16"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin/gcc-ranlib16"
- "/home/saqut/.local/bin/gcc-ranlib16"
- "/usr/local/bin/gcc-ranlib16"
- "/bin/gcc-ranlib16"
@ -1195,8 +943,7 @@ events:
found: "/usr/bin/gcc-ranlib"
search_context:
ENV{PATH}:
- "/home/saqut/.local/bin"
- "/home/saqut/.local/bin"
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
- "/home/saqut/.local/bin"
- "/usr/local/bin"
- "/usr/bin"
@ -1217,8 +964,8 @@ events:
checks:
- "Detecting CXX compiler ABI info"
directories:
source: "/home/saqut/Masa\u00fcst\u00fc/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-bNmRFu"
binary: "/home/saqut/Masa\u00fcst\u00fc/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-bNmRFu"
source: "/home/saqut/Masa\u00fcst\u00fc/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-lntpv4"
binary: "/home/saqut/Masa\u00fcst\u00fc/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-lntpv4"
cmakeVariables:
CMAKE_CXX_FLAGS: ""
CMAKE_CXX_FLAGS_DEBUG: "-g"
@ -1229,10 +976,10 @@ events:
variable: "CMAKE_CXX_ABI_COMPILED"
cached: true
stdout: |
Change Dir: '/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-bNmRFu'
Change Dir: '/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-lntpv4'
Run Build Command(s): /usr/bin/ninja -v cmTC_a8847
[1/2] /usr/bin/c++ -v -o CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp
Run Build Command(s): /usr/bin/ninja -v cmTC_ff321
[1/2] /usr/bin/c++ -v -o CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp
Using built-in specs.
COLLECT_GCC=/usr/bin/c++
Target: x86_64-pc-linux-gnu
@ -1240,8 +987,8 @@ events:
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 16.1.1 20260430 (GCC)
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_a8847.dir/'
/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/cc1plus -quiet -v -D_GNU_SOURCE /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_a8847.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -version -o /tmp/cch7GwnZ.s
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_ff321.dir/'
/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/cc1plus -quiet -v -D_GNU_SOURCE /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_ff321.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -version -o /tmp/ccSiM3Hl.s
GNU C++20 (GCC) version 16.1.1 20260430 (x86_64-pc-linux-gnu)
compiled by GNU C version 16.1.1 20260430, GMP version 6.3.0, MPFR version 4.2.2, MPC version 1.4.1, isl version isl-0.27-GMP
@ -1258,13 +1005,13 @@ events:
/usr/include
End of search list.
Compiler executable checksum: d47d0c990a24bc0dbaf3bd00656bd5f3
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_a8847.dir/'
as -v --64 -o CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o /tmp/cch7GwnZ.s
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_ff321.dir/'
as -v --64 -o CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccSiM3Hl.s
GNU assembler version 2.46.0 (x86_64-pc-linux-gnu) using BFD version (GNU Binutils) 2.46.0
COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.'
[2/2] : && /usr/bin/c++ -v -Wl,-v CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_a8847 && :
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.'
[2/2] : && /usr/bin/c++ -v -Wl,-v CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_ff321 && :
Using built-in specs.
COLLECT_GCC=/usr/bin/c++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/lto-wrapper
@ -1275,12 +1022,12 @@ events:
gcc version 16.1.1 20260430 (GCC)
COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_a8847' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_a8847.'
/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/collect2 -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/cce2Bg9n.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-latomic_asneeded -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_a8847 /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../.. -L/lib -L/usr/lib -v CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -latomic_asneeded -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crtn.o
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_ff321' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_ff321.'
/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/collect2 -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccgqnPZN.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-latomic_asneeded -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_ff321 /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../.. -L/lib -L/usr/lib -v CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -latomic_asneeded -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crtn.o
collect2 version 16.1.1 20260430
/usr/bin/ld -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/cce2Bg9n.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-latomic_asneeded -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_a8847 /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../.. -L/lib -L/usr/lib -v CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -latomic_asneeded -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crtn.o
/usr/bin/ld -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccgqnPZN.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-latomic_asneeded -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_ff321 /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../.. -L/lib -L/usr/lib -v CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -latomic_asneeded -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crtn.o
GNU ld (GNU Binutils) 2.46.0
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_a8847' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_a8847.'
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_ff321' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_ff321.'
exitCode: 0
-
@ -1319,10 +1066,10 @@ events:
Parsed CXX implicit link information:
link line regex: [^( *|.*[/\\])(ld[0-9]*(|\\.[a-rt-z][a-z]*|\\.s[a-np-z][a-z]*|\\.so[a-z]+)|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\\]+-)?ld|collect2)[^/\\]*( |$)]
linker tool regex: [^[ ]*(->|"|[0-9]+>[ -]*Build:[ 0-9]+ ms[ ]*)?[ ]*(([^"]*[/\\])?(ld[0-9]*(|\\.[a-rt-z][a-z]*|\\.s[a-np-z][a-z]*|\\.so[a-z]+)))("|,| |$)]
ignore line: [Change Dir: '/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-bNmRFu']
ignore line: [Change Dir: '/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-lntpv4']
ignore line: []
ignore line: [Run Build Command(s): /usr/bin/ninja -v cmTC_a8847]
ignore line: [[1/2] /usr/bin/c++ -v -o CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp]
ignore line: [Run Build Command(s): /usr/bin/ninja -v cmTC_ff321]
ignore line: [[1/2] /usr/bin/c++ -v -o CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/c++]
ignore line: [Target: x86_64-pc-linux-gnu]
@ -1330,8 +1077,8 @@ events:
ignore line: [Thread model: posix]
ignore line: [Supported LTO compression algorithms: zlib zstd]
ignore line: [gcc version 16.1.1 20260430 (GCC) ]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_a8847.dir/']
ignore line: [ /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/cc1plus -quiet -v -D_GNU_SOURCE /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_a8847.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -version -o /tmp/cch7GwnZ.s]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_ff321.dir/']
ignore line: [ /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/cc1plus -quiet -v -D_GNU_SOURCE /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_ff321.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -version -o /tmp/ccSiM3Hl.s]
ignore line: [GNU C++20 (GCC) version 16.1.1 20260430 (x86_64-pc-linux-gnu)]
ignore line: [ compiled by GNU C version 16.1.1 20260430 GMP version 6.3.0 MPFR version 4.2.2 MPC version 1.4.1 isl version isl-0.27-GMP]
ignore line: []
@ -1348,13 +1095,13 @@ events:
ignore line: [ /usr/include]
ignore line: [End of search list.]
ignore line: [Compiler executable checksum: d47d0c990a24bc0dbaf3bd00656bd5f3]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_a8847.dir/']
ignore line: [ as -v --64 -o CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o /tmp/cch7GwnZ.s]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_ff321.dir/']
ignore line: [ as -v --64 -o CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccSiM3Hl.s]
ignore line: [GNU assembler version 2.46.0 (x86_64-pc-linux-gnu) using BFD version (GNU Binutils) 2.46.0]
ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.']
ignore line: [[2/2] : && /usr/bin/c++ -v -Wl -v CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_a8847 && :]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.']
ignore line: [[2/2] : && /usr/bin/c++ -v -Wl -v CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_ff321 && :]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/c++]
ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/lto-wrapper]
@ -1365,13 +1112,13 @@ events:
ignore line: [gcc version 16.1.1 20260430 (GCC) ]
ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_a8847' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_a8847.']
link line: [ /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/collect2 -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/cce2Bg9n.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-latomic_asneeded -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_a8847 /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../.. -L/lib -L/usr/lib -v CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -latomic_asneeded -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crtn.o]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_ff321' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_ff321.']
link line: [ /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/collect2 -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccgqnPZN.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-latomic_asneeded -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_ff321 /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../.. -L/lib -L/usr/lib -v CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -latomic_asneeded -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crtn.o]
arg [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/collect2] ==> ignore
arg [-plugin] ==> ignore
arg [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/liblto_plugin.so] ==> ignore
arg [-plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/lto-wrapper] ==> ignore
arg [-plugin-opt=-fresolution=/tmp/cce2Bg9n.res] ==> ignore
arg [-plugin-opt=-fresolution=/tmp/ccgqnPZN.res] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-latomic_asneeded] ==> ignore
@ -1387,7 +1134,7 @@ events:
arg [/lib64/ld-linux-x86-64.so.2] ==> ignore
arg [-pie] ==> ignore
arg [-o] ==> ignore
arg [cmTC_a8847] ==> ignore
arg [cmTC_ff321] ==> ignore
arg [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/Scrt1.o] ==> obj [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/Scrt1.o]
arg [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crti.o] ==> obj [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crti.o]
arg [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtbeginS.o] ==> obj [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtbeginS.o]
@ -1399,7 +1146,7 @@ events:
arg [-L/lib] ==> dir [/lib]
arg [-L/usr/lib] ==> dir [/usr/lib]
arg [-v] ==> ignore
arg [CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore
arg [CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore
arg [-lstdc++] ==> lib [stdc++]
arg [-lm] ==> lib [m]
arg [-lgcc_s] ==> lib [gcc_s]
@ -1411,7 +1158,7 @@ events:
arg [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtendS.o] ==> obj [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtendS.o]
arg [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crtn.o] ==> obj [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crtn.o]
ignore line: [collect2 version 16.1.1 20260430]
ignore line: [/usr/bin/ld -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/cce2Bg9n.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-latomic_asneeded -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_a8847 /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../.. -L/lib -L/usr/lib -v CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -latomic_asneeded -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crtn.o]
ignore line: [/usr/bin/ld -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccgqnPZN.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-latomic_asneeded -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_ff321 /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../.. -L/lib -L/usr/lib -v CMakeFiles/cmTC_ff321.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -latomic_asneeded -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crtn.o]
linker tool for 'CXX': /usr/bin/ld
collapse obj [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/Scrt1.o] ==> [/usr/lib/Scrt1.o]
collapse obj [/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crti.o] ==> [/usr/lib/crti.o]

View File

@ -1,4 +1,3 @@
/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/saqut.dir
/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/test.dir
/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/edit_cache.dir
/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/rebuild_cache.dir

View File

@ -1,46 +0,0 @@
# CMAKE generated file: DO NOT EDIT!
# Generated by CMake Version 4.3
# ALL_GOLDEN_SQT at CMakeLists.txt:40 (file)
file(GLOB_RECURSE NEW_GLOB LIST_DIRECTORIES false "/home/saqut/Masaüstü/saqutcompiler/tests/golden/*.sqt")
set(OLD_GLOB
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/basic.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/compound_mod.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/mod_by_zero.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/precedence.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/fibonacci/fib.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/logic/not_operator.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/logic/short_circuit.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/basic.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/do_while_once.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/do_while_truthy.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/for_break_continue.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/nested_break.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/while_break_continue.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/opt/dce.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/opt/folding.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/opt/run_opt.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/string/equality.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/string/hello.sqt"
"/home/saqut/Masaüstü/saqutcompiler/tests/golden/string/ordering_error.sqt"
)
if(NOT "${NEW_GLOB}" STREQUAL "${OLD_GLOB}")
message("-- GLOB mismatch!")
set(NEW_ONLY ${NEW_GLOB})
set(OLD_ONLY ${OLD_GLOB})
list(REMOVE_ITEM NEW_ONLY ${OLD_GLOB})
list(REMOVE_ITEM OLD_ONLY ${NEW_GLOB})
if(NEW_ONLY)
message("The following files were added:")
foreach(VAR_FILE IN LISTS NEW_ONLY)
message(" +${VAR_FILE}")
endforeach()
endif()
if(OLD_ONLY)
message("The following files were removed:")
foreach(VAR_FILE IN LISTS OLD_ONLY)
message(" -${VAR_FILE}")
endforeach()
endif()
file(TOUCH_NOCREATE "/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/cmake.verify_globs")
endif()

View File

@ -1 +0,0 @@
# This file is generated by CMake for checking of the VerifyGlobs.cmake file

View File

@ -16,7 +16,7 @@
rule CXX_SCAN__saqut_Debug
depfile = $DEP_FILE
command = /usr/bin/g++ $DEFINES $INCLUDES $FLAGS -E -x c++ $in -MT $DYNDEP_INTERMEDIATE_FILE -MD -MF $DEP_FILE -fmodules-ts -fdeps-file=$DYNDEP_INTERMEDIATE_FILE -fdeps-target=$OBJ_FILE -fdeps-format=p1689r5 -o $PREPROCESSED_OUTPUT_FILE
command = /usr/bin/c++ $DEFINES $INCLUDES $FLAGS -E -x c++ $in -MT $DYNDEP_INTERMEDIATE_FILE -MD -MF $DEP_FILE -fmodules-ts -fdeps-file=$DYNDEP_INTERMEDIATE_FILE -fdeps-target=$OBJ_FILE -fdeps-format=p1689r5 -o $PREPROCESSED_OUTPUT_FILE
description = Scanning $in for CXX dependencies
@ -37,7 +37,7 @@ rule CXX_DYNDEP__saqut_Debug
rule CXX_COMPILER__saqut_scanned_Debug
depfile = $DEP_FILE
deps = gcc
command = ${LAUNCHER}${CODE_CHECK}/usr/bin/g++ $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -fmodules-ts -fmodule-mapper=$DYNDEP_MODULE_MAP_FILE -MD -fdeps-format=p1689r5 -x c++ -o $out -c $in
command = ${LAUNCHER}${CODE_CHECK}/usr/bin/c++ $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -fmodules-ts -fmodule-mapper=$DYNDEP_MODULE_MAP_FILE -MD -fdeps-format=p1689r5 -x c++ -o $out -c $in
description = Building CXX object $out
@ -47,7 +47,7 @@ rule CXX_COMPILER__saqut_scanned_Debug
rule CXX_COMPILER__saqut_unscanned_Debug
depfile = $DEP_FILE
deps = gcc
command = ${LAUNCHER}${CODE_CHECK}/usr/bin/g++ $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
command = ${LAUNCHER}${CODE_CHECK}/usr/bin/c++ $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
@ -57,7 +57,7 @@ rule CXX_COMPILER__saqut_unscanned_Debug
rule CXX_EXECUTABLE_LINKER__saqut_Debug
depfile = $DEP_FILE
deps = gcc
command = $PRE_LINK && /usr/bin/g++ $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
command = $PRE_LINK && /usr/bin/c++ $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
@ -79,15 +79,6 @@ rule RERUN_CMAKE
generator = 1
#############################################
# Rule for re-checking globbed directories.
rule VERIFY_GLOBS
command = /usr/bin/cmake -P /home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/VerifyGlobs.cmake
description = Re-checking globbed directories...
generator = 1
#############################################
# Rule for cleaning all built files.

View File

@ -1,48 +0,0 @@
# CMake generated Testfile for
# Source directory: /home/saqut/Masaüstü/saqutcompiler
# Build directory: /home/saqut/Masaüstü/saqutcompiler/build
#
# This file includes the relevant testing commands required for
# testing this directory and lists subdirectories to be tested as well.
add_test(unit_tests "bash" "/home/saqut/Masaüstü/saqutcompiler/tests/run.sh")
set_tests_properties(unit_tests PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;31;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_arithmetic_basic "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/basic.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/basic.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_arithmetic_basic PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_arithmetic_compound_mod "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/compound_mod.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/compound_mod.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_arithmetic_compound_mod PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_arithmetic_mod_by_zero_runtime_error "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/mod_by_zero.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/mod_by_zero.runtime_error" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden_error.cmake")
set_tests_properties(golden_arithmetic_mod_by_zero_runtime_error PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;109;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_arithmetic_precedence "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/precedence.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/arithmetic/precedence.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_arithmetic_precedence PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_fibonacci_fib "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/fibonacci/fib.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/fibonacci/fib.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_fibonacci_fib PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_logic_not_operator "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/logic/not_operator.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/logic/not_operator.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_logic_not_operator PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_logic_short_circuit "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/logic/short_circuit.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/logic/short_circuit.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_logic_short_circuit PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_loops_basic "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/basic.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/basic.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_loops_basic PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_loops_do_while_once "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/do_while_once.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/do_while_once.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_loops_do_while_once PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_loops_do_while_truthy "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/do_while_truthy.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/do_while_truthy.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_loops_do_while_truthy PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_loops_for_break_continue "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/for_break_continue.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/for_break_continue.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_loops_for_break_continue PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_loops_nested_break "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/nested_break.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/nested_break.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_loops_nested_break PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_loops_while_break_continue "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/while_break_continue.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/loops/while_break_continue.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_loops_while_break_continue PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_opt_dce_ir_opt "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/opt/dce.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/opt/dce.ir_opt.expected" "-DCOMMAND=ir" "-DOPTIMIZED=1" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_opt_dce_ir_opt PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;64;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_opt_folding_ir_opt "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/opt/folding.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/opt/folding.ir_opt.expected" "-DCOMMAND=ir" "-DOPTIMIZED=1" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_opt_folding_ir_opt PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;64;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_opt_run_opt "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/opt/run_opt.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/opt/run_opt.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_opt_run_opt PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_opt_run_opt_run_opt "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/opt/run_opt.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/opt/run_opt.run_opt.expected" "-DOPTIMIZED=1" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_opt_run_opt_run_opt PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;80;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_string_equality "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/string/equality.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/string/equality.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_string_equality PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_string_hello "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/string/hello.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/string/hello.expected" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden.cmake")
set_tests_properties(golden_string_hello PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;51;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")
add_test(golden_string_ordering_error_compile_error "/usr/bin/cmake" "-DBINARY=/home/saqut/Masaüstü/saqutcompiler/build/saqut" "-DSOURCE=/home/saqut/Masaüstü/saqutcompiler/tests/golden/string/ordering_error.sqt" "-DEXPECTED=/home/saqut/Masaüstü/saqutcompiler/tests/golden/string/ordering_error.compile_error" "-P" "/home/saqut/Masaüstü/saqutcompiler/cmake/run_golden_error.cmake")
set_tests_properties(golden_string_ordering_error_compile_error PROPERTIES _BACKTRACE_TRIPLES "/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;95;add_test;/home/saqut/Masaüstü/saqutcompiler/CMakeLists.txt;0;")

File diff suppressed because one or more lines are too long

View File

@ -1,39 +0,0 @@
# run_golden.cmake tek bir golden test çalıştırır ve çıktıyı karşılaştırır.
#
# Parametreler (cmake -D ile geçilir):
# BINARY saqut binary yolu
# SOURCE test .sqt dosyası (tam yol)
# EXPECTED beklenen çıktı dosyası (tam yol)
# COMMAND "run" (varsayılan) veya "ir"
# OPTIMIZED 1 ise --optimized bayrağı eklenir
if(NOT DEFINED COMMAND)
set(COMMAND "run")
endif()
set(EXTRA_FLAGS "")
if(OPTIMIZED)
list(APPEND EXTRA_FLAGS "--optimized")
endif()
execute_process(
COMMAND "${BINARY}" "${COMMAND}" ${EXTRA_FLAGS} "file:${SOURCE}"
OUTPUT_VARIABLE ACTUAL
ERROR_VARIABLE STDERR_OUT
RESULT_VARIABLE EXIT_CODE
)
if(NOT EXIT_CODE EQUAL 0)
message(FATAL_ERROR
"saqut ${COMMAND} başarısız (exit ${EXIT_CODE}):\n${STDERR_OUT}")
endif()
file(READ "${EXPECTED}" EXPECTED_CONTENT)
if(NOT ACTUAL STREQUAL EXPECTED_CONTENT)
message(FATAL_ERROR
"Çıktı uyuşmuyor: ${SOURCE}\n"
"--- BEKLENEN ---\n${EXPECTED_CONTENT}"
"--- GERÇEK ---\n${ACTUAL}"
)
endif()

View File

@ -1,29 +0,0 @@
# run_golden_error.cmake derleme hatası BEKLEYEN golden test.
#
# Parametreler (cmake -D ile geçilir):
# BINARY saqut binary yolu
# SOURCE test .sqt dosyası (tam yol)
# EXPECTED beklenen hata içeriği (.compile_error dosyası); stderr bu
# metni içermeli (regex veya düz dize olarak eşleşir)
execute_process(
COMMAND "${BINARY}" run "file:${SOURCE}"
OUTPUT_VARIABLE STDOUT_OUT
ERROR_VARIABLE STDERR_OUT
RESULT_VARIABLE EXIT_CODE
)
if(EXIT_CODE EQUAL 0)
message(FATAL_ERROR
"Derleme hatası bekleniyordu ama program başarıyla çalıştı: ${SOURCE}\n"
"Çıktı: ${STDOUT_OUT}")
endif()
file(READ "${EXPECTED}" EXPECTED_CONTENT)
string(STRIP "${EXPECTED_CONTENT}" EXPECTED_CONTENT)
if(NOT STDERR_OUT MATCHES "${EXPECTED_CONTENT}")
message(FATAL_ERROR
"Beklenen '${EXPECTED_CONTENT}' mesajı stderr'de bulunamadı: ${SOURCE}\n"
"Stderr: ${STDERR_OUT}")
endif()

File diff suppressed because it is too large Load Diff

View File

@ -1,60 +0,0 @@
# ADR-008: && ve || kısa devre değerlendirmesi
## Durum
Kabul edildi.
## Bağlam
Mevcut kodda `&&` ve `||` çalışma anında bozuk: IR üretici bu operatörler için
`case` içermiyor, `default` koluna düşüp `LOAD_CONST 0` üretiyor — yani değişken
operandlarda her zaman `false` dönüyor. Yalnızca her iki operand sabit olduğunda
sabit katlama doğru sonucu veriyor. (Kanıt: `ir_generator.cpp:395-413`,
`constant_folding.hpp:107-112`; davranış referansı bölüm B.)
## Karar
`&&` ve `||` **KISA DEVRE** değerlendirilir:
- `a && b`: `a` false ise `b` **HİÇ değerlendirilmez**, sonuç `false`.
- `a || b`: `a` true ise `b` **HİÇ değerlendirilmez**, sonuç `true`.
Bu, bu operatörlerin sıradan ikili işlem (iki tarafı hesapla sonra birleştir)
**DEĞİL**, bir dallanma olarak üretilmesi gerektiği anlamına gelir.
IR şeması:
```
a && b:
slot_a = [a değerlendir]
result = freshSlot()
LOAD_CONST result, 0 ; varsayılan: false
JIF_FALSE slot_a → DONE ; a false? b'yi atla, result=0 kalsın
slot_b = [b değerlendir]
LOAD_SLOT result, slot_b ; result = b'nin değeri
DONE:
a || b:
slot_a = [a değerlendir]
result = freshSlot()
LOAD_CONST result, 1 ; varsayılan: true
JIF_TRUE slot_a → DONE ; a true? b'yi atla, result=1 kalsın
slot_b = [b değerlendir]
LOAD_SLOT result, slot_b ; result = b'nin değeri
DONE:
```
`||` için `JIF_TRUE` opcode'u gerekir. `JIF_FALSE`'un simetriği olarak
`instruction.hpp`'e ve `interpreter.cpp`'e eklendi. `do-while` döngüsünün
mevcut `EQUAL_EQUAL(cond, 1)` geçici çözümü bu opcode'dan faydalanabilir
(ayrı düzeltme — bu ADR kapsamı dışı).
## Gerekçe
- C-ailesi dillerin (C, Go, Java, JS, C#) tamamı kısa devre yapar; hedef kitle
bunu bekler.
- Performans artısı: gereksiz sağ-taraf değerlendirmesi atlanır; kısa devre
OLMAYAN versiyon her iki tarafı da her zaman hesaplayacağı için daha yavaştır.
- Niş ile uyumlu: derleyici "şu çağrı şu durumda atlandı" diye gösterebilir.
## Sonuçlar
- Tek dezavantaj: mantıksal operatörün sağındaki yan etki koşullu çalışır.
Bu kabul edilir; yan etkiyi koşula gömmek zaten kötü kalıptır.
- Sabit katlama yolu (`constant_folding.hpp`) zaten doğru çalışıyordu ve
değiştirilmedi; bu düzeltme yalnızca değişken-operand (IR üretim) yolunu etkiler.

View File

@ -1,225 +0,0 @@
# saQut — Mimari Referans
**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 ast` ile incelenebilir.
- **CLI komut yapısı**`tokens`, `ast`, `symbols`, `run` iskeletleri.
- **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-analysis` dalı ş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 `mmap` bellek) **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.
---
## Tasarım felsefesi — neden saQut farklı?
saQut "daha iyi bir dil" iddiasında değil. Farkı, **derleyiciyi bir platform**
olarak ele almasında. İki taahhüt üstüne kuruludur:
**1. Cam (gör + sorgula + içine müdahale et).** Her aşama — token, AST, sembol
tablosu, tip, IR — kararlı, makine-okur ve **çift yönlü** bir arayüzden
erişilebilir olmalıdır. Sadece "dök ve göster" değil: kendi AST'ini verip tip
kontrolü isteyebilmeli, IR verip çalıştırabilmelisin. **Turnusol testi:** bir
yabancı, yalnızca `saqut ast` + `saqut symbols` çıktısından, bizden habersiz bir
LSP yazabiliyor mu? Cevap "evet" ise platform gerçektir.
**2. Kafes (deterministik + yetenek-güvenli çalıştırma).** Pointer yok, value
semantics, scope-tabanlı bellek ve **tek dış-dünya kapısı olan FFI seam**
(ADR-016) sayesinde saQut kodu, host'un açıkça izin verdiği fonksiyonlar dışında
dünyaya dokunamaz. Bytecode VM deterministiktir (ADR-015): aynı girdi → aynı
çıktı → aynı çalışma. "Sadelik" diye tasarlanan bu kararlar aslında bir
**yetenek-güvenliği (capability sandbox)** kurar — güvenilmeyen veya
AI-üretimi kodu güvenle çalıştırmak için biçilmiş kaftan.
**Bu ikisinin ödülü — kayıt & tekrar (record-replay).** 🚧 *(vizyon, v0 değil;
bkz. issue #94.)* Belirsizliğin tek kaynağı (kullanıcı girdisi, zaman, IO,
GC/thread kararları) FFI kapısından geçtiği için, mükemmel tekrar oynatma için
**her değişkeni her adımda kaydetmek gerekmez** — yalnızca kapıdan geçen değerler
kaydedilir, gerisi VM deterministik olarak yeniden çalıştırılarak üretilir. Boyut
gigabayttan kilobayta düşer. Replay modunda FFI çağrıları gerçekten çalışmaz,
kaydedilmiş değeri döndürür (dosyayı tekrar silmez, sunucuya tekrar istek atmaz).
Böylece "benim makinemde çalışıyor, müşteride patlıyor" sorunu: müşteri bir dump
yollar, sen çöküşü adım adım, aynı verilerle geri sararsın.
> Log, önceden sormayı akıl ettiğin sorulara cevap verir; **tekrar-oynatma,
> çöküşten *sonra* aklına gelen sorulara.** Zaman-yolculuğu hata ayıklama ayrı
> bir altyapı değildir — cam sorgularına bir **zaman koordinatı** eklemektir.
⚠️ Bu ödülün bedeli v0'da ödenir: **determinizm kutsaldır ve her belirsizlik
kaynağı kayıt-altına-alınabilir tek kapıdan geçmelidir.** Sonradan eklenemez;
baştan korunur.
---
## 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. `print` bunu 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.

View File

@ -4,24 +4,6 @@
> gelecek yol haritası hakkında kapsamlı analizleri içerir.
> Her kararın **neden** alındığı, alternatiflerin neden elendiği ve
> gelecekte hangi koşullarda tekrar değerlendirileceği belirtilmiştir.
>
> ⚠️ **Hizalama notu (sonraki oturum):** Aşağıdaki ADR-001 ve ADR-005, backend
> kod-üretimi seçeneklerini (LLVM/QBE/custom/C-transpile) ve "JIT" terimini
> tartışır. Sonradan **çalıştırma modeli netleşti** ve bazı ifadeler güncellendi:
>
> - **Birincil çalıştırma modeli = IR + bytecode VM** (yorumlayıcı döngü).
> Bkz. `docs/adr-frontend-analiz.md` **ADR-015**.
> - **Gerçek makine-kodu JIT kapsam DIŞIDIR** (tek faydası ham hız; öncelik
> determinizm + incelenebilirlik). Buradaki "JIT" geçişleri bu ışıkta okunmalı.
> - **C-transpile**, ileride geçerli bir **ikinci backend**'tir; QBE/custom/LLVM
> ise "makine kodu gerçekten gerekirse libgccjit/LLVM'e bağlan" çerçevesinde
> **çok uzak gelecektir**. ADR-001'deki karşılaştırmalar o gün için geçerli.
> - "HeavyIR/LightIR" ikiliği (ADR-005) bir **gelecek fikri** olarak durur; v0'ın
> IR+VM hedefi tek, basit bir IR'dir + **FFI seam** (ADR-016).
> - **Yapılan vs planlanan:** Tüm pipeline uygulandı. `examples/fibonacci.sqt`
> uçtan uca çalışıyor (lexer → tokenizer → parser → sembol tablosu → tip
> denetleyici → optimizasyon → IR üreteci → bytecode VM). ADR-001'deki
> "mevcut durum" listesi artık tarihseldir; güncel durum için bkz. `CLAUDE.md`.
---

View File

@ -1,421 +0,0 @@
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
22.22 0.02 0.02 1064503 0.00 0.00 SourceFile::offsetToLocation(int) const
11.11 0.03 0.01 1059636 0.00 0.00 Tokenizer::scope()
11.11 0.04 0.01 1059635 0.00 0.00 Lexer::isNumeric()
11.11 0.05 0.01 461302 0.00 0.00 DelimiterToken::~DelimiterToken()
11.11 0.06 0.01 278426 0.00 0.00 DelimiterToken::DelimiterToken()
11.11 0.07 0.01 133847 0.00 0.00 Lexer::readNumeric()
11.11 0.08 0.01 1 10.00 90.00 cmdTokens(CliArgs const&)
11.11 0.09 0.01 1 10.00 70.00 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
0.00 0.09 0.00 2754372 0.00 0.00 Lexer::isEnd()
0.00 0.09 0.00 2620524 0.00 0.00 Lexer::getchar()
0.00 0.09 0.00 2119274 0.00 0.00 Lexer::include(std::basic_string_view<char, std::char_traits<char> >, bool)
0.00 0.09 0.00 1851576 0.00 0.00 Lexer::getOffset()
0.00 0.09 0.00 1059640 0.00 0.00 Lexer::skipWhiteSpace()
0.00 0.09 0.00 991432 0.00 0.00 std::__detail::_Map_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
0.00 0.09 0.00 925788 0.00 0.00 Lexer::getchar(int)
0.00 0.09 0.00 691504 0.00 0.00 Lexer::getLocation()
0.00 0.09 0.00 691504 0.00 0.00 Lexer::toChar(int)
0.00 0.09 0.00 400817 0.00 0.00 Lexer::nextChar()
0.00 0.09 0.00 234284 0.00 0.00 IdentifierToken::~IdentifierToken()
0.00 0.09 0.00 234284 0.00 0.00 Lexer::beginPosition()
0.00 0.09 0.00 234284 0.00 0.00 Lexer::acceptPosition()
0.00 0.09 0.00 234284 0.00 0.00 Tokenizer::readIdentifier()
0.00 0.09 0.00 230202 0.00 0.00 OperatorToken::OperatorToken()
0.00 0.09 0.00 230202 0.00 0.00 OperatorToken::~OperatorToken()
0.00 0.09 0.00 133847 0.00 0.00 NumberToken::~NumberToken()
0.00 0.09 0.00 58981 0.00 0.00 KeywordToken::~KeywordToken()
0.00 0.09 0.00 21 0.00 0.00 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long)
0.00 0.09 0.00 20 0.00 0.00 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_invoke(std::_Any_data const&, CliArgs const&)
0.00 0.09 0.00 19 0.00 0.00 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
0.00 0.09 0.00 11 0.00 0.00 bool std::operator==<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*)
0.00 0.09 0.00 9 0.00 0.00 CliCommand::~CliCommand()
0.00 0.09 0.00 7 0.00 0.00 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&)
0.00 0.09 0.00 3 0.00 0.00 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
0.00 0.09 0.00 3 0.00 0.00 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
0.00 0.09 0.00 3 0.00 0.00 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
0.00 0.09 0.00 3 0.00 0.00 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
0.00 0.09 0.00 2 0.00 0.00 std::_Hashtable<TokenType, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > >, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > >, std::__detail::_Select1st, std::equal_to<TokenType>, std::hash<TokenType>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_Hashtable<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*>(std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, unsigned long, std::hash<TokenType> const&, std::equal_to<TokenType> const&, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > > const&, std::integral_constant<bool, true>)
0.00 0.09 0.00 2 0.00 0.00 std::_Hashtable<std::basic_string_view<char, std::char_traits<char> >, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType>, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> >, std::__detail::_Select1st, std::equal_to<std::basic_string_view<char, std::char_traits<char> > >, std::hash<std::basic_string_view<char, std::char_traits<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_Hashtable<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*>(std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, unsigned long, std::hash<std::basic_string_view<char, std::char_traits<char> > > const&, std::equal_to<std::basic_string_view<char, std::char_traits<char> > > const&, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> > const&, std::integral_constant<bool, true>)
0.00 0.09 0.00 1 0.00 0.00 readSource[abi:cxx11](CliArgs const&)
0.00 0.09 0.00 1 0.00 0.00 parseArgs(int, char**)
0.00 0.09 0.00 1 0.00 0.00 SourceFile::computeLineStarts()
0.00 0.09 0.00 1 0.00 0.00 SourceFile::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
0.00 0.09 0.00 1 0.00 0.00 Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
0.00 0.09 0.00 1 0.00 0.00 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_invoke(std::_Any_data const&, CliArgs const&)
% the percentage of the total running time of the
time program used by this function.
cumulative a running sum of the number of seconds accounted
seconds for by this function and those listed above it.
self the number of seconds accounted for by this
seconds function alone. This is the major sort for this
listing.
calls the number of times this function was invoked, if
this function is profiled, else blank.
self the average number of milliseconds spent in this
ms/call function per call, if this function is profiled,
else blank.
total the average number of milliseconds spent in this
ms/call function and its descendents per call, if this
function is profiled, else blank.
name the name of the function. This is the minor sort
for this listing. The index shows the location of
the function in the gprof listing. If the index is
in parenthesis it shows where it would appear in
the gprof listing if it were to be printed.
Copyright (C) 2012-2026 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
Call graph (explanation follows)
granularity: each sample hit covers 4 byte(s) for 11.11% of 0.09 seconds
index % time self children called name
<spontaneous>
[1] 100.0 0.00 0.09 main [1]
0.01 0.08 1/1 cmdTokens(CliArgs const&) [2]
0.00 0.00 18/20 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_invoke(std::_Any_data const&, CliArgs const&) [35]
0.00 0.00 9/9 CliCommand::~CliCommand() [38]
0.00 0.00 7/19 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [36]
0.00 0.00 7/7 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [39]
0.00 0.00 4/21 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long) [34]
0.00 0.00 1/1 parseArgs(int, char**) [47]
0.00 0.00 1/11 bool std::operator==<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) [37]
0.00 0.00 1/1 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_invoke(std::_Any_data const&, CliArgs const&) [51]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [42]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [41]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [40]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [43]
-----------------------------------------------
0.01 0.08 1/1 main [1]
[2] 100.0 0.01 0.08 1 cmdTokens(CliArgs const&) [2]
0.01 0.06 1/1 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [3]
0.01 0.00 461302/461302 DelimiterToken::~DelimiterToken() [9]
0.00 0.00 230202/230202 OperatorToken::~OperatorToken() [31]
0.00 0.00 175303/234284 IdentifierToken::~IdentifierToken() [27]
0.00 0.00 133847/133847 NumberToken::~NumberToken() [32]
0.00 0.00 58981/58981 KeywordToken::~KeywordToken() [33]
0.00 0.00 2/21 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long) [34]
0.00 0.00 1/1 readSource[abi:cxx11](CliArgs const&) [46]
-----------------------------------------------
0.01 0.06 1/1 cmdTokens(CliArgs const&) [2]
[3] 77.8 0.01 0.06 1 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [3]
0.01 0.05 1059636/1059636 Tokenizer::scope() [4]
0.00 0.00 1059635/2754372 Lexer::isEnd() [18]
0.00 0.00 1/1 Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [50]
-----------------------------------------------
0.01 0.05 1059636/1059636 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [3]
[4] 66.7 0.01 0.05 1059636 Tokenizer::scope() [4]
0.00 0.01 691504/691504 Lexer::getLocation() [6]
0.01 0.00 133847/133847 Lexer::readNumeric() [7]
0.01 0.00 1059635/1059635 Lexer::isNumeric() [8]
0.01 0.00 278426/278426 DelimiterToken::DelimiterToken() [10]
0.00 0.00 234284/234284 Tokenizer::readIdentifier() [11]
0.00 0.00 2119274/2119274 Lexer::include(std::basic_string_view<char, std::char_traits<char> >, bool) [20]
0.00 0.00 1985561/2620524 Lexer::getchar() [19]
0.00 0.00 1383008/1851576 Lexer::getOffset() [21]
0.00 0.00 1059774/2754372 Lexer::isEnd() [18]
0.00 0.00 1059640/1059640 Lexer::skipWhiteSpace() [22]
0.00 0.00 991400/991432 std::__detail::_Map_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [23]
0.00 0.00 925788/925788 Lexer::getchar(int) [24]
0.00 0.00 691504/691504 Lexer::toChar(int) [25]
0.00 0.00 230202/230202 OperatorToken::OperatorToken() [30]
0.00 0.00 58981/234284 IdentifierToken::~IdentifierToken() [27]
0.00 0.00 138/400817 Lexer::nextChar() [26]
-----------------------------------------------
0.00 0.00 138715/1064503 Lexer::readNumeric() [7]
0.00 0.00 234284/1064503 Tokenizer::readIdentifier() [11]
0.01 0.00 691504/1064503 Lexer::getLocation() [6]
[5] 22.2 0.02 0.00 1064503 SourceFile::offsetToLocation(int) const [5]
-----------------------------------------------
0.00 0.01 691504/691504 Tokenizer::scope() [4]
[6] 14.4 0.00 0.01 691504 Lexer::getLocation() [6]
0.01 0.00 691504/1064503 SourceFile::offsetToLocation(int) const [5]
-----------------------------------------------
0.01 0.00 133847/133847 Tokenizer::scope() [4]
[7] 14.0 0.01 0.00 133847 Lexer::readNumeric() [7]
0.00 0.00 138715/1064503 SourceFile::offsetToLocation(int) const [5]
-----------------------------------------------
0.01 0.00 1059635/1059635 Tokenizer::scope() [4]
[8] 11.1 0.01 0.00 1059635 Lexer::isNumeric() [8]
-----------------------------------------------
0.01 0.00 461302/461302 cmdTokens(CliArgs const&) [2]
[9] 11.1 0.01 0.00 461302 DelimiterToken::~DelimiterToken() [9]
-----------------------------------------------
0.01 0.00 278426/278426 Tokenizer::scope() [4]
[10] 11.1 0.01 0.00 278426 DelimiterToken::DelimiterToken() [10]
-----------------------------------------------
0.00 0.00 234284/234284 Tokenizer::scope() [4]
[11] 4.9 0.00 0.00 234284 Tokenizer::readIdentifier() [11]
0.00 0.00 234284/1064503 SourceFile::offsetToLocation(int) const [5]
0.00 0.00 634963/2754372 Lexer::isEnd() [18]
0.00 0.00 634963/2620524 Lexer::getchar() [19]
0.00 0.00 468568/1851576 Lexer::getOffset() [21]
0.00 0.00 400679/400817 Lexer::nextChar() [26]
0.00 0.00 234284/234284 Lexer::beginPosition() [28]
0.00 0.00 234284/234284 Lexer::acceptPosition() [29]
-----------------------------------------------
0.00 0.00 634963/2754372 Tokenizer::readIdentifier() [11]
0.00 0.00 1059635/2754372 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [3]
0.00 0.00 1059774/2754372 Tokenizer::scope() [4]
[18] 0.0 0.00 0.00 2754372 Lexer::isEnd() [18]
-----------------------------------------------
0.00 0.00 634963/2620524 Tokenizer::readIdentifier() [11]
0.00 0.00 1985561/2620524 Tokenizer::scope() [4]
[19] 0.0 0.00 0.00 2620524 Lexer::getchar() [19]
-----------------------------------------------
0.00 0.00 2119274/2119274 Tokenizer::scope() [4]
[20] 0.0 0.00 0.00 2119274 Lexer::include(std::basic_string_view<char, std::char_traits<char> >, bool) [20]
-----------------------------------------------
0.00 0.00 468568/1851576 Tokenizer::readIdentifier() [11]
0.00 0.00 1383008/1851576 Tokenizer::scope() [4]
[21] 0.0 0.00 0.00 1851576 Lexer::getOffset() [21]
-----------------------------------------------
0.00 0.00 1059640/1059640 Tokenizer::scope() [4]
[22] 0.0 0.00 0.00 1059640 Lexer::skipWhiteSpace() [22]
-----------------------------------------------
0.00 0.00 32/991432 __static_initialization_and_destruction_0() [81]
0.00 0.00 991400/991432 Tokenizer::scope() [4]
[23] 0.0 0.00 0.00 991432 std::__detail::_Map_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [23]
-----------------------------------------------
0.00 0.00 925788/925788 Tokenizer::scope() [4]
[24] 0.0 0.00 0.00 925788 Lexer::getchar(int) [24]
-----------------------------------------------
0.00 0.00 691504/691504 Tokenizer::scope() [4]
[25] 0.0 0.00 0.00 691504 Lexer::toChar(int) [25]
-----------------------------------------------
0.00 0.00 138/400817 Tokenizer::scope() [4]
0.00 0.00 400679/400817 Tokenizer::readIdentifier() [11]
[26] 0.0 0.00 0.00 400817 Lexer::nextChar() [26]
-----------------------------------------------
0.00 0.00 58981/234284 Tokenizer::scope() [4]
0.00 0.00 175303/234284 cmdTokens(CliArgs const&) [2]
[27] 0.0 0.00 0.00 234284 IdentifierToken::~IdentifierToken() [27]
-----------------------------------------------
0.00 0.00 234284/234284 Tokenizer::readIdentifier() [11]
[28] 0.0 0.00 0.00 234284 Lexer::beginPosition() [28]
-----------------------------------------------
0.00 0.00 234284/234284 Tokenizer::readIdentifier() [11]
[29] 0.0 0.00 0.00 234284 Lexer::acceptPosition() [29]
-----------------------------------------------
0.00 0.00 230202/230202 Tokenizer::scope() [4]
[30] 0.0 0.00 0.00 230202 OperatorToken::OperatorToken() [30]
-----------------------------------------------
0.00 0.00 230202/230202 cmdTokens(CliArgs const&) [2]
[31] 0.0 0.00 0.00 230202 OperatorToken::~OperatorToken() [31]
-----------------------------------------------
0.00 0.00 133847/133847 cmdTokens(CliArgs const&) [2]
[32] 0.0 0.00 0.00 133847 NumberToken::~NumberToken() [32]
-----------------------------------------------
0.00 0.00 58981/58981 cmdTokens(CliArgs const&) [2]
[33] 0.0 0.00 0.00 58981 KeywordToken::~KeywordToken() [33]
-----------------------------------------------
0.00 0.00 1/21 readSource[abi:cxx11](CliArgs const&) [46]
0.00 0.00 2/21 cmdTokens(CliArgs const&) [2]
0.00 0.00 4/21 main [1]
0.00 0.00 14/21 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [39]
[34] 0.0 0.00 0.00 21 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long) [34]
-----------------------------------------------
0.00 0.00 2/20 parseArgs(int, char**) [47]
0.00 0.00 18/20 main [1]
[35] 0.0 0.00 0.00 20 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_invoke(std::_Any_data const&, CliArgs const&) [35]
-----------------------------------------------
0.00 0.00 3/19 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [39]
0.00 0.00 4/19 parseArgs(int, char**) [47]
0.00 0.00 5/19 CliCommand::~CliCommand() [38]
0.00 0.00 7/19 main [1]
[36] 0.0 0.00 0.00 19 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [36]
-----------------------------------------------
0.00 0.00 1/11 main [1]
0.00 0.00 10/11 parseArgs(int, char**) [47]
[37] 0.0 0.00 0.00 11 bool std::operator==<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) [37]
-----------------------------------------------
0.00 0.00 9/9 main [1]
[38] 0.0 0.00 0.00 9 CliCommand::~CliCommand() [38]
0.00 0.00 5/19 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [36]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [42]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [41]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [40]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [43]
-----------------------------------------------
0.00 0.00 7/7 main [1]
[39] 0.0 0.00 0.00 7 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [39]
0.00 0.00 14/21 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long) [34]
0.00 0.00 3/19 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [36]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [41]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [40]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [43]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [42]
-----------------------------------------------
0.00 0.00 1/3 main [1]
0.00 0.00 1/3 CliCommand::~CliCommand() [38]
0.00 0.00 1/3 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [39]
[40] 0.0 0.00 0.00 3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [40]
-----------------------------------------------
0.00 0.00 1/3 main [1]
0.00 0.00 1/3 CliCommand::~CliCommand() [38]
0.00 0.00 1/3 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [39]
[41] 0.0 0.00 0.00 3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [41]
-----------------------------------------------
0.00 0.00 1/3 main [1]
0.00 0.00 1/3 CliCommand::~CliCommand() [38]
0.00 0.00 1/3 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [39]
[42] 0.0 0.00 0.00 3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [42]
-----------------------------------------------
0.00 0.00 1/3 main [1]
0.00 0.00 1/3 CliCommand::~CliCommand() [38]
0.00 0.00 1/3 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [39]
[43] 0.0 0.00 0.00 3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [43]
-----------------------------------------------
0.00 0.00 2/2 __static_initialization_and_destruction_0() [69]
[44] 0.0 0.00 0.00 2 std::_Hashtable<TokenType, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > >, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > >, std::__detail::_Select1st, std::equal_to<TokenType>, std::hash<TokenType>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_Hashtable<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*>(std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, unsigned long, std::hash<TokenType> const&, std::equal_to<TokenType> const&, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > > const&, std::integral_constant<bool, true>) [44]
-----------------------------------------------
0.00 0.00 2/2 __static_initialization_and_destruction_0() [69]
[45] 0.0 0.00 0.00 2 std::_Hashtable<std::basic_string_view<char, std::char_traits<char> >, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType>, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> >, std::__detail::_Select1st, std::equal_to<std::basic_string_view<char, std::char_traits<char> > >, std::hash<std::basic_string_view<char, std::char_traits<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_Hashtable<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*>(std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, unsigned long, std::hash<std::basic_string_view<char, std::char_traits<char> > > const&, std::equal_to<std::basic_string_view<char, std::char_traits<char> > > const&, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> > const&, std::integral_constant<bool, true>) [45]
-----------------------------------------------
0.00 0.00 1/1 cmdTokens(CliArgs const&) [2]
[46] 0.0 0.00 0.00 1 readSource[abi:cxx11](CliArgs const&) [46]
0.00 0.00 1/21 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long) [34]
-----------------------------------------------
0.00 0.00 1/1 main [1]
[47] 0.0 0.00 0.00 1 parseArgs(int, char**) [47]
0.00 0.00 10/11 bool std::operator==<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) [37]
0.00 0.00 4/19 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [36]
0.00 0.00 2/20 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_invoke(std::_Any_data const&, CliArgs const&) [35]
-----------------------------------------------
0.00 0.00 1/1 Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [50]
[48] 0.0 0.00 0.00 1 SourceFile::computeLineStarts() [48]
-----------------------------------------------
0.00 0.00 1/1 Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [50]
[49] 0.0 0.00 0.00 1 SourceFile::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [49]
-----------------------------------------------
0.00 0.00 1/1 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [3]
[50] 0.0 0.00 0.00 1 Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [50]
0.00 0.00 1/1 SourceFile::computeLineStarts() [48]
0.00 0.00 1/1 SourceFile::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [49]
-----------------------------------------------
0.00 0.00 1/1 main [1]
[51] 0.0 0.00 0.00 1 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_invoke(std::_Any_data const&, CliArgs const&) [51]
-----------------------------------------------
This table describes the call tree of the program, and was sorted by
the total amount of time spent in each function and its children.
Each entry in this table consists of several lines. The line with the
index number at the left hand margin lists the current function.
The lines above it list the functions that called this function,
and the lines below it list the functions this one called.
This line lists:
index A unique number given to each element of the table.
Index numbers are sorted numerically.
The index number is printed next to every function name so
it is easier to look up where the function is in the table.
% time This is the percentage of the `total' time that was spent
in this function and its children. Note that due to
different viewpoints, functions excluded by options, etc,
these numbers will NOT add up to 100%.
self This is the total amount of time spent in this function.
children This is the total amount of time propagated into this
function by its children.
called This is the number of times the function was called.
If the function called itself recursively, the number
only includes non-recursive calls, and is followed by
a `+' and the number of recursive calls.
name The name of the current function. The index number is
printed after it. If the function is a member of a
cycle, the cycle number is printed between the
function's name and the index number.
For the function's parents, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the function into this parent.
children This is the amount of time that was propagated from
the function's children into this parent.
called This is the number of times this parent called the
function `/' the total number of times the function
was called. Recursive calls to the function are not
included in the number after the `/'.
name This is the name of the parent. The parent's index
number is printed after it. If the parent is a
member of a cycle, the cycle number is printed between
the name and the index number.
If the parents of the function cannot be determined, the word
`<spontaneous>' is printed in the `name' field, and all the other
fields are blank.
For the function's children, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the child into the function.
children This is the amount of time that was propagated from the
child's children to the function.
called This is the number of times the function called
this child `/' the total number of times the child
was called. Recursive calls by the child are not
listed in the number after the `/'.
name This is the name of the child. The child's index
number is printed after it. If the child is a
member of a cycle, the cycle number is printed
between the name and the index number.
If there are any cycles (circles) in the call graph, there is an
entry for the cycle-as-a-whole. This entry shows who called the
cycle (as parents) and the members of the cycle (as children.)
The `+' recursive calls entry shows the number of function calls that
were internal to the cycle, and the calls entry for each member shows,
for that member, how many times it was called from other members of
the cycle.
Copyright (C) 2012-2026 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
Index by function name
[46] readSource[abi:cxx11](CliArgs const&) [28] Lexer::beginPosition() [5] SourceFile::offsetToLocation(int) const
[2] cmdTokens(CliArgs const&) [50] Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [44] std::_Hashtable<TokenType, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > >, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > >, std::__detail::_Select1st, std::equal_to<TokenType>, std::hash<TokenType>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_Hashtable<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*>(std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, unsigned long, std::hash<TokenType> const&, std::equal_to<TokenType> const&, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > > const&, std::integral_constant<bool, true>)
[47] parseArgs(int, char**) [29] Lexer::acceptPosition() [45] std::_Hashtable<std::basic_string_view<char, std::char_traits<char> >, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType>, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> >, std::__detail::_Select1st, std::equal_to<std::basic_string_view<char, std::char_traits<char> > >, std::hash<std::basic_string_view<char, std::char_traits<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_Hashtable<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*>(std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, unsigned long, std::hash<std::basic_string_view<char, std::char_traits<char> > > const&, std::equal_to<std::basic_string_view<char, std::char_traits<char> > > const&, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> > const&, std::integral_constant<bool, true>)
[38] CliCommand::~CliCommand() [22] Lexer::skipWhiteSpace() [36] std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
[48] SourceFile::computeLineStarts() [18] Lexer::isEnd() [51] std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_invoke(std::_Any_data const&, CliArgs const&)
[49] SourceFile::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [25] Lexer::toChar(int) [40] std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) (std_function.h)
[32] NumberToken::~NumberToken() [24] Lexer::getchar(int) [41] std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) (std_function.h)
[33] KeywordToken::~KeywordToken() [19] Lexer::getchar() [42] std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) (std_function.h)
[30] OperatorToken::OperatorToken() [20] Lexer::include(std::basic_string_view<char, std::char_traits<char> >, bool) [35] std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_invoke(std::_Any_data const&, CliArgs const&) (std_function.h)
[31] OperatorToken::~OperatorToken() [26] Lexer::nextChar() [43] std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) (std_function.h)
[10] DelimiterToken::DelimiterToken() [21] Lexer::getOffset() [39] std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&)
[9] DelimiterToken::~DelimiterToken() [8] Lexer::isNumeric() [34] void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long)
[27] IdentifierToken::~IdentifierToken() [11] Tokenizer::readIdentifier() [23] std::__detail::_Map_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
[6] Lexer::getLocation() [3] Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [37] bool std::operator==<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*)
[7] Lexer::readNumeric() [4] Tokenizer::scope()

View File

@ -1,406 +0,0 @@
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
81.25 0.26 0.26 66967977 0.00 0.00 Lexer::include(std::basic_string_view<char, std::char_traits<char> >, bool)
9.38 0.29 0.03 1059636 0.00 0.00 Tokenizer::scope()
6.25 0.31 0.02 _init
3.12 0.32 0.01 1064503 0.00 0.00 SourceFile::offsetToLocation(int) const
0.00 0.32 0.00 2509314 0.00 0.00 Lexer::isEnd()
0.00 0.32 0.00 1851576 0.00 0.00 Lexer::getOffset()
0.00 0.32 0.00 1449678 0.00 0.00 Lexer::getchar()
0.00 0.32 0.00 1059640 0.00 0.00 Lexer::skipWhiteSpace()
0.00 0.32 0.00 1059635 0.00 0.00 Lexer::isNumeric()
0.00 0.32 0.00 750485 0.00 0.00 Lexer::getLocation()
0.00 0.32 0.00 750485 0.00 0.00 Lexer::toChar(int)
0.00 0.32 0.00 461302 0.00 0.00 DelimiterToken::~DelimiterToken()
0.00 0.32 0.00 230202 0.00 0.00 OperatorToken::~OperatorToken()
0.00 0.32 0.00 214740 0.00 0.00 Lexer::nextChar()
0.00 0.32 0.00 175303 0.00 0.00 IdentifierToken::~IdentifierToken()
0.00 0.32 0.00 175303 0.00 0.00 Lexer::beginPosition()
0.00 0.32 0.00 175303 0.00 0.00 Lexer::acceptPosition()
0.00 0.32 0.00 175303 0.00 0.00 Tokenizer::readIdentifier()
0.00 0.32 0.00 133847 0.00 0.00 NumberToken::~NumberToken()
0.00 0.32 0.00 133847 0.00 0.00 Lexer::readNumeric()
0.00 0.32 0.00 58981 0.00 0.00 KeywordToken::~KeywordToken()
0.00 0.32 0.00 58981 0.00 0.00 Lexer::getchar(int)
0.00 0.32 0.00 21 0.00 0.00 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long)
0.00 0.32 0.00 20 0.00 0.00 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_invoke(std::_Any_data const&, CliArgs const&)
0.00 0.32 0.00 19 0.00 0.00 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
0.00 0.32 0.00 11 0.00 0.00 bool std::operator==<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*)
0.00 0.32 0.00 9 0.00 0.00 CliCommand::~CliCommand()
0.00 0.32 0.00 7 0.00 0.00 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&)
0.00 0.32 0.00 3 0.00 0.00 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
0.00 0.32 0.00 3 0.00 0.00 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
0.00 0.32 0.00 3 0.00 0.00 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
0.00 0.32 0.00 3 0.00 0.00 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
0.00 0.32 0.00 2 0.00 0.00 std::_Hashtable<TokenType, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > >, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > >, std::__detail::_Select1st, std::equal_to<TokenType>, std::hash<TokenType>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_Hashtable<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*>(std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, unsigned long, std::hash<TokenType> const&, std::equal_to<TokenType> const&, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > > const&, std::integral_constant<bool, true>)
0.00 0.32 0.00 2 0.00 0.00 std::_Hashtable<std::basic_string_view<char, std::char_traits<char> >, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType>, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> >, std::__detail::_Select1st, std::equal_to<std::basic_string_view<char, std::char_traits<char> > >, std::hash<std::basic_string_view<char, std::char_traits<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_Hashtable<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*>(std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, unsigned long, std::hash<std::basic_string_view<char, std::char_traits<char> > > const&, std::equal_to<std::basic_string_view<char, std::char_traits<char> > > const&, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> > const&, std::integral_constant<bool, true>)
0.00 0.32 0.00 1 0.00 0.00 readSource[abi:cxx11](CliArgs const&)
0.00 0.32 0.00 1 0.00 300.00 cmdTokens(CliArgs const&)
0.00 0.32 0.00 1 0.00 0.00 parseArgs(int, char**)
0.00 0.32 0.00 1 0.00 0.00 SourceFile::computeLineStarts()
0.00 0.32 0.00 1 0.00 0.00 SourceFile::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
0.00 0.32 0.00 1 0.00 0.00 Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
0.00 0.32 0.00 1 0.00 300.00 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
0.00 0.32 0.00 1 0.00 0.00 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_invoke(std::_Any_data const&, CliArgs const&)
% the percentage of the total running time of the
time program used by this function.
cumulative a running sum of the number of seconds accounted
seconds for by this function and those listed above it.
self the number of seconds accounted for by this
seconds function alone. This is the major sort for this
listing.
calls the number of times this function was invoked, if
this function is profiled, else blank.
self the average number of milliseconds spent in this
ms/call function per call, if this function is profiled,
else blank.
total the average number of milliseconds spent in this
ms/call function and its descendents per call, if this
function is profiled, else blank.
name the name of the function. This is the minor sort
for this listing. The index shows the location of
the function in the gprof listing. If the index is
in parenthesis it shows where it would appear in
the gprof listing if it were to be printed.
Copyright (C) 2012-2026 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
Call graph (explanation follows)
granularity: each sample hit covers 4 byte(s) for 3.12% of 0.32 seconds
index % time self children called name
<spontaneous>
[1] 93.8 0.00 0.30 main [1]
0.00 0.30 1/1 cmdTokens(CliArgs const&) [2]
0.00 0.00 18/20 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_invoke(std::_Any_data const&, CliArgs const&) [33]
0.00 0.00 9/9 CliCommand::~CliCommand() [36]
0.00 0.00 7/19 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [34]
0.00 0.00 7/7 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [37]
0.00 0.00 4/21 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long) [32]
0.00 0.00 1/1 parseArgs(int, char**) [45]
0.00 0.00 1/11 bool std::operator==<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) [35]
0.00 0.00 1/1 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_invoke(std::_Any_data const&, CliArgs const&) [49]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [40]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [39]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [38]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [41]
-----------------------------------------------
0.00 0.30 1/1 main [1]
[2] 93.8 0.00 0.30 1 cmdTokens(CliArgs const&) [2]
0.00 0.30 1/1 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [3]
0.00 0.00 461302/461302 DelimiterToken::~DelimiterToken() [23]
0.00 0.00 230202/230202 OperatorToken::~OperatorToken() [24]
0.00 0.00 175303/175303 IdentifierToken::~IdentifierToken() [26]
0.00 0.00 133847/133847 NumberToken::~NumberToken() [29]
0.00 0.00 58981/58981 KeywordToken::~KeywordToken() [30]
0.00 0.00 2/21 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long) [32]
0.00 0.00 1/1 readSource[abi:cxx11](CliArgs const&) [44]
-----------------------------------------------
0.00 0.30 1/1 cmdTokens(CliArgs const&) [2]
[3] 93.8 0.00 0.30 1 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [3]
0.03 0.27 1059636/1059636 Tokenizer::scope() [4]
0.00 0.00 175303/175303 Tokenizer::readIdentifier() [9]
0.00 0.00 1059635/2509314 Lexer::isEnd() [17]
0.00 0.00 1/1 Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [48]
-----------------------------------------------
0.03 0.27 1059636/1059636 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [3]
[4] 93.2 0.03 0.27 1059636 Tokenizer::scope() [4]
0.26 0.00 66967977/66967977 Lexer::include(std::basic_string_view<char, std::char_traits<char> >, bool) [5]
0.00 0.01 750485/750485 Lexer::getLocation() [8]
0.00 0.00 133847/133847 Lexer::readNumeric() [10]
0.00 0.00 1500970/1851576 Lexer::getOffset() [18]
0.00 0.00 1059774/2509314 Lexer::isEnd() [17]
0.00 0.00 1059773/1449678 Lexer::getchar() [19]
0.00 0.00 1059640/1059640 Lexer::skipWhiteSpace() [20]
0.00 0.00 1059635/1059635 Lexer::isNumeric() [21]
0.00 0.00 750485/750485 Lexer::toChar(int) [22]
0.00 0.00 58981/58981 Lexer::getchar(int) [31]
0.00 0.00 138/214740 Lexer::nextChar() [25]
-----------------------------------------------
0.26 0.00 66967977/66967977 Tokenizer::scope() [4]
[5] 81.2 0.26 0.00 66967977 Lexer::include(std::basic_string_view<char, std::char_traits<char> >, bool) [5]
-----------------------------------------------
<spontaneous>
[6] 6.2 0.02 0.00 _init [6]
-----------------------------------------------
0.00 0.00 138715/1064503 Lexer::readNumeric() [10]
0.00 0.00 175303/1064503 Tokenizer::readIdentifier() [9]
0.01 0.00 750485/1064503 Lexer::getLocation() [8]
[7] 3.1 0.01 0.00 1064503 SourceFile::offsetToLocation(int) const [7]
-----------------------------------------------
0.00 0.01 750485/750485 Tokenizer::scope() [4]
[8] 2.2 0.00 0.01 750485 Lexer::getLocation() [8]
0.01 0.00 750485/1064503 SourceFile::offsetToLocation(int) const [7]
-----------------------------------------------
0.00 0.00 175303/175303 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [3]
[9] 0.5 0.00 0.00 175303 Tokenizer::readIdentifier() [9]
0.00 0.00 175303/1064503 SourceFile::offsetToLocation(int) const [7]
0.00 0.00 389905/2509314 Lexer::isEnd() [17]
0.00 0.00 389905/1449678 Lexer::getchar() [19]
0.00 0.00 350606/1851576 Lexer::getOffset() [18]
0.00 0.00 214602/214740 Lexer::nextChar() [25]
0.00 0.00 175303/175303 Lexer::beginPosition() [27]
0.00 0.00 175303/175303 Lexer::acceptPosition() [28]
-----------------------------------------------
0.00 0.00 133847/133847 Tokenizer::scope() [4]
[10] 0.4 0.00 0.00 133847 Lexer::readNumeric() [10]
0.00 0.00 138715/1064503 SourceFile::offsetToLocation(int) const [7]
-----------------------------------------------
0.00 0.00 389905/2509314 Tokenizer::readIdentifier() [9]
0.00 0.00 1059635/2509314 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [3]
0.00 0.00 1059774/2509314 Tokenizer::scope() [4]
[17] 0.0 0.00 0.00 2509314 Lexer::isEnd() [17]
-----------------------------------------------
0.00 0.00 350606/1851576 Tokenizer::readIdentifier() [9]
0.00 0.00 1500970/1851576 Tokenizer::scope() [4]
[18] 0.0 0.00 0.00 1851576 Lexer::getOffset() [18]
-----------------------------------------------
0.00 0.00 389905/1449678 Tokenizer::readIdentifier() [9]
0.00 0.00 1059773/1449678 Tokenizer::scope() [4]
[19] 0.0 0.00 0.00 1449678 Lexer::getchar() [19]
-----------------------------------------------
0.00 0.00 1059640/1059640 Tokenizer::scope() [4]
[20] 0.0 0.00 0.00 1059640 Lexer::skipWhiteSpace() [20]
-----------------------------------------------
0.00 0.00 1059635/1059635 Tokenizer::scope() [4]
[21] 0.0 0.00 0.00 1059635 Lexer::isNumeric() [21]
-----------------------------------------------
0.00 0.00 750485/750485 Tokenizer::scope() [4]
[22] 0.0 0.00 0.00 750485 Lexer::toChar(int) [22]
-----------------------------------------------
0.00 0.00 461302/461302 cmdTokens(CliArgs const&) [2]
[23] 0.0 0.00 0.00 461302 DelimiterToken::~DelimiterToken() [23]
-----------------------------------------------
0.00 0.00 230202/230202 cmdTokens(CliArgs const&) [2]
[24] 0.0 0.00 0.00 230202 OperatorToken::~OperatorToken() [24]
-----------------------------------------------
0.00 0.00 138/214740 Tokenizer::scope() [4]
0.00 0.00 214602/214740 Tokenizer::readIdentifier() [9]
[25] 0.0 0.00 0.00 214740 Lexer::nextChar() [25]
-----------------------------------------------
0.00 0.00 175303/175303 cmdTokens(CliArgs const&) [2]
[26] 0.0 0.00 0.00 175303 IdentifierToken::~IdentifierToken() [26]
-----------------------------------------------
0.00 0.00 175303/175303 Tokenizer::readIdentifier() [9]
[27] 0.0 0.00 0.00 175303 Lexer::beginPosition() [27]
-----------------------------------------------
0.00 0.00 175303/175303 Tokenizer::readIdentifier() [9]
[28] 0.0 0.00 0.00 175303 Lexer::acceptPosition() [28]
-----------------------------------------------
0.00 0.00 133847/133847 cmdTokens(CliArgs const&) [2]
[29] 0.0 0.00 0.00 133847 NumberToken::~NumberToken() [29]
-----------------------------------------------
0.00 0.00 58981/58981 cmdTokens(CliArgs const&) [2]
[30] 0.0 0.00 0.00 58981 KeywordToken::~KeywordToken() [30]
-----------------------------------------------
0.00 0.00 58981/58981 Tokenizer::scope() [4]
[31] 0.0 0.00 0.00 58981 Lexer::getchar(int) [31]
-----------------------------------------------
0.00 0.00 1/21 readSource[abi:cxx11](CliArgs const&) [44]
0.00 0.00 2/21 cmdTokens(CliArgs const&) [2]
0.00 0.00 4/21 main [1]
0.00 0.00 14/21 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [37]
[32] 0.0 0.00 0.00 21 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long) [32]
-----------------------------------------------
0.00 0.00 2/20 parseArgs(int, char**) [45]
0.00 0.00 18/20 main [1]
[33] 0.0 0.00 0.00 20 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_invoke(std::_Any_data const&, CliArgs const&) [33]
-----------------------------------------------
0.00 0.00 3/19 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [37]
0.00 0.00 4/19 parseArgs(int, char**) [45]
0.00 0.00 5/19 CliCommand::~CliCommand() [36]
0.00 0.00 7/19 main [1]
[34] 0.0 0.00 0.00 19 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [34]
-----------------------------------------------
0.00 0.00 1/11 main [1]
0.00 0.00 10/11 parseArgs(int, char**) [45]
[35] 0.0 0.00 0.00 11 bool std::operator==<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) [35]
-----------------------------------------------
0.00 0.00 9/9 main [1]
[36] 0.0 0.00 0.00 9 CliCommand::~CliCommand() [36]
0.00 0.00 5/19 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [34]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [40]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [39]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [38]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [41]
-----------------------------------------------
0.00 0.00 7/7 main [1]
[37] 0.0 0.00 0.00 7 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [37]
0.00 0.00 14/21 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long) [32]
0.00 0.00 3/19 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [34]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [39]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [38]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [41]
0.00 0.00 1/3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [40]
-----------------------------------------------
0.00 0.00 1/3 main [1]
0.00 0.00 1/3 CliCommand::~CliCommand() [36]
0.00 0.00 1/3 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [37]
[38] 0.0 0.00 0.00 3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [38]
-----------------------------------------------
0.00 0.00 1/3 main [1]
0.00 0.00 1/3 CliCommand::~CliCommand() [36]
0.00 0.00 1/3 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [37]
[39] 0.0 0.00 0.00 3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [39]
-----------------------------------------------
0.00 0.00 1/3 main [1]
0.00 0.00 1/3 CliCommand::~CliCommand() [36]
0.00 0.00 1/3 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [37]
[40] 0.0 0.00 0.00 3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [40]
-----------------------------------------------
0.00 0.00 1/3 main [1]
0.00 0.00 1/3 CliCommand::~CliCommand() [36]
0.00 0.00 1/3 std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&) [37]
[41] 0.0 0.00 0.00 3 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [41]
-----------------------------------------------
0.00 0.00 2/2 __static_initialization_and_destruction_0() [66]
[42] 0.0 0.00 0.00 2 std::_Hashtable<TokenType, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > >, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > >, std::__detail::_Select1st, std::equal_to<TokenType>, std::hash<TokenType>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_Hashtable<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*>(std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, unsigned long, std::hash<TokenType> const&, std::equal_to<TokenType> const&, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > > const&, std::integral_constant<bool, true>) [42]
-----------------------------------------------
0.00 0.00 2/2 __static_initialization_and_destruction_0() [66]
[43] 0.0 0.00 0.00 2 std::_Hashtable<std::basic_string_view<char, std::char_traits<char> >, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType>, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> >, std::__detail::_Select1st, std::equal_to<std::basic_string_view<char, std::char_traits<char> > >, std::hash<std::basic_string_view<char, std::char_traits<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_Hashtable<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*>(std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, unsigned long, std::hash<std::basic_string_view<char, std::char_traits<char> > > const&, std::equal_to<std::basic_string_view<char, std::char_traits<char> > > const&, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> > const&, std::integral_constant<bool, true>) [43]
-----------------------------------------------
0.00 0.00 1/1 cmdTokens(CliArgs const&) [2]
[44] 0.0 0.00 0.00 1 readSource[abi:cxx11](CliArgs const&) [44]
0.00 0.00 1/21 void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long) [32]
-----------------------------------------------
0.00 0.00 1/1 main [1]
[45] 0.0 0.00 0.00 1 parseArgs(int, char**) [45]
0.00 0.00 10/11 bool std::operator==<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) [35]
0.00 0.00 4/19 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) [34]
0.00 0.00 2/20 std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_invoke(std::_Any_data const&, CliArgs const&) [33]
-----------------------------------------------
0.00 0.00 1/1 Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [48]
[46] 0.0 0.00 0.00 1 SourceFile::computeLineStarts() [46]
-----------------------------------------------
0.00 0.00 1/1 Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [48]
[47] 0.0 0.00 0.00 1 SourceFile::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [47]
-----------------------------------------------
0.00 0.00 1/1 Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [3]
[48] 0.0 0.00 0.00 1 Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [48]
0.00 0.00 1/1 SourceFile::computeLineStarts() [46]
0.00 0.00 1/1 SourceFile::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [47]
-----------------------------------------------
0.00 0.00 1/1 main [1]
[49] 0.0 0.00 0.00 1 std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_invoke(std::_Any_data const&, CliArgs const&) [49]
-----------------------------------------------
This table describes the call tree of the program, and was sorted by
the total amount of time spent in each function and its children.
Each entry in this table consists of several lines. The line with the
index number at the left hand margin lists the current function.
The lines above it list the functions that called this function,
and the lines below it list the functions this one called.
This line lists:
index A unique number given to each element of the table.
Index numbers are sorted numerically.
The index number is printed next to every function name so
it is easier to look up where the function is in the table.
% time This is the percentage of the `total' time that was spent
in this function and its children. Note that due to
different viewpoints, functions excluded by options, etc,
these numbers will NOT add up to 100%.
self This is the total amount of time spent in this function.
children This is the total amount of time propagated into this
function by its children.
called This is the number of times the function was called.
If the function called itself recursively, the number
only includes non-recursive calls, and is followed by
a `+' and the number of recursive calls.
name The name of the current function. The index number is
printed after it. If the function is a member of a
cycle, the cycle number is printed between the
function's name and the index number.
For the function's parents, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the function into this parent.
children This is the amount of time that was propagated from
the function's children into this parent.
called This is the number of times this parent called the
function `/' the total number of times the function
was called. Recursive calls to the function are not
included in the number after the `/'.
name This is the name of the parent. The parent's index
number is printed after it. If the parent is a
member of a cycle, the cycle number is printed between
the name and the index number.
If the parents of the function cannot be determined, the word
`<spontaneous>' is printed in the `name' field, and all the other
fields are blank.
For the function's children, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the child into the function.
children This is the amount of time that was propagated from the
child's children to the function.
called This is the number of times the function called
this child `/' the total number of times the child
was called. Recursive calls by the child are not
listed in the number after the `/'.
name This is the name of the child. The child's index
number is printed after it. If the child is a
member of a cycle, the cycle number is printed
between the name and the index number.
If there are any cycles (circles) in the call graph, there is an
entry for the cycle-as-a-whole. This entry shows who called the
cycle (as parents) and the members of the cycle (as children.)
The `+' recursive calls entry shows the number of function calls that
were internal to the cycle, and the calls entry for each member shows,
for that member, how many times it was called from other members of
the cycle.
Copyright (C) 2012-2026 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
Index by function name
[44] readSource[abi:cxx11](CliArgs const&) [48] Lexer::setSourceText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [7] SourceFile::offsetToLocation(int) const
[2] cmdTokens(CliArgs const&) [28] Lexer::acceptPosition() [42] std::_Hashtable<TokenType, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > >, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > >, std::__detail::_Select1st, std::equal_to<TokenType>, std::hash<TokenType>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_Hashtable<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*>(std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > const*, unsigned long, std::hash<TokenType> const&, std::equal_to<TokenType> const&, std::allocator<std::pair<TokenType const, std::basic_string_view<char, std::char_traits<char> > > > const&, std::integral_constant<bool, true>)
[45] parseArgs(int, char**) [20] Lexer::skipWhiteSpace() [43] std::_Hashtable<std::basic_string_view<char, std::char_traits<char> >, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType>, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> >, std::__detail::_Select1st, std::equal_to<std::basic_string_view<char, std::char_traits<char> > >, std::hash<std::basic_string_view<char, std::char_traits<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_Hashtable<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*>(std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> const*, unsigned long, std::hash<std::basic_string_view<char, std::char_traits<char> > > const&, std::equal_to<std::basic_string_view<char, std::char_traits<char> > > const&, std::allocator<std::pair<std::basic_string_view<char, std::char_traits<char> > const, TokenType> > const&, std::integral_constant<bool, true>)
[36] CliCommand::~CliCommand() [17] Lexer::isEnd() [34] std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
[46] SourceFile::computeLineStarts() [22] Lexer::toChar(int) [49] std::_Function_handler<int (CliArgs const&), int (*)(CliArgs const&)>::_M_invoke(std::_Any_data const&, CliArgs const&)
[47] SourceFile::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [31] Lexer::getchar(int) [38] std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#2}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) (std_function.h)
[29] NumberToken::~NumberToken() [19] Lexer::getchar() [39] std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#3}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) (std_function.h)
[30] KeywordToken::~KeywordToken() [5] Lexer::include(std::basic_string_view<char, std::char_traits<char> >, bool) [40] std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) (std_function.h)
[24] OperatorToken::~OperatorToken() [25] Lexer::nextChar() [33] std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#4}>::_M_invoke(std::_Any_data const&, CliArgs const&) (std_function.h)
[23] DelimiterToken::~DelimiterToken() [18] Lexer::getOffset() [41] std::_Function_handler<int (CliArgs const&), main::{lambda(CliArgs const&)#1}>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) (std_function.h)
[26] IdentifierToken::~IdentifierToken() [21] Lexer::isNumeric() [37] std::vector<CliCommand, std::allocator<CliCommand> >::push_back(CliCommand const&)
[8] Lexer::getLocation() [9] Tokenizer::readIdentifier() [32] void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<true>(char const*, unsigned long)
[10] Lexer::readNumeric() [3] Tokenizer::scan(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [35] bool std::operator==<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*)
[27] Lexer::beginPosition() [4] Tokenizer::scope() [6] _init

View File

@ -1,217 +0,0 @@
# saQut Frontend Yol Haritası — Symbol Table + Semantic Analiz + Optimizasyon
> Bu belge, frontend'i tamamlamaya yönelik dosya-dosya uygulama planıdır.
> Kararların gerekçeleri: `docs/adr-frontend-analiz.md` (ADR-006…019).
> Tartışma akışı: `docs/transkript-frontend-tasarim.md`.
>
> **İlke:** Sıralama katıdır — her faz bir öncekine dayanır. Her faz sonunda
> geçerli örnekle (`examples/fibonacci.sqt`, `examples/source.sqt`) ve CLI
> komutlarıyla doğrulama yapılır; regresyon olmamalıdır. Kod temiz, anlaşılır ve
> yorum satırlarıyla takip edilebilir olmalıdır (header-only tarzı korunur,
> bkz. ADR-003).
>
> ✅ **Birinci kilometre taşı AŞILDI.** Faz 04 uygulandı; `examples/fibonacci.sqt`
> uçtan uca çalışıyor. Bu yol haritası artık tarihsel bir referanstır.
>
> **Sonraki hedefler:** float/double codegen, struct IR, array IR, açık bug'lar
> (#35 bellek sızıntısı, #36 W003 uyarısı, #37 `%=` IR, #38 global değişken IR).
> Güncel "çalışıyor / henüz yok" listesi için bkz. `CLAUDE.md`.
---
## Genel Bakış
```
Faz 0 Temeller Type sınıfı + Diagnostic modülü + Hata kataloğu
Faz 1 AST Refactor ExpressionNode/StatementNode + analiz alanları
Faz 2 Symbol Table Symbol + Scope + SymbolTable + iki-geçişli toplama
Faz 3 Semantic Analiz Tip kontrolü + yapısal doğrulama (diagnostic'e basar)
Faz 4 Optimizasyon Pass manager (fixpoint) + constant folding + dead code
```
Katman eşlemesi (ADR-006):
- **Frontend:** Faz 03
- **Middle-end:** Faz 4
- **Backend:** bu yol haritasının dışında (birincil: IR + bytecode VM, ADR-015;
ileride: C transpile; makine kodu uzak gelecek — "JIT" kapsam dışı)
---
## ✅ Faz 0 — Temeller (Type + Diagnostic + Hata Kataloğu) — TAMAMLANDI
**Bağımlılık:** yok. **Hedef:** her şeyin üstüne kurulacağı temel veri yapıları.
İlgili ADR: 010 (Type), 013 (Diagnostic).
### Dosyalar
| Dosya | İçerik |
|---|---|
| `src/core/type.hpp` | `Type` sınıfı. `enum class TypeKind { Primitive, Array, Struct, Function, Error }`. Primitif alt-tipleri: `int, float, double, char, string, bool, void`. Alanlar: array için `elementType`, function için `returnType`+`paramTypes`, struct için `structName`. Metotlar: `equals(const Type&)`, `toString()`, `toJson()`, factory'ler (`Type::primitive(...)`, `Type::array(...)`, `Type::error()`). |
| `src/diagnostic/diagnostic.hpp` | `enum class DiagLevel { Error, Warning, Note, Hint }`. `struct Diagnostic { DiagLevel level; std::string code; SourceLocation loc; std::string message; std::string hint; }`. **Hata kataloğu** (sabitler/enum): bkz. aşağı. |
| `src/diagnostic/diagnostic_engine.hpp` | `DiagnosticEngine`: `report(Diagnostic)`, `hasErrors()`, `errorCount()`, `printAll(std::ostream&)`, `toJson()`. Diagnostic'leri biriktirir; durdurma kararını pipeline verir (tüm hatalar toplanır, sonra raporlanır — ADR-013). |
### Hata Kataloğu (baştan belirlenir)
| Kod | Anlam | Hangi fazda üretilir |
|---|---|---|
| `E001` | Tanımsız değişken/isim (declare-before-use ihlali dahil — lokal ve **global başlatıcı**, ADR-011) | Faz 2/3 |
| `E002` | Aynı scope'ta çift tanım | Faz 2 |
| `E003` | Tip uyuşmazlığı (gizli dönüşüm yok; literal için bağlama-göre kural, ADR-010) | Faz 3 |
| `E004` | Döngü/switch dışı `break`/`continue` | Faz 3 |
| `E005` | Fonksiyon dışı `return` | Faz 3 |
| `E006` | Return tipi imzaya uymuyor | Faz 3 |
| `E007` | Tanımsız tip (bilinmeyen tip adı) | Faz 2/3 |
| `E008` | Fonksiyon çağrısı argüman sayısı/tipi uyuşmuyor | Faz 3 |
| `E009` | Array boyutu sabit değil / geçersiz | Faz 3 |
| `E010` | **Özyinelemeli/döngüsel struct tanımı** (by-value çevrim → sonsuz boyut, ADR-011) | Faz 2/3 |
| `W001` | Kullanılmayan değişken | Faz 4 |
| `W002` | Sıfıra bölme (sabit folding) | Faz 4 |
| `W003` | Erişilemez (ölü) kod | Faz 4 |
*(Liste uygulamada genişleyebilir; yeni hatalar buraya eklenir.)*
**Literal / başlatıcı kuralları (ADR-010/011) hata kataloğunu nasıl etkiler:**
- `float x = 1;`**hata değil** (tamsayı literali bağlama-göre tiplenir,
kayıpsız). `int y = 1.5;``E003` (kayıp). `float x = anInt;``E003`
(değişken→değişken gizli dönüşüm yok).
- `int a = b; int b = 5;` (global) → `E001` (global başlatıcı declare-before-use).
### Doğrulama
- `Type::equals` / `toString` birim testleri.
- `DiagnosticEngine` topla → `printAll` çıktısı doğru sıralı.
---
## ✅ Faz 1 — AST Refactor (ExpressionNode / StatementNode + analiz alanları) — TAMAMLANDI
**Bağımlılık:** Faz 0 (Type). **Hedef:** node hiyerarşisini ifade/deyim olarak
ayır, analiz alanlarını ekle. İlgili ADR: 012, 013.
### Dosyalar
| Dosya | Değişiklik |
|---|---|
| `src/parser/ast_node.hpp` | İki ara taban ekle: `class ExpressionNode : public ASTNode { Type resolvedType; bool isConstant=false; /* foldedValue */ }` ve `class StatementNode : public ASTNode { bool isReachable=true; }`. |
| `src/parser/nodes/literal.hpp` · `binary_expr.hpp` · `identifier.hpp` · `expressions.hpp` (Call/Member/Index/Postfix) | Bu node'ları `ExpressionNode`'dan türet. |
| `src/parser/nodes/statements.hpp` (Block/If/While/For/DoWhile/Return/Break/Continue/ExpressionStatement) · `declarations.hpp`? | Statement'ları `StatementNode`'dan türet. (VariableDecl/FunctionDecl/StructDecl tartışmalı — declaration; şimdilik `StatementNode` veya doğrudan `ASTNode` altında değerlendirilir.) |
| `src/parser/nodes/identifier.hpp` | `IdentifierNode`'a `Symbol* resolvedSymbol = nullptr;` (Faz 2'de bağlanır). |
| `src/parser/nodes/*.cpp` | `toJson()`/`log()`'a yeni alanları (tip, isReachable) ekle — boş cpp'ler doluyor. |
### Doğrulama
- `saqut ast examples/fibonacci.sqt` hâlâ geçerli JSON (regresyon yok,
`python3 -m json.tool` ile). Parser regresyonu için ayrıca
`examples/parser-stress/Final.sqt` de geçerli JSON üretmeye devam etmeli (bu
dosya **geçerli program değildir**, yalnızca parser/AST stres fixture'ıdır —
semantik fazlarda fixture olarak kullanılmaz).
- Derleme uyarısız (`-Wall -Wextra`).
---
## ✅ Faz 2 — Symbol Table (scope'lu, iki-geçişli toplama) — TAMAMLANDI
**Bağımlılık:** Faz 0, 1. **Hedef:** isim çözümleme + scope + referans toplama.
İlgili ADR: 011, 013.
### Dosyalar
| Dosya | İçerik |
|---|---|
| `src/symbol/symbol.hpp` | `enum class SymbolKind { Variable, Function, Parameter, Struct, Field }`. `struct Symbol { std::string name; SymbolKind kind; Type type; SourceLocation definitionLoc; std::vector<SourceLocation> references; Scope* scope; }`. |
| `src/symbol/scope.hpp` | `class Scope { Scope* parent; std::unordered_map<std::string, Symbol*> symbols; ... }`. `defineLocal()`, `lookupLocal()`. Her katman bir namespace. |
| `src/symbol/symbol_table.hpp` | Scope yığını yönetimi: `enterScope()`, `exitScope()`, `define(Symbol)` (aynı scope'ta duplicate → false + `E002`), `resolve(name)` (içten dışa), `addReference(name, loc)`, `getAllSymbols()`, `toJson()`. |
| `src/symbol/symbol_collector.hpp/.cpp` | **İki geçiş** (ADR-011): **Geçiş 1** → tüm üst-seviye tanımlarını (fonksiyon imzaları, struct isim+alan tipleri, global değişkenler) global scope'a hoist et. **Geçiş 2** → fonksiyon gövdelerine in; lokal'leri declare-before-use ile topla; her `IdentifierNode`'u `resolve()` edip `resolvedSymbol`'a bağla + `addReference`. |
### Notlar
- Scope oluşturan node'lar: Program, FunctionDecl (parametreler), Block, for/while.
- `src/json.hpp`'deki eski `collectSymbolsRecursive` bu sistemle değiştirilir.
- Tanımsız isim → `E001`; bilinmeyen tip → `E007`; çift tanım → `E002`.
- **Döngüsel struct kontrolü (`E010`):** Geçiş 1'den sonra struct'lar düğüm,
"alanı olarak içerir" kenarıyla bir çevrim-arama (DFS) çalıştır; çevrim →
`E010` (ADR-011). Pointer olmadığı için tüm kapsama by-value'dur; çevrim =
sonsuz boyut.
- **Global başlatıcı declare-before-use (ADR-011):** fonksiyon/struct tam hoist
edilir, global değişken **ismi** hoist edilir, ama global değişken
**başlatıcısı** kendinden önce tanımlı isimleri kullanabilir; aksi → `E001`.
### Doğrulama
- `saqut symbols examples/fibonacci.sqt` → zengin tablo (her sembolün tipi, tanım
yeri, referansları). Forward reference çalışır (sonra tanımlı fonksiyon
çağrılabilir — `main`, `fibonacci`'yi çağırır).
- Hatalı örnekler → `E001`/`E002`/`E007`/`E010` diagnostic'leri.
---
## ✅ Faz 3 — Semantic Analiz (Tip Kontrolü + Yapısal Doğrulama) — TAMAMLANDI
**Bağımlılık:** Faz 2. **Hedef:** tipleri ata/kontrol et, yapısal kuralları
doğrula. İlgili ADR: 010, 013.
### Dosyalar
| Dosya | İçerik |
|---|---|
| `src/sema/type_checker.hpp/.cpp` | İfadeleri alttan üste gez, her `ExpressionNode`'a `resolvedType` ata. Gizli **değişken→değişken** dönüşüm yok (ADR-010) → uyuşmazlıkta `E003`. **Tamsayı literali bağlama-göre tiplenir** (kayıpsızsa beklenen tipe uyar; `float x = 1;` geçerli, `int y = 1.5;``E003`). Kontrol noktaları: atama (`=`), binary op operand tipleri, fonksiyon çağrısı argümanları (`E008`), array index, return değeri (`E006`), variable init tip uyumu. Hata olunca node'a `Type::error()` → ardışık sahte hata yok. |
| `src/sema/structural_validator.hpp/.cpp` | Parent pointer ile ağaç-tırmanma kontrolleri: `break`/`continue` döngü/switch içinde mi (`E004`), `return` fonksiyon içinde mi (`E005`), array boyutu sabit mi (`E009`). |
### Notlar
- Bu iki modül + Faz 2'nin collector'ı birlikte "semantic analiz" fazını oluşturur.
- Tüm hatalar toplanır, ilk hatada durulmaz; faz sonunda `DiagnosticEngine`
hepsini raporlar, pipeline durur (ADR-013).
### Doğrulama
- Doğru `.sqt` → temiz geçer, her expression node'unun tipi JSON'da görünür.
- Hatalı `.sqt` örnekleri → tüm semantik hatalar tek seferde listelenir.
---
## ✅ Faz 4 — Optimizasyon Framework — TAMAMLANDI
**Bağımlılık:** Faz 3. **Hedef:** opsiyonel, iteratif, toggle'lı kaynak-seviyesi
optimizasyon. **Orijinali bozmaz — klon üstünde** (ADR-007). İlgili ADR: 007, 008, 009.
### Dosyalar
| Dosya | İçerik |
|---|---|
| `src/core/config.hpp` | `CompilerConfig`: pass toggle'ları (`optConstantFolding`, `optDeadCodeElim`, …), `outputFormat`, `mode`, `optimized` bayrağı. |
| `src/opt/optimization_pass.hpp` | Soyut `OptimizationPass`: `virtual bool run(ASTNode* root, SymbolTable* table) = 0;` (değişiklik yaptıysa true). `name()`. |
| `src/opt/optimization_manager.hpp` | Pass listesi; `CompilerConfig`'e göre seçim; **fixpoint döngüsü** (hiçbir pass değişiklik yapmayana kadar + **sert iterasyon tavanı** `maxFixpointRounds`, ADR-009). **Sonlanma değişmezi:** havuzdaki pass'ler monoton (yalnızca küçültür); büyüten pass (inlining) eklenirse tavan zorunlu. Çalışmadan önce AST'yi **klonlar**`ASTNode::clone()` **merkezi bir bileşendir** (ADR-007): parent pointer'lar yeniden bağlanır, sembol tablosu klonlanıp `IdentifierNode→Symbol` bağları **remap** edilir. **Her turda**, klon üzerinde akışa-bağlı analiz (`isReachable`, ref-count) **yeniden hesaplanır** (ADR-009); aksi halde zincirleme fırsatlar bayat veriyle kaçar. |
| `src/opt/constant_folding.hpp/.cpp` | `BinaryExpression` operandları sabitse hesapla, sonucu sabit `Literal` ile değiştir (klonda). Tipe saygılı (`5/2`→int `2`, ADR-010). Sıfıra bölme → `W002`, katlama yapma. |
| `src/opt/dead_code_elim.hpp/.cpp` | `isReachable` (Faz 3) işaretine göre: `return`/`break`/`continue` sonrası statement'lar, `if(false)`, sıfır-referanslı değişken (`W001`/`W003`). |
### CLI Entegrasyonu
| Dosya | Değişiklik |
|---|---|
| `src/cli/args.hpp` | `--optimized` ve `--opt-all`/`--opt-none`/`--skip-*` bayrakları`CompilerConfig`. |
| `src/cli/commands/ast.hpp` · `symbols.hpp` | `--optimized` verilince klon+optimize edilmiş hali göster; verilmezse orijinal. |
### Doğrulama
- `saqut ast file --optimized``1+2` katlanmış, ölü kod elenmiş.
- `saqut ast file` (bayraksız) → orijinal, **değişmemiş** (öncesi/sonrası ayrımı).
- Fixpoint: zincirleme optimizasyon (folding → yeni dead code → DCE) yakalanır.
---
## Tamamlanınca
Bu yol haritası bittiğinde frontend tamamlanmış olur:
- Parser → analizli, tipli, sembol-çözümlü AST + zengin symbol table.
- Tam hata raporlama (toplu, kataloglu).
- Opsiyonel, incelenebilir optimizasyon.
Sonraki adım (ayrı yol haritası): **IR güçlendirme** (kontrol akışı/fonksiyon/
bellek opcode'ları + **FFI seam** `callhost`, ADR-016) → **bytecode VM ile
çalıştırma** (ADR-015) → hedef: **`examples/fibonacci.sqt` derlenir ve çalışır.**
- **Çalıştırma modeli IR + bytecode VM'dir** (ADR-015). **Makine-kodu JIT
ıkça kapsam dışıdır;** öncelik determinizm + incelenebilirlik, ham hız değil.
- **C transpile**, ileride geçerli bir **ikinci** backend olarak kalır (frontend
backend-bağımsız). Makine kodu gerçekten istenirse libgccjit/LLVM'e bağlanılır
— çok uzak gelecek.
- IR/VM tasarlanırken **FFI seam'i şimdiden bırak** (ADR-016); `print` ilk
müşteridir. Bellek host (C++) heap'idir; özel allocator yok. Dinamik array'in
runtime modeli (ADR-014) bu fazda netleşir.
> Çerçeve uyarısı: bu sonraki adım da **önce dikey dilim** ilkesine tabidir —
> genel VM/optimizasyon altyapısı kurmadan önce fibonacci uçtan uca çalışsın.

View File

@ -1,186 +0,0 @@
# Sonnet Uygulama Promptu — Bileşik Tipler Runtime'ı (ADR-020…024)
> Bu dosya bir **devir teslim promptu**. Opus ile yapılan mimari oturumda 5 karar
> alındı (ADR-020…024). Bu plan o kararları **koda döker.** Kararları yeniden
> sorma — uygula. İletişim Türkçe; commit sonu `Co-Authored-By: Claude Opus 4.8
> <noreply@anthropic.com>`; dal `0.1.0`.
---
## 0. Nerede kaldık (bağlam)
Bu oturumda kilitlenen mimari kararlar (tümü `docs/adr-frontend-analiz.md`):
| ADR | Karar (özet) |
|---|---|
| **020** | Primitive (`int`/`float`/`bool`) = **değer**; bileşik (`struct`/`array`/`string`) = **referans** (JS/Java/C# modeli). "Pointer yok" = kullanıcıya `&`/`*` *sözdizimi* yok; runtime referansı kullanır. |
| **021** | Null güvenliği: varsayılan **non-null**; nullable açıkça `Type?`. Akış-duyarlı null analizi (compile-time, runtime sıfır). `a!` = runtime-kontrollü iddia. |
| **022** | GC: basit **taşımasız, stop-the-world, deterministik mark-sweep**. Nesne modeli **baştan GC-hazır** (header + kök sayımı + çocuk sayımı). v1: toplama YOK. **`shared_ptr`'ı kalıcı sahiplik modeli YAPMA.** |
| **023** | `==`: primitive değer; referans (struct/array) **kimlik** (aynı nesne); string **içerik**. Derin eşitlik asla `==`'e bağlanmaz → ayrı `deepEquals()`. |
| **024** | String = **immutable değer-tipi, iç temsil UTF-8**. `s+"x"` yeni string üretir; `==` içerik. |
ık mimari borç: **#56** (döngüsel referans → mark-sweep GC v2). Şimdilik toplama yok, bilinçli.
**Mevcut kod durumu:**
- int-only pipeline uçtan uca çalışıyor (`examples/fibonacci.sqt`).
- `src/vm/value.hpp``Value` = `{ ValueKind kind; int intValue; std::string stringValue; }`. String **inline** (immutable olduğu için yeterli — taşıma zorunlu değil).
- `src/ir/` → 3-adresli IR, slot tabanlı. `instruction.hpp`, `ir_generator.cpp`, `ir_program.hpp`.
- `src/vm/interpreter.cpp` → bytecode yorumlayıcı döngü. `call_frame.hpp` çağrı çerçevesi.
- struct/array: parser + semantik **var**, IR/VM codegen **YOK**.
---
## 1. İlk görev — GC-hazır nesne modeli + ARRAY runtime (dikey dilim)
**Neden array, string değil:** string zaten immutable-değer olarak inline çalışıyor;
asıl kararları (referans semantiği + GC-hazır nesne modeli + kimlik eşitliği)
**doğrulayan** ilk gerçek referans-tipi array'dir. Bu görev, struct'ın da oturacağı
temeli atar.
### KAPSAM DIŞI (bu görevde YAPMA — sonraki görevler)
- ❌ Gerçek çöp toplama (mark-sweep). ADR-022 v1 = toplama yok. Sadece header +
all-objects listesi + kök-sayımı *kancasını* kur.
- ❌ Tam null akış-analizi (ADR-021). `int[]?` parse edilebilir ama flow-narrowing
bu görevde değil.
- ❌ struct codegen, string UTF-8 cilası, builder. Ayrı görevler (Bölüm 2).
- ❌ `shared_ptr` ile nesne sahipliği. Düz `Object*` + intrusive liste.
### Adım 1.1 — Nesne modeli temeli (`src/vm/object.hpp` veya benzeri)
```cpp
enum class ObjectType { Array /*, Struct, String (ileride) */ };
struct Object {
ObjectType type;
bool marked = false; // mark-sweep için (v2); şimdilik kullanılmaz
Object* next = nullptr; // intrusive "tüm nesneler" listesi (mark-sweep tarayışı için)
};
```
- Bir **Heap/allocator**: `Object* allocate(...)` her yeni nesneyi `next` zincirine
ekler. **Free yok** (v1). Yıkıcıda/process exit'te toptan bırak.
- **Kök sayımı kancası:** VM'in operand stack + frame local'leri + global slot'lar
üstünden referansları gezebileceği bir yol bırak (şimdilik imza/TODO yeterli; içini
doldurmak v2). `// TODO(#56): mark-sweep kök taraması buradan` ile işaretle.
### Adım 1.2 — `Value`'yu referans taşıyacak şekilde genişlet (`src/vm/value.hpp`)
- `ValueKind`'a `Ref` ekle (array/struct nesnelerine `Object*`).
- `Value`'ya `Object* ref = nullptr;` alanı + `static Value fromRef(Object*)`.
- `Nil` kind ekle (ADR-021 null: `Type?` null değeri ve referans varsayılanı).
- `isTruthy`/`toString`/`typeName`'i yeni kind'lar için genişlet.
- String inline kalsın (`ValueKind::String`), dokunma.
### Adım 1.3 — ArrayObject
```cpp
struct ArrayObject : Object { // type = ObjectType::Array
std::vector<Value> elements; // homojen (int[] → hepsi Int)
};
```
- Array literali (`[1,2,3]` — **parser'ın mevcut sözdizimini doğrula**, Bölüm 4'e bak)
→ ArrayObject tahsis, `elements` doldur, `Value::fromRef` ile slot'a koy.
### Adım 1.4 — IR opcode'ları + IR üreteci
- `ARRAY_NEW` (literal/boyuttan array oluştur), `ARRAY_GET dest, arr, idx`,
`ARRAY_SET arr, idx, val`, `ARRAY_LEN dest, arr`. (`instruction.hpp` + üreteç.)
- **Referans semantiği:** array bir fonksiyona geçince/atanınca `Value` (içindeki
`Object*`) **kopyalanır ama nesne paylaşılır**`func(arr)` içindeki `ARRAY_SET`
çağıranı etkiler. (Bu, kararın doğrulandığı kritik testtir.)
- **`==` (ADR-023):** array'de **kimlik** → iki `Value`'nun `ref`'i aynı `Object*` mı?
(İçerik DEĞİL.) Mevcut EQ opcode'unu tip-bazlı dallandır veya `REF_EQ` ekle.
### Adım 1.5 — Sınır kontrolü (kafes felsefesi)
- `ARRAY_GET`/`ARRAY_SET` index sınır dışıysa → **temiz runtime hatası** (sessiz UB
değil). saQut "cage" — koruma şart.
### Doğrulama (golden test — `tests/` veya `examples/`)
```c
func degistir(int[] a) {
a[0] = 99;
}
func main() {
int[] x = [1, 2, 3];
degistir(x);
print(x[0]); // 99 ← referans semantiği (ADR-020)
int[] y = x;
print(y == x); // true ← kimlik (aynı nesne, ADR-023)
int[] z = [1, 2, 3];
print(z == x); // false ← içerikçe aynı ama farklı nesne
print(x[1]); // 2
// x[5] → runtime sınır hatası
}
```
`saqut run` ile beklenen çıktı doğrulanmalı. `saqut ir` çıktısı yeni opcode'ları göstermeli.
---
## 2. Sonraki görevler (sıralı — ilk görev bitince)
1. **Struct runtime.** Alanlar (isimli), `StructObject : Object { std::vector<Value> fields; }`.
`struct Node { Node next; }` artık **meşru** (referans → sonlu boyut). **E010
revizyonu:** referansla tutulan struct alanı için döngü artık hata DEĞİL (ADR-020).
Bu görev #56'yı *canlı* hale getirir (döngü kurulabilir, henüz toplanmaz).
2. **String cilası (ADR-024).** İçerik `==`'i doğrula; UTF-8 çok-baytlı pass-through
(`"şğü"` concat+print bozulmasın); bayt-uzunluğu vs karakter ayrımınıık API
olarak işaretle. (İstege bağlı: string'i de Object modeline taşıyıp intern et —
zorunlu değil.)
3. **Null akış-analizi (ADR-021 — REVİZE).** Ayrı **frontend** görevi: `Type?` tip
sistemi + `T <: T?` atama kuralı + katı operand kuralı + akış-duyarlı narrowing
(nested `if` + sıralı guard + `&&`). ⚠️ **`a!`/`??`/`?.` YASAK** — null yalnızca
görünür `if` ile aklanır. `T?` üstünde doğrudan erişim → derleme hatası. Frontend
kesin çözer (backend yeniden analiz etmez). Detay: TODO Bölüm "SIRADAKİ İŞ" + ADR-021.
4. **Hata yönetimi (ADR-025, #57).** Struct-tabanlı yakalanabilir hata (Swift-tarzı):
- **Önkoşul:** IR'a **satır tablosu** (komut index → kaynak konum) — stacktrace için. Şu an taşıyor mu doğrula.
- Standart built-in `struct Error { int line; int char; string message; string trace; string code; }`.
- Klasik **`try { ... } catch (e) { ... }` bloğu** (unwind + en yakın handler'a zıpla); `catch (e)``e : Error`. `throw` ile kullanıcı da kaldırır.
- Runtime null-deref (NPE analoğu), array OOB, /0, `a!` patlaması**yakalanabilir hata**; `message`/`code` = derleyicinin W/E kataloğu.
- **UNCHECKED (Java/C#/JS usulü):** fonksiyon **işaretlenmez** (`noexcept`/`constexpr` tarzı YOK), çağrıda **`try f()` YOK**. İmza-işaretli Swift/Zig modeli KULLANMA.
- Stacktrace = frame stack'ten en içten dışa; insan + JSON; deterministik (adım indeksi/replay handle).
5. **float/double (#44).** Bağımsız; `Value::Float` + FADD… opcode + tip denetleyici.
6. **mark-sweep GC v2 (#56).** Adım 1.1'de bırakılan header+kök kancası üstünde aç.
---
## 3. Uyman gereken kararlar (sorma, uygula)
- Referans semantiği: bileşik = paylaşılan nesne; primitive = kopya (ADR-020).
- Array/struct `==` = **kimlik**; string `==` = **içerik** (ADR-023).
- Nesne modeli GC-hazır ama v1 toplama YOK (ADR-022); `shared_ptr` sahiplik modeli kurma.
- Sınır kontrolü + temiz runtime hataları (kafes felsefesi).
- Erken soyutlama yok: önce çalışan dikey dilim, framework sonra (CLAUDE.md ilkesi).
## 4. Bloklamayan açık noktalar (ilk göreve engel değil — gerekirse Opus'a sor)
- **Array literal sözdizimi:** parser'da `[1,2,3]` mi `{0,1,2}` mi kabul ediliyor?
Mevcut parser'ı **doğrula**; tutarsızsa `[...]` tercih (tip `int[]`). Karar gerekirse işaretle.
- Array sabit-boyut mu büyüyebilir mi: readme "dinamik" der; ilk görevde literal+indeks
yeter, büyütme API'si (`push`/`len`) sonra.
- `int[]` non-null varsayılan (ADR-021) → `int[] a;` init zorunlu; nullable `int[]?`.
- #42 (cast modeli) ve #41 (stdlib politikası) henüz karara bağlanmadı — ilk görevi
bloklamaz; sıraları gelince Opus ile.
---
## 5. Özet — tek cümle
GC-hazır basit nesne modelini kur (header + all-objects listesi, toplama yok), `Value`'ya
referans (`Ref`) + `Null` ekle, **array**'i referans semantiği + kimlik `==` + sınır
kontrolüyle uçtan uca çalıştır; struct ve null-analizi sonraki görevler.
---
## 6. ⚠️ TERMİNOLOJİ KİLİDİ — isimleri değiştirme/icat etme
Bu oturumda `null` yerine `nil` yazıldı; bu tür sapmalar **olmamalı.** Anlaşılan
isimler **aynen** kullanılır. İsmi belirsiz bir şeyle karşılaşırsan **icat etme —
Opus'a sor.**
| Kavram | DOĞRU | YANLIŞ (kullanma) |
|---|---|---|
| Null anahtar sözcüğü / literal | **`null`** | ~~`nil`~~, ~~`none`~~, ~~`void`~~ |
| Nullable tip işareti | **`Type?`** (ör. `int?`, `Node?`) | ~~`Optional<T>`~~, ~~`Type \| null`~~ |
| Non-null iddiası / elvis / safe-call | **YASAK**`if` narrowing kullan | ~~`a!`~~, ~~`a ?? x`~~, ~~`a?.f`~~ (ADR-021 revize) |
| Array literal | **`[1, 2, 3]`** | ~~`{1,2,3}`~~ |
| Array tip | **`int[]`** | ~~`array<int>`~~, ~~`[]int`~~ |
| Hata tipi | **`Error`** (`{line,char,message,trace,code}`) | ~~`Exception`~~, ~~`Err`~~ |
| Hata kaldırma / yakalama | **`throw` / `try` / `catch`** | ~~`raise`~~, ~~`rescue`~~ |
| Fonksiyon | **`func`** | ~~`fn`~~, ~~`function`~~, ~~`def`~~ |
| C++ ValueKind null'u | **`ValueKind::Null`** | ~~`Nil`~~ |
**Genel kural:** ADR'lerde/handoff'ta yazan tam ismi kullan. Yeni bir isim gerekiyorsa
ve ADR'de yoksa, **kendin karar verme** — TODO'ya not düş veya Opus'a sor. Kod
identifier'ları İngilizce (dil sözdizimi), yorum/commit Türkçe.

View File

@ -1,214 +0,0 @@
# saQut Frontend Tasarım Oturumu — Transkript
> Bu belge, frontend (symbol table + semantic analiz + optimizasyon) mimarisinin
> kararlaştırıldığı tasarım oturumunun **sadık bir transkriptidir.** Alınan
> kararların gerekçeleri ADR formatında `docs/adr-frontend-analiz.md`'de,
> uygulama planı `docs/roadmap-frontend.md`'de yer alır. Bu belge ise tartışmanın
> **akışını ve düşünce sürecini** korur — bir kararın nasıl olgunlaştığı, hangi
> itirazların nasıl çözüldüğü buradadır.
---
## 0. Başlangıç durumu
Oturum öncesi tamamlananlar:
- Aşama 0 (SourceLocation / konum takibi) bitirildi: her token ve AST node'u
dosya/satır/sütun/offset taşıyor.
- İki bug giderildi: (1) `location.file` boş geliyordu → `Tokenizer::scan` artık
dosya yolu alıyor; (2) `"kind": true` bug'ı`JsonObject::add`'a `const char*`
overload'u eklendi.
- AST JSON çıktısındaki fazla boşluk/girinti hataları temizlendi.
- Bu işler commit'lendi, master'a merge edildi ve push edildi.
---
## 1. "Rotamız ne? IR/JIT'e geçebilir miyiz?"
**Kullanıcı:** AST ve parser hazır mı? IR ve JIT adımına geçebilir miyiz?
**Asistan (özet):** Henüz değil, doğrudan atlamak riskli. Roadmap durumu:
- Aşama 0 (konum) ✅
- Aşama 1 (CLI/REPL) 🟡 yarım
- Aşama 2 (AST bellek canavarı) 🟡 yarım
- Aşama 3 (Symbol Table) ❌ yok (`src/symbol/` klasörü bile yok)
- Aşama 4 (Feature Toggle) ❌ yok
- Aşama 5 (IR + Backend) ❌ embriyonik (IR'de sadece 5 opcode: mathadd/sub/mul/div,
declare; backend yok)
JIT'e atlamamak için iki engel: (1) Symbol table yok — IR üretimi değişken
çözümlemesi ister; (2) IR'de kontrol akışı/fonksiyon/bellek opcode'ları yok, yani
if/while/fonksiyon derlenemez. Ayrıca ADR-001'e göre strateji: C transpile →
QBE → custom/JIT. JIT "uzun vade".
Önerilen sıra: Symbol Table → IR güçlendirme → C transpile → sonra JIT/QBE.
---
## 2. Kullanıcının vizyonu: 2-pass parser ve AST'yi derinleştirme
**Kullanıcı (özet):** Parser 2 aşamalı olacak. İlk pass syntax'ı çözüp basit
AST'yi bırakacak (tokenler, yerleri, türleri). İkinci pass'te symbol table
kurulacak (değişkenler, türleri, yerleri, kapsamları, kaç kez/nerede kullanıldıkları).
Sonraki tüm operasyonlar AST üzerinden döneceği için AST'de çok fazla ham/işlenmiş
veri olmalı; optimizasyon ve analizler tamamen burada olacak. 2. pass'te ilk AST
ve symbol table kullanılarak: kullanılmayan değişkenler, return sonrası kod,
bir kez atanıp bir kez kullanılan değişkenler, literal-operatör-literal (`1+2`)
kapatılacak (constant folding). Yorumlar/eleştiriler isteniyor.
**Asistan — 4 itiraz/uyarı:**
1. **"AST'yi derinleştirmek" felsefeyle çelişebilir.** "Hiçbir bilgi atılmaz"
prensibi var. `1+2`'yi yıkıcı şekilde `3` yaparsan orijinali silersin →
`saqut ast` artık kullanıcının yazdığını göstermez. Çözüm: **annotation**
(node'a `foldedValue:3` ekle, ağacı bozma) vs **transformation** (asıl silmeyi
AST→IR indirmede yap).
2. **"2. pass" tek pass değil, içine 3 iş tıkıyorsun:** (a) sembol toplama/isim
çözümleme, (b) semantik doğrulama, (c) optimizasyon. Bunlar farklı bağımlılık
sırasına sahip; optimizasyon semantik analiz bitince anlamlı; optimizasyonlar
birbirini tetikler (fixpoint gerekir); ayrı test edilmeli.
3. **"Bir kez atanıp bir kez kullanılan" optimizasyonu ağır.** Def-use chain /
dataflow ister; basit tree-walk değil. Ertele, IR'de yap.
4. **Tip kontrolünü atlamamış ol.** Symbol table tip tutacaksa, `int x = "..."`
hatasını kim yakalar? Her expression node'una sonuç tipi annotate etmek değerli.
İki soru soruldu: constant folding yıkıcı mı annotation mı? Scope kuralı
(forward reference) ne?
---
## 3. Kullanıcının netleştirmesi: pass = derleyici aşaması; optimizasyon nerede?
**Kullanıcı (özet):** "2-pass" sadece parser içindi, optimizasyonu kastetmedim.
Sıralama: 1. pass AST kur, 2. pass symbol table, 3. pass AST'yi derinleştir.
Ölü kodu 3'te sadece işaretleyelim demiştim ama haklısın, optimizasyon kendi
içinde tekrar çalışmalı — belki 5, belki 10 pass; her pass öncekinden rahat.
**Önemli soru:** Optimizasyonları tam derleme/IR üretme zamanından önce
yapmamız gerekmiyor mu? Neden AST aşamasında optimize edeceğimizi düşündün?
Parametre olarak AST isteniyorsa optimizasyon halini isteğe bağlı vermeliyiz;
kullanıcı AST'nin/symbol table'ın optimizasyon öncesi/sonrası halini görmek
isteyebilir.
**Scope:** Bunu JIT veya compiler frontend olarak düşünüyorum; arka planda Java
gibi forward reference olan ama C syntax'lı bir dil. Başta OOP yok, JS gibi düşün.
**Asistan:**
- "Pass" düzeltmesi kabul: "5-10 pass" değil **fixpoint** (değişiklik durana
kadar). Her **tur** daha az iş yapar; analiz pass'leri bir kez çalışır.
- "Neden AST'de optimize?" sorusuna dürüst cevap: Ben "optimize" değil
"annotate" demiştim. **Analiz (gerçekler) vs optimizasyon (değişiklik)** ayrımı.
Frontend/middle-end/backend katmanlaması tanıtıldı. Basit kaynak-seviyesi
optimizasyonlar AST'de (backend-bağımsız, incelenebilir); ağır dataflow
optimizasyonları IR'de. Backend'e koyarsak 3 backend'de 3 kez yazarız.
- **Kullanıcının "öncesi/sonrası görebilmeli" gereksinimi mimariyi belirledi:**
optimizasyon orijinali ASLA bozmamalı → klon üret. `saqut ast` öncesi,
`saqut ast --optimized` sonrası.
- Scope kararı önerildi: üst seviye tam forward reference (2 alt-geçiş), lokal
declare-before-use. "Local hoisting istiyor musun?" sorusu soruldu.
---
## 4. Tipli dil, hoisting yok; kalan tasarım sorunları
**Kullanıcı (özet):** JS'i sadece syntax basitliği için örnek verdim, kötü
yanlarını almıyoruz — null/undefined karmaşası yok. Lokal'de hoisting olmasın,
tipli dil olacak. Pass = derleyicinin kendi aşamaları (lexing/parsing/optimizing/
compiling), bunları çoğaltabiliriz. Scope: tam forward reference olsun.
Başka sorun var mı?
**Asistan — "pass = aşama" doğrulandı,** her aşama bağımsız çalışan modül; CLI
komutları bunun yansıması. Sonra **3 gerçek mesele + küçük kararlar:**
1. **Tip sistemi hiç tanımlanmadı.** `varType` şu an sadece string. Minimal ama
genişletilebilir `Type` sınıfı gerek. Tip çıkarımı (auto)? Implicit conversion?
2. **Diagnostic altyapısı şimdi gelmeli.** Semantik analiz hata üretecek ama
koyacak yer yok. Aşama 6'nın tamamı değil ama minimal `Diagnostic` toplayıcı
bu işle birlikte gelmeli.
3. **Annotation'lar node'larda nerede yaşayacak?** `ExpressionNode`/`StatementNode`
ara tabanları önerisi.
Küçük kararlar: overloading yok; scope granülerliği (Program/FunctionDecl/Block/
for-while); recursive struct → pointer gelince; aritmetik semantiği (5/2 int mi).
---
## 5. Kullanıcının kapsam kararları + sorular
**Kullanıcı (özet):** En baştan: pointer sistemi yok, tipleme basit, tuple
(`<T,U>`) yok, class yok struct var, array'ler define sırasında `[]` ile —
ama dinamik mi statik bellek mi karar veremedim. Fonksiyonlar tipli. `class`
gibi keyword'leri dikkate alma, `auto` yok. Otomatik float↔int dönüşümü yok,
her şey açık; gizli dönüşüm istemiyorum, sadece constant'larda (`5/2`→`2`).
Minimal Type sınıfına katılıyorum ama ileride geliştirilebilir olmalı — bu dilin
geleceğini bilmiyorum, popüler de olabilir, tozlanabilir de. Diagnostic için tüm
hataları baştan belirlemeliyiz; sistemi durdurup tüm hataları kullanıcıya
söylemeliyiz; hata raporlama fonksiyonları ayrı bir yerde olsun. Recursive struct
define yok ama `struct StructA { StructB BVar }` olabilir. Scope granülerliği
onaylandı. Duplicate'i tamamen yok et. For döngüsü içindeki objeler dışında
silinebilir — ama symbol table'ı karmaşıklaştırır, her katmanda namespace
tutmalıyız; üst katmanda hem öncesi hem sonrası aranacak — symbol table da mı 2
geçiş olacak? AST'nin temiz kalması neyi zorlaştırır bilmiyorum, sen karar ver.
AST node cpp dosyaları neredeyse boş, oraları kullanalım, o class'ları dolduralım.
**ExpressionNode konusunu tam anlamadım, açar mısın?** Ben tüm analizi AST'de
yapar, her node'da anlamlı veri tutar, ref'leri kendi içimde pointer olarak
tutarım diye düşünüyordum.
**Asistan cevapları:**
- **Array:** Pointer yoksa dinamik array kuramazsın (heap+gizli pointer ister).
Öneri: statik sabit boyut. *(Bu karar bir sonraki turda revize edildi — bkz. §6.)*
- **ExpressionNode = aslında aynı fikirdeyiz.** Sorum felsefi değil, C++ detayı:
`resolvedType`'ı hangi node'a koyacağız? Tipli dilde sadece ifadelerin tipi var
(`5+3`→int; `if`→tipsiz). İki ara taban (`ExpressionNode`/`StatementNode`)
alanları doğru yere koyar + "burası ifade olmalı" kontrolü sağlar. Analiz yine
AST'de yaşar; bu sadece alanları doğru sınıflara dağıtmak.
- **Symbol table 2 geçiş?** Evet ama sadece üst seviyede. Geçiş 1: global'leri
hoist et. Geçiş 2: gövdelere in, çöz. Fonksiyon içi tek geçiş (lokal'de forward
ref yok). Öncesi/sonrası derdi sadece global'ler için, onu Geçiş 1 çözer.
- **AST temiz vs her şey AST'de → karar: her şey AST'de** (senin modelin).
Optimizasyon klonda dönüştürür. **Önemli:** "kaç kez kullanıldı" Symbol'da
yaşar (değişkene ait), node'da değil; IdentifierNode Symbol'a pointer tutar.
- **Hoisting açıklaması** (kullanıcı "local hoisting ne demek, global=local değil
mi?" diye sordu): Hoisting = tanımın yazıldığı satırdan önce de görünmesi.
Global'de forward ref güvenli (gövde tanımda çalışmaz, çağrılınca çalışır).
Lokal'de declare-before-use (değişkenin sırası/değeri var). Asimetri =
tutarsızlık değil, tam olarak Java'nın davranışı.
---
## 6. Pointer netleştirmesi + son onaylar
**Kullanıcı (özet):** Yanlış anlama düzeltmesi: pointer derleyici **içinde** tabii
ki var; programlama **dilinde** `*`/`&` yok. Pointer sadece derleyicinin içinde.
Bu, değişken listelerini destekler — JS'te pointer syntax'ı yok ama array var.
Kullanıcıya pointer yok, arka planda A'dan Z'ye pointer var. Ayrıca: local
hoisting senin dediğin gibi (declare-before-use). Array'ler `int[]` olsun.
**Ama bu backend'de dinamik bellek zorunluluğu getirmez mi? JIT'te?**
ExpressionNode → evet ekle. Her şey temiz, anlaşılır, yorum satırlarıyla
takip edilebilir olsun yeter.
**Asistan:**
- **Array kararı revize edildi:** Pointer arka planda olduğuna göre dinamik
array mümkün. Frontend için `Type` sadece "array of T" temsil etsin, boyut
tipte olmasın. Runtime bellek modeli (statik/heap/free) backend kararı, ertelendi.
- **Dinamik bellek/JIT yükümlülüğü cevabı:** Evet ileride yükümlülük getirir ama
frontend'i bloklamaz. C transpile'da malloc/realloc/free ile neredeyse bedava;
JIT'te minik runtime kütüphanesine call emit edilir; yönetim stratejisi en
basiti scope-tabanlı ownership, GC gerekmez.
- Tüm kararlar kilitlendi; dosya-dosya yol haritası sunuldu (Faz 0…4).
---
## 7. Belgeleme talebi
**Kullanıcı:** Konuştuklarımızı ve kararları ADR formatında, neden öyle yaptığımızı
da belgele; hiçbir şey boş geçmesin; transkript de yazabilirsin; en son yol
haritasını oluştur; her şeyden önce yeni bir branch çık.
**Asistan:** `feature/frontend-analysis` branch'i açıldı. Üç belge üretildi:
- `docs/adr-frontend-analiz.md` (ADR-006…014)
- `docs/transkript-frontend-tasarim.md` (bu belge)
- `docs/roadmap-frontend.md` (uygulama planı)

View File

@ -1,33 +0,0 @@
// saQut — geçerli örnek program (semantik analiz + kod üretimi fixture'ı)
//
// Kilitlenmiş tasarıma uyar: prosedürel, value semantics, kullanıcıya açık
// pointer yok, tek main, struct/array gerektirmez. Birinci kilometre taşının
// ("fibonacci'yi derle ve çalıştır") referans programıdır.
//
// İlk ifade doğrudan bir fonksiyon tanımı olabilir; zorunlu class/main
// boilerplate'i yoktur (Java'nın aksine).
int fibonacci(int n) {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
int fibonacciIterative(int n) {
int first = 0;
int second = 1;
for (int i = 0; i < n; i = i + 1) {
int next = first + second;
first = second;
second = next;
}
return first;
}
int main() {
int n = 10;
print(fibonacci(n)); // recursive
print(fibonacciIterative(n)); // iterative
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
int main() {
print("Merhaba");
print("saQut calisiyor");
return 0;
}

View File

@ -1,15 +0,0 @@
// Ölü kod eleme örneği
// saqut ast file:examples/opt_dce.sqt --optimized
// Beklenen: return sonrasındaki deyimler silinir.
int foo() {
return 42;
int unreachable = 1;
int also_dead = 2;
}
int main() {
int x = foo();
return x;
print("Bu satır asla çalışmaz");
}

View File

@ -1,11 +0,0 @@
// Sabit katlama örneği
// saqut ast file:examples/opt_folding.sqt --optimized
// Beklenen: tüm BinaryExpression'lar Literal'e dönüşür.
int main() {
int a = 2 + 3;
int b = 10 * 4;
int c = 100 / 5;
int d = a + 1;
return 1 * 10 + 2 * 5;
}

View File

@ -1,21 +0,0 @@
# Parser Stres Fixture'ları
Buradaki dosyalar **yalnızca parser/AST'yi zorlamak** için yazılmıştır.
**Geçerli saQut programı değildirler** ve semantik analiz / kod üretimi için
fixture olarak **kullanılmamalıdır**.
## `Final.sqt`
Tarihsel olarak parser'ın token/AST kapsamını test etmek için kullanıldı
(289 token, 200+ AST node). Ancak kilitlenmiş dil tasarımını birden çok yerde
**ihlal eder**:
- **Kullanıcıya açık pointer kullanımı** (`struct List*`, `->`) — dilde `*`/`&`
yoktur (bkz. ADR-014).
- **Sabit boyutlu array** (`int arr[100]`) — array tipi `int[]`'tir, boyut tipin
parçası değildir (bkz. ADR-010).
- **İki `int main()` tanımı** — aynı scope'ta çift tanım yasaktır (ADR-011, `E002`).
- `printf` format-string semantiği — dilin builtin'i `print`'tir; format'lı
çıktı bir kütüphane/FFI işidir (bkz. ADR-017).
Geçerli, küçük bir örnek için `examples/fibonacci.sqt`'ye bakın.

View File

@ -1,9 +0,0 @@
// E008 — yanlış argüman sayısı
int add(int a, int b) {
return a + b;
}
int main() {
int x = add(1, 2, 3);
return 0;
}

View File

@ -1,8 +0,0 @@
// E003 — return tipi uyuşmazlığı
int foo() {
return 1.5;
}
int main() {
return 0;
}

View File

@ -1,5 +0,0 @@
// E004 — break döngü dışında
int main() {
break;
return 0;
}

View File

@ -1,5 +0,0 @@
// E003 — daraltma: float literal → int
int main() {
int x = 1.5;
return 0;
}

View File

@ -1,7 +0,0 @@
// W004 — örtük genişletme: değişken→değişken int→float
int main() {
int a = 5;
float b = 1; // OK: literal bağlama-göre tiplenir, uyarısız
float c = a; // W004: int değişken → float değişken
return 0;
}

View File

@ -1,12 +0,0 @@
// E010 — döngüsel struct (by-value çevrim → sonsuz boyut)
struct A {
B b;
}
struct B {
A a;
}
int main() {
return 0;
}

View File

@ -1,6 +0,0 @@
// E002 — aynı scope'ta çift tanım
int main() {
int x = 1;
int x = 2;
return 0;
}

View File

@ -1,5 +0,0 @@
// E001 — tanımsız isim
int main() {
int x = y + 1;
return 0;
}

View File

@ -1,25 +0,0 @@
int global_x = 10;
int global_y = 3;
int main() {
// global değişken testi (#38)
print(global_x);
print(global_y);
// bitsel AND, OR, SHL, SHR (#45)
int a = 12;
int b = 10;
print(a & b);
print(a | b);
print(1 << 3);
print(16 >> 2);
// unary ~ ve !
int c = 0;
print(!c);
int d = 5;
print(!d);
print(~0);
return 0;
}

227
readme.md
View File

@ -1,186 +1,127 @@
# saQut
# Syntax
> **A compiler built as a toolbox, not a black box —**
> every internal phase is a first-class, inspectable output.
Syntax modunda 2 seçenek bulunmaktadır
- JIR: Söz dizimi tamamen Java programlama diline uygun olarak parse edilmektedir. Compiling, transpiling desteklenir Interpreter desteklenmez
- CIR: Söz dizimi tamamen C programlama diline uygun olarak parse edilir. Compiling ve Interpreter desteklenir. transpiling desteklenmez
# Compiler short options
```
saqut tokens file:fib.sqt → token stream, JSON
saqut ast file:fib.sqt → full AST, JSON
saqut ast file:fib.sqt --optimized → constant-folded + DCE'd AST
saqut run file:fib.sqt → execute via IR + bytecode VM
sqt kaynak kodunu çallıştırır
saqut file:sourcecode.sqt
sqt kaynak kodunu C koduna sonrada makine koduna derler. GCC gereklidir
saqut compile file:sourcecode.sqt output:program.exe
Derleyicinin olduğu gibi çalıştırılması interpreter moduna alır, konsola yazılan kodları alır çalıştırır outputu loglar
saqut
Derleyici kodu alır ve IR üretir
saqut parse file:sourcecode.sqt output:program.ces
Derleyici IRyi alır ve çalıştırır. Burda kaynak kodu veya IR olup olmadığını otomatik anlar
saqut file:sourcecode.ces
Derleyici IRyi veya kaynak kodunu alır C diline çevirir
saqut transpile file:sourcecode.ces output:program.c
Derleyici kaynak kodu ASTsini çıkarır ve kaydeder
saqut file:sourcecode.sqt ast:sourcecode.xml
```
Most compilers are black boxes. saQut is a **glass box.**
---
## What is it?
# Compiler Structure
saQut is a **procedural language compiler** written in C++.
The language is small and C-flavoured on purpose — it is a vehicle, not the product.
The product is **a compilation pipeline where every stage is named, queryable, and machine-readable.**
## 1 Source Code
You can pipe `saqut ast` into your own tool.
You can hand the optimized AST diff to a review script.
A stranger with no access to source could write an LSP from `saqut symbols` output alone.
That is the test saQut is designed to pass.
- Yazılan kaynak kodun derleyiciye aktarılması
- Derleyici için belirlenen seçenekler ile derleyici yapısının yeniden yapılandırılması
- Derleyicinin outputlarının ayarlanması ve çıkışlarının aktarılması
---
## 2 Lexing
## The language looks like this
Kaynak kodun içindeki tüm harflerin gezilip tek parça büyük bir token listesinin oluşturulması
```c
int fibonacci(int n) {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
Bu işlemin sonucunda kaynak kodun içindeki tüm yapılar; semboller, sayılar, stringler ve operatörler olarak 4 kategoriye ayrılır
int fibonacciIterative(int n) {
int first = 0;
int second = 1;
for (int i = 0; i < n; i = i + 1) {
int next = first + second;
first = second;
second = next;
}
return first;
}
## 3 Tokenning
int main() {
int n = 10;
print(fibonacci(n));
print(fibonacciIterative(n));
return 0;
}
```
Tüm tokenler gezilerek bir Abstract Syntax Tree ağacı (AST) oluşturulur. Tek düze tokenler bu aşamada hiyerarşik olarak
- No mandatory `class` / `main` boilerplate
- Typed functions, `struct`, `int[]` arrays
- `int`, `float`, `bool`, `string` literal types
- Value semantics — no user-visible pointers
- Single FFI seam (`callhost`) — the only door to the outside world
File -> Class -> Methods -> Expressions / Statements -> Volumes -> Values
**Deliberately absent:** OOP, closures, generics, implicit int↔float coercion, `auto`.
Şeklinde bir ağaç yapısına kavuşur. Böylece yazılan kaynak kodu anlaşılır ilk yapısına kavuşur
---
## 4 Parsing
## Build
Oluşturulan AST ağacı anlamlaştırılır ve zenginleştirilir. Tanımlanan değerler, fonksiyonlar, classler ve değişkenler belirlenir. Tip kontrolleri ve Syntax hataları burada keşfedilir. Ayrıca Ulaşılamayan kod alanları, sınıfların ulaşılamayan (private) accessorları kontrol edilir, tüm bir kod boyunca class, tipleme, değişken ve döngülerin kullanım adetleri analiz edilir. Sistem içinde kullanılan tüm yapılar için geniş kapsamlı bir Symbol tablosu oluşturulur
**Requirements:** C++17, CMake ≥ 3.16, Ninja
## 5 Optimizing
```bash
git clone https://github.com/abdussamedulutas/saqut
cd saqut
cmake -B build -G Ninja
cmake --build build
```
Zenginleştirilmiş AST üzerindeki analizler üzerinden bazı AST dalları silinir, değiştirilir veya yeni dallar eklenebilir
Binary lands at `build/saqut`.
- Constant Folding : 4 + 1 gibi sonucu belli olan ifadeler 5 olarak tutulur
- Dead Code Elimination : returnden sonraki kod bloğunun silinmesi veya if(false) ve dengi statementlerin yapıdan kaldırılması
- Matematiksel olarak değişmez kodların kaldırılması x * 1, x+0, x * 1 gibi valuelerin direkt x olarak değiştirilmesi
- Hiç kullanılmayan değişkenlerin kaldırılması
- Sabit (const) değerlerin döngülerin dışına çıkarılması veya programın globaline taşınması
- Null Check Elimination : Daha önce nullcheck yapılmış bir değişkenin tekrar nullcheck yapılan kontrollerini devredışı bırakmak
- Type Check Elimination : Daha önce typecheck yapılmış bir değişkenin tekrar typecheck yapılan kontrollerini devredışı bırakmak
**Tested on:** Linux (x86-64, Manjaro). macOS and Windows untested but no platform-specific code.
## 6 Compiling
---
Oluşturulmuş tüm AST ağacını tamamen aynı işi yapan daha alt bir veri kümesine indirgeme işidir. Bellekteki AST yapısı ardışık komutlar dizisine çevrilir (Intermediate Representation) IR daha sonra tekrar okunup çalıştırılabilir.
## CLI
Daha sonra IR ile kurulacak yapı ile bazen HeavyIR bazende LightIR üretilir.
LightIR, en temiz ve hızlı ancak hiç bir ayrıntı içermeyen koddur. Kaynak kodun çalıştırılması için mükemmel veridir ancak debug verilerinden yoksundur
HeavyIR, kaynak kodu verilerinin yanı sıra orjinal AST üzerinde tanımlanmış değişken isimleri ayrıntıları ve tiplemeleride içerir. LightIRye göre daha ayrıntılı ve büyüktür ancak debugging ve kaynak kodun parça parça okunduğu durumlar için (örneğin interpreter) kullanışlıdır
| Command | What you get |
|---|---|
| `saqut tokens file:src.sqt` | Token stream with positions |
| `saqut ast file:src.sqt` | Full AST as JSON |
| `saqut ast file:src.sqt --optimized` | AST after constant folding + dead-code elimination |
| `saqut symbols file:src.sqt` | Symbol table dump |
| `saqut check file:src.sqt` | Semantic analysis only — errors and warnings, JSON |
| `saqut ir file:src.sqt` | IR instruction dump |
| `saqut run file:src.sqt` | Compile and run via bytecode VM |
## 7 Interpreting
Every output is designed to be piped, diffed, or consumed by other tools.
Derleyici HeavyIR üretir ve Symbol tablosunu silmez.
Optimizasyonların çoğu kapatılır.
Oluşturulmuş HeavyIR kodu çalıştırılır çalışma bittikten sonra stackframe kapatılmaz yeni girişler beklenir. Yeni kaynak kodu girişleri yapıldığında yine derlenir ve anında çalıştırılır. Yeni çalıştırılan kaynak kodu bir önceki stackframe içersinde symbol tablosu dikkate alınarak output üretir böylece önceki değerler halen kullanılabilir
---
## or 7 Executing
## Pipeline
Derleyici LightIR üretir IR oluşturulduktan sonra symbol tablosu silinir.
Üretilen IR otomatize edilmiş bellekte yüksek performans ile çalıştırılır.
```
Source
│ Lexer + Tokenizer
Tokens ──────────────────── saqut tokens
│ Pratt parser + recursive descent
AST ─────────────────────── saqut ast
│ Symbol collector (two-pass)
Symbol Table ────────────── saqut symbols
│ Type checker + structural validator
Annotated AST
│ Optimization Manager (clone — original untouched)
│ ├─ Constant Folding pass
│ └─ Dead Code Elimination pass
Optimized AST ───────────── saqut ast --optimized
│ IR Generator
IR ──────────────────────── saqut ir
│ Bytecode VM (interpreter loop)
Output ──────────────────── saqut run
```
Derleyici o an ürettiği kaynak kodu anında çalıştırdığı (JIT) gibi
Daha önce üretilmiş ve depolanmış IR kodunuda çalıştırabilir
The optimizer works on a **clone** of the AST — the original is preserved.
Constant folding and DCE run in a fixpoint loop until nothing changes.
## or 7 Transpiling
---
Derleyici HeavyIR üretir ve Symbol tablosunu silmez.
Derleyici IR üretmez bunun yerine AST Üzerinden yeni bir dile çevrilir.
Duruma göre daha üst bir seviye dile dönüşüm yapıldığı gibi daha alt bir dile dönüşüm yapılabilir. IR üretilmez bunun yerine alınan kaynak kodu farklı bir kaynak koduna çevrilir
## What works right now
# programmable compiler
| Stage | Status |
|---|---|
| Lexer / Tokenizer | ✅ |
| Pratt parser | ✅ |
| AST + JSON serialization | ✅ |
| Symbol table (two-pass collector) | ✅ |
| Type checker | ✅ |
| Structural validator | ✅ |
| Constant folding (int, bool, logical, unary) | ✅ |
| Dead code elimination | ✅ |
| IR generator + bytecode VM | ✅ |
| `saqut run` executes fibonacci | ✅ |
| `string` type | ✅ |
| `struct` | 🚧 |
| `int[]` arrays | 🚧 |
| Standard library / FFI beyond `print` | 🚧 |
Derleyici tek seferde kaynak kodu alıp okuyup çalıştırabilir veya derleyebilir.
Ayrıca debug ortamlarında veya daha ayrıntılı projelerde derleme anına müdehale edilebilir
---
## Stage Session
## Philosophy in two sentences
Derleyiciye verilen bazı parametreler ile Lexer ve Tokenizer anında bazı işlemlerin yapılması engellenebilir
Örneğin accessorler kapatılabilir, hexedecimal sayılar kapatılabilir. Veya class olmadan globale yazılmış kodlar engellenebilir
**Glass:** every compilation stage is a stable, queryable output — tokens, AST, symbols, IR — all separately inspectable and pipeable.
**Cage:** no user pointers, value semantics, single FFI door — the VM is deterministic, which makes record-replay and time-travel debugging a natural extension, not an afterthought.
## AST Session
The long version is in [`docs/architecture.md`](docs/architecture.md).
Derleyiciye verilen bazı parametreler ile class yapılarına müdehale edilebilir, tipleme sistemleri sabitlenebilir, tek bir metot içerisine yazılacak kod sınırlanabilir veya for içerisinde for döngüsü kısıtlanabilir. Yazılan kod için analizler sonucunda bazı bloklar görmezden gelinebilir veya manipüle edilebilir
---
## Optimizing Session
## Design records
Optimizasyon aşamaları parametreler ile tek tek açılabilir veya kapatılabilir
Architectural decisions live in `docs/`:
## Output Session
| File | Coverage |
|---|---|
| [`docs/fikirler.md`](docs/fikirler.md) | ADR-001005: backend strategy, parser, header-only, token, IR |
| [`docs/adr-frontend-analiz.md`](docs/adr-frontend-analiz.md) | ADR-006019: analysis, optimization, execution model, FFI, memory |
| [`docs/roadmap-frontend.md`](docs/roadmap-frontend.md) | Phase-by-phase implementation plan |
| [`docs/architecture.md`](docs/architecture.md) | Full architecture reference (Turkish) |
Derleyici ürettiği veriyi erken bir aşamada dosyalayabilir ve loglayabilir.
Derleyicinin oluşturduğui token, Pure AST, Optimized AST, LightIR veya HeavyIR ayrı ayrı kaydedilebilir
---
## Compiling Session
## License
Source-available, commercial use restricted.
Free for: personal use, learning, writing and running saQut programs, internal tooling.
Requires permission for: hosting as a service, embedding sub-components commercially, redistributing as a product.
See [`LICENSE.md`](LICENSE.md) for the full terms.
Commercial licensing: saqutsoftware+gitea@gmail.com
AST ağacını IRye dönüştürürken neleri aktaracağı derleyici parametre şeklinde verilebilir.
IR, yanlızca JIT ve Compiling modunda değiştirilebilir. Interpreter modunda değiştirilmesine izin verilmez
IR olarak tipleme, sınıflar, değişken isimleri, tekrarlama kayıtları, işlemler ve statementlerin hangilerinin eklenebileceği değiştirilebilir

BIN
saqut Executable file

Binary file not shown.

View File

@ -1,560 +0,0 @@
#!/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ü 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ç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 ık olur "herkese açık" (public-by-default), C'nin extern'siz fonksiyonlarına benzer. Basitlik ı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 ?
- `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 (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 <isim> <argüman sayısı>` IR/bytecode komutu: argümanlar yığından alınır, C++ tarafındaki kayıtlı bir fonksiyon tablosuna (`std::map<std::string, HostFunction>`) 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ü" 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 (`<string>`, `<cmath>`) 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ü" 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 ı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']}")

View File

@ -1,160 +0,0 @@
#!/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 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 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 /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 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 . Burada `Symbol` yapısını tanımla (ad, tür, tip, tanım konumu, referans listesi alanları bulunsun). `Scope` sınıfını 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 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 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 ı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']}")

View File

@ -1,499 +0,0 @@
#!/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) ı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ü 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 ığı 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ıılmalı — IR/VM tasarım issue'larına (#74-78) not edilmeli.
- Sınır kontrolü **her zaman** mı ı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']}")

View File

@ -1,153 +0,0 @@
"""
saQut büyük kaynak dosyası üretici.
Sözdizimsel ve semantik olarak geçerli, çeşitli yapılar içeren
gerçekçi bir .sqt dosyası üretir.
Hedef: ~1 MB
"""
import sys
import random
random.seed(42)
lines = []
def emit(s=""):
lines.append(s)
# ── Başlık ────────────────────────────────────────────────────────────────────
emit("// saQut büyük kaynak dosyası — otomatik üretildi (gen_large.py)")
emit("// Amaç: ast / symbols / check komutları için performans ölçümü")
emit()
# ── Struct tanımları ──────────────────────────────────────────────────────────
STRUCT_COUNT = 20
for i in range(STRUCT_COUNT):
emit(f"struct Vec{i} {{")
emit(f" int x;")
emit(f" int y;")
emit(f" int z;")
emit(f" float w;")
emit(f"}}")
emit()
# ── Global değişkenler ────────────────────────────────────────────────────────
for i in range(50):
emit(f"int g_{i} = {i * 3 + 1};")
emit()
# ── Yardımcı: rastgele aritmetik ifade (derinlik sınırlı) ─────────────────────
def expr(depth=0, vars=None):
if vars is None:
vars = ["a", "b", "c", "x", "n"]
if depth >= 3 or random.random() < 0.35:
choice = random.random()
if choice < 0.5 and vars:
return random.choice(vars)
elif choice < 0.8:
return str(random.randint(1, 100))
else:
return str(random.randint(1, 20))
ops = ["+", "-", "*"]
op = random.choice(ops)
return f"({expr(depth+1, vars)} {op} {expr(depth+1, vars)})"
def cond(vars=None):
if vars is None:
vars = ["a", "b", "n"]
ops = ["<", ">", "<=", ">=", "==", "!="]
op = random.choice(ops)
lhs = expr(0, vars)
rhs = expr(0, vars)
return f"{lhs} {op} {rhs}"
# ── Fonksiyon gövdesi üreteci ─────────────────────────────────────────────────
def gen_body(fn_idx, local_vars, indent=1):
pad = " " * indent
code = []
# 2-5 lokal değişken tanımı — sadece declare edilenleri ifadelerde kullan
n_vars = random.randint(2, 5)
declared = []
for v in local_vars[:n_vars]:
# İlk değişken sadece sabitle başlatılır (henüz başka değişken yok)
init = expr(0, declared if declared else ["1"])
code.append(f"{pad}int {v} = {init};")
declared.append(v)
local_vars = declared # bundan sonra sadece declare edilenleri kullan
# 1-3 if bloğu
for _ in range(random.randint(1, 3)):
c = cond(local_vars)
then_val = expr(0, local_vars)
code.append(f"{pad}if ({c}) {{")
code.append(f"{pad} {local_vars[0]} = {then_val};")
if random.random() < 0.4:
else_val = expr(0, local_vars)
code.append(f"{pad}}} else {{")
code.append(f"{pad} {local_vars[0]} = {else_val};")
code.append(f"{pad}}}")
# 0-2 for döngüsü
for _ in range(random.randint(0, 2)):
bound = random.randint(3, 15)
inner = expr(0, local_vars)
code.append(f"{pad}for (int i = 0; i < {bound}; i = i + 1) {{")
code.append(f"{pad} {local_vars[0]} = {local_vars[0]} + {inner};")
code.append(f"{pad}}}")
# return
ret_val = expr(0, local_vars)
code.append(f"{pad}return {ret_val};")
return code
# ── Fonksiyon tanımları ───────────────────────────────────────────────────────
# Toplam ~5000 fonksiyon → ~1 MB hedef
FUNC_COUNT = 5000
func_names = [f"fn_{i:04d}" for i in range(FUNC_COUNT)]
func_params = {} # fname → n_params (çağrı sırasında eşleştirmek için)
for i, fname in enumerate(func_names):
# Parametre listesi (0-3 parametre)
n_params = random.randint(0, 3)
func_params[fname] = n_params
params = [f"int p{j}" for j in range(n_params)]
param_str = ", ".join(params)
# Lokal değişken adları
local_vars = ["a", "b", "c", "d", "e",
f"v{i % 10}", f"w{i % 7}"]
emit(f"int {fname}({param_str}) {{")
for line in gen_body(i, local_vars):
emit(line)
emit("}")
emit()
# ── Main ──────────────────────────────────────────────────────────────────────
emit("int main() {")
emit(" int result = 0;")
emit()
# Her 50 fonksiyonu bir kere çağır — argüman sayısı imzayla eşleştirildi
for i in range(0, FUNC_COUNT, 50):
fname = func_names[i]
n_params = func_params[fname]
args = ", ".join(str(random.randint(1, 20)) for _ in range(n_params))
emit(f" result = result + {fname}({args});")
emit()
emit(" print(result);")
emit(" return 0;")
emit("}")
# ── Yaz ───────────────────────────────────────────────────────────────────────
output = "\n".join(lines) + "\n"
path = sys.argv[1] if len(sys.argv) > 1 else "examples/large.sqt"
with open(path, "w", encoding="utf-8") as f:
f.write(output)
size_kb = len(output.encode("utf-8")) / 1024
print(f"Üretildi: {path} ({size_kb:.1f} KB, {len(lines)} satır)")

View File

@ -32,8 +32,6 @@ struct CliArgs {
std::string format;
bool showHelp = false;
bool stdinMode = false;
bool compact = false; // --compact: boşluksuz JSON
bool optimized = false; // --optimized: sabit katlama + ölü kod eleme
};
// ============================================================================
@ -69,14 +67,6 @@ inline CliArgs parseArgs(int argc, char* argv[]) {
if (i + 1 < argc) args.format = argv[++i];
continue;
}
if (arg == "--compact") {
args.compact = true;
continue;
}
if (arg == "--optimized") {
args.optimized = true;
continue;
}
if (arg.compare(0, 5, "file:") == 0) {
args.positional.push_back(arg.substr(5));
continue;
@ -93,9 +83,8 @@ inline CliArgs parseArgs(int argc, char* argv[]) {
// İlk argüman komut mu?
if (args.command.empty() && i == 1) {
if (arg == "run" || arg == "tokens" || arg == "ast" ||
arg == "symbols" || arg == "check" || arg == "ir" ||
arg == "compile" || arg == "parse" || arg == "transpile" ||
arg == "interpret") {
arg == "symbols" || arg == "compile" || arg == "parse" ||
arg == "transpile" || arg == "interpret") {
args.command = arg;
continue;
}
@ -136,12 +125,4 @@ inline std::string readSource(const CliArgs& args) {
return buffer.str();
}
// ============================================================================
// inputFilePath: Kaynak dosyanın yolunu döndür (stdin modunda boş string)
// ============================================================================
inline std::string inputFilePath(const CliArgs& args) {
if (args.stdinMode || args.positional.empty()) return "";
return args.positional[0];
}
#endif // SAQUT_CLI_ARGS

View File

@ -1,8 +1,5 @@
// ============================================================================
// saQut CLI — ast komutu (JSON formatında AST hiyerarşisi + analiz)
//
// --optimized: sabit katlama + ölü kod eleme uygulandıktan sonra AST göster.
// Orijinal AST dokunulmaz; optimize edilmiş klon gösterilir.
// ============================================================================
#ifndef SAQUT_CLI_AST
@ -13,13 +10,6 @@
#include "cli/args.hpp"
#include "tokenizer/tokenizer.hpp"
#include "parser/parser.hpp"
#include "symbol/symbol_table.hpp"
#include "symbol/symbol_collector.hpp"
#include "semantic/type_checker.hpp"
#include "semantic/structural_validator.hpp"
#include "diagnostic/diagnostic_engine.hpp"
#include "core/config.hpp"
#include "opt/optimization_manager.hpp"
#include "json.hpp"
inline int cmdAst(const CliArgs& args) {
@ -27,7 +17,7 @@ inline int cmdAst(const CliArgs& args) {
if (source.empty()) return 1;
Tokenizer tokenizer;
auto tokens = tokenizer.scan(source, inputFilePath(args));
auto tokens = tokenizer.scan(source);
Parser parser;
ASTNode* ast = parser.parse(tokens);
@ -38,25 +28,9 @@ inline int cmdAst(const CliArgs& args) {
return 1;
}
// ── Sembol + tip analizi (--optimized için gerekli; yalın ast'te opsiyonel) ──
SymbolTable symbolTable;
DiagnosticEngine diag;
SymbolCollector(symbolTable, diag).collect(ast);
TypeChecker(symbolTable, diag).check(ast);
StructuralValidator(diag).validate(ast);
ASTNode* displayAst = ast; // gösterilecek ağaç (orijinal veya klon)
ASTNode* clonedAst = nullptr;
if (args.optimized) {
CompilerConfig cfg;
OptimizationManager mgr(cfg, diag);
clonedAst = mgr.optimize(ast, &symbolTable);
displayAst = clonedAst;
}
AstAnalysis analysis = analyzeAst(displayAst);
AstAnalysis analysis = analyzeAst(ast);
// Çıktı hedefi
std::ostream* out = &std::cout;
std::ofstream outFile;
if (!args.outputFile.empty()) {
@ -66,16 +40,12 @@ inline int cmdAst(const CliArgs& args) {
*out << "{\n"
<< " \"ast\":\n"
<< jsonIndent(2) << astToJson(displayAst, 2) << ",\n"
<< astToJson(ast, 2) << ",\n\n"
<< " \"analysis\": {\n"
<< analysisToJson(analysis) << "\n"
<< " }\n"
<< "}\n";
// Optimizasyon uyarılarını (W002 vb.) stderr'e yazdır
if (args.optimized) diag.printAll(std::cerr);
if (clonedAst) delete clonedAst;
delete ast;
for (auto* t : tokens) delete t;
return 0;

View File

@ -1,59 +0,0 @@
#ifndef SAQUT_CLI_CHECK
#define SAQUT_CLI_CHECK
#include <iostream>
#include "cli/args.hpp"
#include "tokenizer/tokenizer.hpp"
#include "parser/parser.hpp"
#include "symbol/symbol_table.hpp"
#include "symbol/symbol_collector.hpp"
#include "semantic/type_checker.hpp"
#include "semantic/structural_validator.hpp"
#include "diagnostic/diagnostic_engine.hpp"
#include "vendor/nlohmann/json.hpp"
inline int cmdCheck(const CliArgs& args) {
std::string filePath = inputFilePath(args);
std::string source = readSource(args);
if (source.empty()) return 1;
Tokenizer tokenizer;
auto tokens = tokenizer.scan(source, filePath);
Parser parser;
ASTNode* ast = parser.parse(tokens);
DiagnosticEngine diag;
if (!ast) {
diag.report("E000", SourceLocation{}, "AST üretilemedi");
nlohmann::json out;
out["file"] = filePath;
out["diagnostics"] = diag.toJsonObj();
std::cout << (args.compact ? out.dump() : out.dump(2)) << "\n";
for (auto* t : tokens) delete t;
return 1;
}
SymbolTable table;
SymbolCollector(table, diag).collect(ast);
// Sembol toplama hataları varsa tip denetimine geçme
// (çözümsüz semboller tip denetiminde sahte E003 üretir)
if (!diag.hasErrors()) {
TypeChecker(table, diag).check(ast);
StructuralValidator(diag).validate(ast);
}
nlohmann::json out;
out["file"] = filePath;
out["diagnostics"] = diag.toJsonObj();
std::cout << (args.compact ? out.dump() : out.dump(2)) << "\n";
delete ast;
for (auto* t : tokens) delete t;
return diag.hasErrors() ? 1 : 0;
}
#endif // SAQUT_CLI_CHECK

View File

@ -1,65 +0,0 @@
#ifndef SAQUT_CLI_IR
#define SAQUT_CLI_IR
#include <iostream>
#include "cli/args.hpp"
#include "tokenizer/tokenizer.hpp"
#include "parser/parser.hpp"
#include "symbol/symbol_table.hpp"
#include "symbol/symbol_collector.hpp"
#include "semantic/type_checker.hpp"
#include "semantic/structural_validator.hpp"
#include "diagnostic/diagnostic_engine.hpp"
#include "ir/ir_generator.hpp"
#include "core/config.hpp"
#include "opt/optimization_manager.hpp"
inline int cmdIr(const CliArgs& args) {
std::string filePath = inputFilePath(args);
std::string source = readSource(args);
if (source.empty()) return 1;
Tokenizer tokenizer;
auto tokens = tokenizer.scan(source, filePath);
Parser parser;
ASTNode* ast = parser.parse(tokens);
if (!ast) {
std::cerr << "Hata: AST üretilemedi\n";
for (auto* t : tokens) delete t;
return 1;
}
SymbolTable symbolTable;
DiagnosticEngine diag;
SymbolCollector(symbolTable, diag).collect(ast);
TypeChecker(symbolTable, diag).check(ast);
StructuralValidator(diag).validate(ast);
if (diag.hasErrors()) {
diag.printAll(std::cerr);
delete ast;
for (auto* t : tokens) delete t;
return 1;
}
// --optimized: constant folding + DCE yerinde uygulanır, klon yok.
// IR dump için tek versiyon yeterli — ast komutu gibi karşılaştırma yok.
if (args.optimized) {
CompilerConfig cfg;
DiagnosticEngine optDiag;
OptimizationManager(cfg, optDiag).runPassesInPlace(ast, &symbolTable);
if (optDiag.errorCount() + optDiag.warningCount() > 0)
optDiag.printAll(std::cerr); // W002 vb. uyarılar stderr'e
}
IRGenerator irGenerator;
IRProgram program = irGenerator.generate(ast, symbolTable);
program.dump();
delete ast;
for (auto* t : tokens) delete t;
return 0;
}
#endif // SAQUT_CLI_IR

View File

@ -1,12 +1,10 @@
// ============================================================================
// saQut CLI — run komutu
// saQut CLI — run komutu (pipeline: token → AST → IR debug)
// ============================================================================
//
// Tam derleme + çalıştırma pipeline'ı:
// tokenize → parse → sembol topla → [opsiyonel: optimize] → IR üret → VM çalıştır
// TODO: İleride `saqut -` ile stdin'den okuyup anında çalıştıracak
// interpreter modu bu komutun altına gelecek.
//
// --optimized bayrağı: AST yerinde optimize edilir (klon yok — sadece tek versiyon
// gerekiyor). ast komutu orijinali saklaması gerektiği için klon kullanır; run/ir
// kullanmaz. Aynı pattern ir.hpp'de de var — paralel değişikliklerde ikisine bak.
// ============================================================================
#ifndef SAQUT_CLI_RUN
@ -16,78 +14,53 @@
#include "cli/args.hpp"
#include "tokenizer/tokenizer.hpp"
#include "parser/parser.hpp"
#include "symbol/symbol_table.hpp"
#include "symbol/symbol_collector.hpp"
#include "semantic/type_checker.hpp"
#include "semantic/structural_validator.hpp"
#include "diagnostic/diagnostic_engine.hpp"
#include "core/config.hpp"
#include "opt/optimization_manager.hpp"
#include "ir/ir_generator.hpp"
#include "vm/interpreter.hpp"
#include "ir/ir.hpp"
inline int cmdRun(const CliArgs& args) {
std::string filePath = inputFilePath(args);
std::string source = readSource(args);
if (source.empty()) return 1;
// ── Aşama 1: Tokenize ────────────────────────────────────────────────
Tokenizer tokenizer;
auto tokens = tokenizer.scan(source, filePath);
auto tokens = tokenizer.scan(source);
std::cout << "=== saQut Compiler ===\n";
std::cout << "Kaynak kod:\n" << source << "\n\n";
std::cout << "Tokenler (" << tokens.size() << " adet):\n";
for (auto* t : tokens) {
std::cout << " [" << t->gettype() << "] \"" << t->token << "\"\n";
}
std::cout << "\n";
// ── Aşama 2: Parse ───────────────────────────────────────────────────
Parser parser;
ASTNode* ast = parser.parse(tokens);
if (!ast) {
std::cerr << "Hata: AST üretilemedi\n";
for (auto* t : tokens) delete t;
return 1;
if (ast) {
std::cout << "AST:\n";
ast->log(0);
std::cout << "\n";
CodeGenerator cg;
cg.parse(ast);
std::cout << "IR (" << cg.IROpDatas.size() << " komut):\n";
for (size_t i = 0; i < cg.IROpDatas.size(); i++) {
auto& op = cg.IROpDatas[i];
std::cout << " [" << i << "] reg" << op.targetReg << " = ";
switch (op.op) {
case OPCode::mathadd: std::cout << "add"; break;
case OPCode::mathsub: std::cout << "sub"; break;
case OPCode::mathmul: std::cout << "mul"; break;
case OPCode::mathdiv: std::cout << "div"; break;
case OPCode::declare: std::cout << "literal"; break;
}
// ── Aşama 3: Sembol toplama + semantik analiz ─────────────────────────
// Identifier'ların resolvedSymbol'ü doldurulur — IR generator buna ihtiyaç duyar.
SymbolTable symbolTable;
DiagnosticEngine diag;
SymbolCollector(symbolTable, diag).collect(ast);
TypeChecker(symbolTable, diag).check(ast);
StructuralValidator(diag).validate(ast);
if (diag.hasErrors()) {
std::cerr << "Derleme hataları var, program çalıştırılamaz:\n";
diag.printAll(std::cerr);
delete ast;
for (auto* t : tokens) delete t;
return 1;
}
// ── Aşama 4 (opsiyonel): Optimizasyon ────────────────────────────────
// --optimized: constant folding + DCE yerinde uygulanır, klon yok.
// Tek versiyon (optimize edilmiş) yeterli — ast komutu gibi karşılaştırma yok.
if (args.optimized) {
CompilerConfig cfg;
DiagnosticEngine optDiag;
OptimizationManager(cfg, optDiag).runPassesInPlace(ast, &symbolTable);
if (optDiag.errorCount() + optDiag.warningCount() > 0)
optDiag.printAll(std::cerr); // W002 (derleme zamanı sıfıra bölme) vb.
}
// ── Aşama 5: IR üretimi ───────────────────────────────────────────────
IRGenerator irGenerator;
IRProgram program = irGenerator.generate(ast, symbolTable);
// ── Aşama 6: VM çalıştırma ────────────────────────────────────────────
int exitCode = 0;
try {
Interpreter vm(program);
exitCode = vm.run();
} catch (const std::exception& e) {
std::cerr << "Çalışma zamanı hatası: " << e.what() << "\n";
exitCode = 1;
std::cout << " (" << op.arg1.value.index() << ")\n";
}
delete ast;
}
for (auto* t : tokens) delete t;
return exitCode;
return 0;
}
#endif // SAQUT_CLI_RUN

View File

@ -1,5 +1,5 @@
// ============================================================================
// saQut CLI — symbols komutu (sembol tablosu — JSON çıktı, Faz 2)
// saQut CLI — symbols komutu (sembol tablosu)
// ============================================================================
#ifndef SAQUT_CLI_SYMBOLS
@ -9,62 +9,50 @@
#include "cli/args.hpp"
#include "tokenizer/tokenizer.hpp"
#include "parser/parser.hpp"
#include "symbol/symbol_table.hpp"
#include "symbol/symbol_collector.hpp"
#include "diagnostic/diagnostic_engine.hpp"
#include "vendor/nlohmann/json.hpp"
#include "json.hpp"
inline int cmdSymbols(const CliArgs& args) {
std::string filePath = inputFilePath(args);
std::string source = readSource(args);
if (source.empty()) return 1;
Tokenizer tokenizer;
auto tokens = tokenizer.scan(source, filePath);
auto tokens = tokenizer.scan(source);
Parser parser;
ASTNode* ast = parser.parse(tokens);
SymbolTable table;
DiagnosticEngine diag;
if (ast) {
SymbolCollector(table, diag).collect(ast);
} else {
diag.report("E000", SourceLocation{}, "AST üretilemedi");
if (!ast) {
std::cerr << "Hata: AST üretilemedi\n";
for (auto* t : tokens) delete t;
return 1;
}
// ── JSON çıktı ──────────────────────────────────────────────────────────
nlohmann::json out;
out["file"] = filePath;
auto symbols = collectSymbols(ast);
nlohmann::json symArray = nlohmann::json::array();
for (Symbol* s : table.allSymbols()) {
if (s->isBuiltin) continue;
std::cout << "Sembol Tablosu (" << symbols.size() << " sembol):\n";
std::cout << "────────────────────────────────────────────\n";
nlohmann::json refs = nlohmann::json::array();
for (const SourceLocation& r : s->references)
refs.push_back(r.toJsonObj());
symArray.push_back({
{"name", s->name},
{"kind", symbolKindName(s->kind)},
{"type", s->type.toString()},
{"typeDetail", s->type.toJsonObj()},
{"definition", s->definitionLoc.toJsonObj()},
{"referenceCount", static_cast<int>(s->references.size())},
{"references", refs},
{"isBuiltin", s->isBuiltin}
});
if (symbols.empty()) {
std::cout << " (sembol bulunamadı)\n";
}
out["symbols"] = symArray;
out["diagnostics"] = diag.toJsonObj();
std::cout << (args.compact ? out.dump() : out.dump(2)) << "\n";
for (auto& s : symbols) {
std::cout << " [" << s.kind << "] " << s.type << " " << s.name << "\n";
}
std::cout << "────────────────────────────────────────────\n";
int fnCount = 0, varCount = 0;
for (auto& s : symbols) {
if (s.kind == "function") fnCount++;
else if (s.kind == "variable") varCount++;
}
std::cout << "Fonksiyon: " << fnCount
<< " | Değişken: " << varCount << "\n";
delete ast;
for (auto* t : tokens) delete t;
return diag.hasErrors() ? 1 : 0;
return 0;
}
#endif // SAQUT_CLI_SYMBOLS

View File

@ -14,7 +14,7 @@ inline int cmdTokens(const CliArgs& args) {
if (source.empty()) return 1;
Tokenizer tokenizer;
auto tokens = tokenizer.scan(source, inputFilePath(args));
auto tokens = tokenizer.scan(source);
std::cout << "Tokenler (" << tokens.size() << " adet):\n";
for (auto* t : tokens) {

View File

@ -1,11 +0,0 @@
#ifndef SAQUT_CORE_CONFIG
#define SAQUT_CORE_CONFIG
// Derleyici yapılandırması — hangi optimizasyon pass'lerinin çalışacağı.
struct CompilerConfig {
bool optConstantFolding = true;
bool optDeadCodeElim = true;
int maxFixpointRounds = 10;
};
#endif // SAQUT_CORE_CONFIG

View File

@ -22,7 +22,6 @@
#define SAQUT_CORE_LOCATION
#include <string>
#include "vendor/nlohmann/json.hpp"
// ============================================================================
// SourceLocation — Kaynak Koddaki Bir Nokta
@ -67,17 +66,15 @@ struct SourceLocation {
}
// JSON formatı: {"file":"...","line":5,"column":10,"offset":134}
nlohmann::json toJsonObj() const {
if (!isValid()) return nullptr;
return {
{"file", filePath},
{"line", line},
{"column", column},
{"offset", offset}
};
std::string toJson() const {
if (!isValid()) return "null";
return "{"
"\"file\":\"" + filePath + "\","
"\"line\":" + std::to_string(line) + ","
"\"column\":" + std::to_string(column) + ","
"\"offset\":" + std::to_string(offset) +
"}";
}
std::string toJson() const { return toJsonObj().dump(); }
};
#endif // SAQUT_CORE_LOCATION

View File

@ -1,285 +0,0 @@
// ============================================================================
// saQut Compiler — Tip Sistemi (Type System)
// ============================================================================
//
// DİZİN: src/core/type.hpp
// KATMAN: Katman 0 — Tüm analiz katmanları tarafından kullanılır
// BAĞIMLI: Yok (sadece <string>, <vector>, <memory>)
// KULLANAN: Sembol tablosu (Faz 2), tip denetleyici (Faz 3), optimizasyon (Faz 4)
//
// AMAÇ:
// Kaynak koddaki her ifadenin/sembolün veri tipini temsil eder. Derleyicinin
// "bu değer ne?" sorusuna verdiği yapısal cevaptır. Tip, makine-okur (toJson)
// ve insan-okur (toString) olarak dışa açıktır — "veri birincil, metin bir
// görünümdür" ilkesine uyar (bkz. readme → Tasarım felsefesi).
//
// TİP TÜRLERİ (TypeKind):
// Primitive : int, float, double, char, string, bool, void
// Array : eleman tipi taşır (örn. int[])
// Struct : struct adı taşır (örn. struct Point)
// Function : dönüş tipi + parametre tipleri taşır
// Error : hatalı/çözümlenememiş tip — ardışık sahte hataları bastırmak için
// (tip denetleyici, operandı Error olan ifadede yeni hata üretmez)
//
// NOT (kasıtlı sadelik): Gizli tip dönüşümü YOKTUR (ADR-010). equals() yapısal
// ve katıdır; "int, float'a uyar mı?" gibi kurallar tip denetleyicinin işidir,
// bu dosyanın değil. Tamsayı literalinin bağlama-göre tiplenmesi de (ADR-010)
// Faz 3'te ele alınır.
//
// ============================================================================
#ifndef SAQUT_CORE_TYPE
#define SAQUT_CORE_TYPE
#include <string>
#include <vector>
#include <memory>
#include "vendor/nlohmann/json.hpp"
// ============================================================================
// Enum'lar
// ============================================================================
enum class PrimitiveKind { Int, Float, Double, Char, String, Bool, Void };
enum class TypeKind { Primitive, Array, Struct, Function, Error };
// ============================================================================
// Type — Bir veri tipi
// ============================================================================
//
// KULLANIM:
// Type a = Type::Int(); // int
// Type b = Type::array(Type::Int()); // int[]
// Type c = Type::function(Type::Int(), {Type::Int(), Type::Int()}); // fn(int,int)->int
// Type d = Type::structType("Point"); // struct Point
// Type e = Type::error(); // <error>
//
// a.equals(Type::Int()); // true
// a.equals(b); // false
// a.toString(); // "int"
// b.toString(); // "int[]"
// c.toJson(); // {"kind":"function",...}
//
// İç içe tipler (array elemanı, fonksiyon dönüşü) shared_ptr ile tutulur:
// Type değer-semantiğiyle kopyalanabilir kalır ama özyinelemeli olabilir.
// ============================================================================
struct Type {
TypeKind kind = TypeKind::Error;
PrimitiveKind prim = PrimitiveKind::Void; // kind == Primitive
std::shared_ptr<Type> elementType; // kind == Array
std::shared_ptr<Type> returnType; // kind == Function
std::vector<Type> paramTypes; // kind == Function
std::string structName; // kind == Struct
bool nullable = false; // ADR-021: Type? sözdizimi
// ------------------------------------------------------------------ //
// Factory'ler
// ------------------------------------------------------------------ //
static Type primitive(PrimitiveKind p) {
Type t;
t.kind = TypeKind::Primitive;
t.prim = p;
return t;
}
static Type Int() { return primitive(PrimitiveKind::Int); }
static Type Float() { return primitive(PrimitiveKind::Float); }
static Type Double() { return primitive(PrimitiveKind::Double); }
static Type Char() { return primitive(PrimitiveKind::Char); }
static Type String() { return primitive(PrimitiveKind::String); }
static Type Bool() { return primitive(PrimitiveKind::Bool); }
static Type Void() { return primitive(PrimitiveKind::Void); }
static Type array(Type elem) {
Type t;
t.kind = TypeKind::Array;
t.elementType = std::make_shared<Type>(std::move(elem));
return t;
}
static Type function(Type ret, std::vector<Type> params) {
Type t;
t.kind = TypeKind::Function;
t.returnType = std::make_shared<Type>(std::move(ret));
t.paramTypes = std::move(params);
return t;
}
static Type structType(std::string name) {
Type t;
t.kind = TypeKind::Struct;
t.structName = std::move(name);
return t;
}
static Type error() {
return Type{}; // varsayılan = Error
}
// ------------------------------------------------------------------ //
// Yüklemler (predicates)
// ------------------------------------------------------------------ //
bool isError() const { return kind == TypeKind::Error; }
bool isPrimitive() const { return kind == TypeKind::Primitive; }
bool isArray() const { return kind == TypeKind::Array; }
bool isStruct() const { return kind == TypeKind::Struct; }
bool isFunction() const { return kind == TypeKind::Function; }
bool isVoid() const { return kind == TypeKind::Primitive && prim == PrimitiveKind::Void; }
// Aritmetik/karşılaştırma operatörlerine uygun sayısal tip mi?
bool isNumeric() const {
return kind == TypeKind::Primitive &&
(prim == PrimitiveKind::Int ||
prim == PrimitiveKind::Float ||
prim == PrimitiveKind::Double);
}
bool isString() const {
return kind == TypeKind::Primitive && prim == PrimitiveKind::String;
}
// ADR-021: "null" literal tipi — yalnızca nullable değişkene atanabilir
bool isNullLiteral() const {
return kind == TypeKind::Primitive && prim == PrimitiveKind::Void && nullable;
}
// Nullable kopyası döndür
Type asNullable() const { Type t = *this; t.nullable = true; return t; }
Type asNonNull() const { Type t = *this; t.nullable = false; return t; }
// ------------------------------------------------------------------ //
// equals — Yapısal eşitlik (katı; gizli dönüşüm yok, ADR-010)
// ------------------------------------------------------------------ //
// Yapısal eşitlik — nullable dahil (ADR-021: int ≠ int?)
bool equals(const Type& o) const {
if (kind != o.kind) return false;
if (nullable != o.nullable) return false;
switch (kind) {
case TypeKind::Primitive:
return prim == o.prim;
case TypeKind::Array:
return elementType && o.elementType &&
elementType->equals(*o.elementType);
case TypeKind::Struct:
return structName == o.structName;
case TypeKind::Function: {
if (!returnType || !o.returnType) return false;
if (!returnType->equals(*o.returnType)) return false;
if (paramTypes.size() != o.paramTypes.size()) return false;
for (size_t i = 0; i < paramTypes.size(); ++i)
if (!paramTypes[i].equals(o.paramTypes[i])) return false;
return true;
}
case TypeKind::Error:
return true;
}
return false;
}
// Temel yapısal eşitlik — nullable farkını yok say (T == T? üstün çakışma için)
bool equalsBase(const Type& o) const { return asNonNull().equals(o.asNonNull()); }
// ------------------------------------------------------------------ //
// İsim yardımcıları
// ------------------------------------------------------------------ //
static const char* primName(PrimitiveKind p) {
switch (p) {
case PrimitiveKind::Int: return "int";
case PrimitiveKind::Float: return "float";
case PrimitiveKind::Double: return "double";
case PrimitiveKind::Char: return "char";
case PrimitiveKind::String: return "string";
case PrimitiveKind::Bool: return "bool";
case PrimitiveKind::Void: return "void";
}
return "?";
}
// Bir tip adından (parser tipleri string olarak tutar) Type üretir.
// "int?" → nullable int; "int[]" → int array; bilinen değilse Error.
static Type fromName(const std::string& n) {
// Nullable soneki: "int?", "string?" vb. (ADR-021)
if (!n.empty() && n.back() == '?') {
Type base = fromName(n.substr(0, n.size() - 1));
if (!base.isError()) return base.asNullable();
return error();
}
if (n == "int") return Int();
if (n == "float") return Float();
if (n == "double") return Double();
if (n == "char") return Char();
if (n == "string") return String();
if (n == "bool") return Bool();
if (n == "void") return Void();
// "int[]", "float[]" vb. — suffix [] ile dizi tipi
if (n.size() > 2 && n.substr(n.size() - 2) == "[]") {
Type elem = fromName(n.substr(0, n.size() - 2));
if (!elem.isError()) return array(elem);
}
return error();
}
// ------------------------------------------------------------------ //
// toString — İnsan-okur ("int", "int[]", "fn(int,int)->int")
// ------------------------------------------------------------------ //
std::string toString() const {
std::string base;
switch (kind) {
case TypeKind::Primitive:
base = primName(prim); break;
case TypeKind::Array:
base = (elementType ? elementType->toString() : "<?>") + "[]"; break;
case TypeKind::Struct:
base = "struct " + structName; break;
case TypeKind::Function: {
base = "fn(";
for (size_t i = 0; i < paramTypes.size(); ++i) {
if (i) base += ",";
base += paramTypes[i].toString();
}
base += ")->";
base += returnType ? returnType->toString() : "<?>";
break;
}
case TypeKind::Error:
return "<error>";
}
return nullable ? base + "?" : base;
}
// ------------------------------------------------------------------ //
// toJson — Makine-okur (cam ilkesi: her tip dışarıdan sorgulanabilir)
// ------------------------------------------------------------------ //
nlohmann::json toJsonObj() const {
nlohmann::json j;
switch (kind) {
case TypeKind::Primitive:
j["kind"] = "primitive";
j["name"] = primName(prim);
break;
case TypeKind::Array:
j["kind"] = "array";
j["element"] = elementType ? elementType->toJsonObj() : nullptr;
break;
case TypeKind::Struct:
j["kind"] = "struct";
j["name"] = structName;
break;
case TypeKind::Function: {
j["kind"] = "function";
j["returns"] = returnType ? returnType->toJsonObj() : nullptr;
nlohmann::json params = nlohmann::json::array();
for (const auto& p : paramTypes) params.push_back(p.toJsonObj());
j["params"] = params;
break;
}
case TypeKind::Error:
j["kind"] = "error";
break;
}
return j;
}
std::string toJson() const { return toJsonObj().dump(); }
};
#endif // SAQUT_CORE_TYPE

View File

@ -1,164 +0,0 @@
// ============================================================================
// saQut Compiler — Tanılama (Diagnostic) Veri Yapıları + Hata Kataloğu
// ============================================================================
//
// DİZİN: src/diagnostic/diagnostic.hpp
// KATMAN: Katman 0 — Tüm analiz katmanları tarafından kullanılır
// BAĞIMLI: src/core/location.hpp
// KULLANAN: DiagnosticEngine, sembol toplayıcı (Faz 2), tip denetleyici (Faz 3)
//
// AMAÇ:
// Derleme sırasında bulunan hata/uyarıları YAPISAL veri olarak temsil eder.
// "Veri birincil, insan-okur metin bir görünümdür" (readme → Tasarım felsefesi):
// bir Diagnostic; seviye + kod + konum + mesaj taşır; ekrana basılan satır
// bunun yalnızca bir render'ıdır. Bu sayede aynı tanı LSP, AI veya `saqut
// explain` tarafından da tüketilebilir.
//
// HATA KATALOĞU (baştan sabitlenir — yeni kodlar buraya eklenir):
// E001 Tanımsız değişken/isim (declare-before-use ihlali dâhil) Faz 2/3
// E002 Aynı scope'ta çift tanım Faz 2
// E003 Tip uyuşmazlığı (gizli dönüşüm yok, ADR-010) Faz 3
// E004 Döngü/switch dışı break/continue Faz 3
// E005 Fonksiyon dışı return Faz 3
// E006 Return tipi imzaya uymuyor Faz 3
// E007 Tanımsız tip (bilinmeyen tip adı) Faz 2/3
// E008 Fonksiyon çağrısı argüman sayısı/tipi uyuşmuyor Faz 3
// E009 Array boyutu sabit değil / geçersiz Faz 3
// E010 Özyinelemeli/döngüsel struct (by-value çevrim → sonsuz boyut) Faz 2/3
// W001 Kullanılmayan değişken Faz 4
// W002 Sıfıra bölme (sabit folding) Faz 4
// W003 Erişilemez (ölü) kod Faz 4
//
// ============================================================================
#ifndef SAQUT_DIAGNOSTIC_DIAGNOSTIC
#define SAQUT_DIAGNOSTIC_DIAGNOSTIC
#include <string>
#include <vector>
#include "core/location.hpp"
#include "tools.hpp" // jsonEscape — TEK tanım (tools.hpp); çakışmayı önler
// ============================================================================
// DiagLevel — Tanı seviyesi
// ============================================================================
enum class DiagLevel { Error, Warning, Note, Hint };
inline const char* diagLevelName(DiagLevel l) {
switch (l) {
case DiagLevel::Error: return "error";
case DiagLevel::Warning: return "warning";
case DiagLevel::Note: return "note";
case DiagLevel::Hint: return "hint";
}
return "?";
}
// İnsan-okur çıktı için Türkçe karşılık
inline const char* diagLevelNameTr(DiagLevel l) {
switch (l) {
case DiagLevel::Error: return "hata";
case DiagLevel::Warning: return "uyarı";
case DiagLevel::Note: return "not";
case DiagLevel::Hint: return "ipucu";
}
return "?";
}
// NOT: jsonEscape() tools.hpp'de tanımlıdır (tek tanım — ODR çakışması olmaz).
// ============================================================================
// Diagnostic — Tek bir tanı (hata/uyarı/not/ipucu)
// ============================================================================
//
// KULLANIM:
// Diagnostic d{DiagLevel::Error, "E003", loc, "int'e string atanamaz"};
// d.hint = "açık dönüşüm gerekiyor";
// std::cout << d.toJson();
// ============================================================================
struct Diagnostic {
DiagLevel level = DiagLevel::Error;
std::string code; // "E003" (katalog kodu; boş olabilir)
SourceLocation loc; // hatanın kaynak koddaki yeri
std::string message; // bağlama özel açıklama
std::string hint; // opsiyonel "şunu dene" önerisi
nlohmann::json toJsonObj() const {
nlohmann::json j;
j["level"] = diagLevelName(level);
j["code"] = code;
j["location"] = loc.toJsonObj();
j["message"] = message;
if (!hint.empty()) j["hint"] = hint;
return j;
}
std::string toJson() const { return toJsonObj().dump(); }
};
// ============================================================================
// Hata Kataloğu — kod → (seviye, kanonik başlık)
// ============================================================================
//
// Bağlama özel mesaj report sırasında verilir; buradaki başlık, kodun GENEL
// anlamıdır (ileride `saqut explain E003` bunu kullanabilir, #107/#98).
// ============================================================================
struct DiagInfo {
const char* code;
DiagLevel level;
const char* title;
};
inline const std::vector<DiagInfo>& diagnosticCatalog() {
static const std::vector<DiagInfo> catalog = {
{"E001", DiagLevel::Error, "Tanımsız değişken/isim"},
{"E002", DiagLevel::Error, "Aynı scope'ta çift tanım"},
{"E003", DiagLevel::Error, "Tip uyuşmazlığı"},
{"E004", DiagLevel::Error, "Döngü/switch dışı break/continue"},
{"E005", DiagLevel::Error, "Fonksiyon dışı return"},
{"E006", DiagLevel::Error, "Return tipi imzaya uymuyor"},
{"E007", DiagLevel::Error, "Tanımsız tip"},
{"E008", DiagLevel::Error, "Fonksiyon çağrısı argümanı uyuşmuyor"},
{"E009", DiagLevel::Error, "Array boyutu sabit değil / geçersiz"},
{"E010", DiagLevel::Error, "Özyinelemeli/döngüsel struct tanımı"},
{"W001", DiagLevel::Warning, "Kullanılmayan değişken"},
{"W002", DiagLevel::Warning, "Sıfıra bölme (sabit ifade)"},
{"W003", DiagLevel::Warning, "Erişilemez (ölü) kod"},
{"W004", DiagLevel::Warning, "Örtük sayısal genişletme (widening)"},
};
return catalog;
}
// Kod kataloğda var mı? (yoksa nullptr)
inline const DiagInfo* findDiag(const std::string& code) {
for (const auto& d : diagnosticCatalog())
if (code == d.code) return &d;
return nullptr;
}
// Bir koddan Diagnostic üretir; seviye kataloğdan çözülür (yoksa: E→Error,
// W→Warning, diğer→Note). Bağlama özel mesajı çağıran verir.
inline Diagnostic makeDiagnostic(const std::string& code,
const SourceLocation& loc,
const std::string& message,
const std::string& hint = "") {
DiagLevel level = DiagLevel::Note;
if (const DiagInfo* info = findDiag(code)) {
level = info->level;
} else if (!code.empty()) {
if (code[0] == 'E') level = DiagLevel::Error;
else if (code[0] == 'W') level = DiagLevel::Warning;
}
Diagnostic d;
d.level = level;
d.code = code;
d.loc = loc;
d.message = message;
d.hint = hint;
return d;
}
#endif // SAQUT_DIAGNOSTIC_DIAGNOSTIC

View File

@ -1,116 +0,0 @@
// ============================================================================
// saQut Compiler — Tanılama Motoru (DiagnosticEngine)
// ============================================================================
//
// DİZİN: src/diagnostic/diagnostic_engine.hpp
// KATMAN: Katman 0 — Tüm analiz katmanları tarafından kullanılır
// BAĞIMLI: src/diagnostic/diagnostic.hpp
// KULLANAN: sembol toplayıcı (Faz 2), tip denetleyici (Faz 3), pipeline (main)
//
// AMAÇ:
// Derleme boyunca üretilen tüm Diagnostic'leri EKLENME SIRASIYLA biriktirir.
// İlk hatada DURMAZ (ADR-013): bütün hatalar toplanır, faz sonunda topluca
// raporlanır; durdurma kararını pipeline verir (hasErrors()).
//
// İki çıktı yüzü vardır — aynı veriden:
// printAll() → insan-okur (terminal)
// toJson() → makine-okur (LSP / AI / araçlar)
//
// ============================================================================
#ifndef SAQUT_DIAGNOSTIC_ENGINE
#define SAQUT_DIAGNOSTIC_ENGINE
#include <string>
#include <vector>
#include <ostream>
#include "diagnostic/diagnostic.hpp"
#include "vendor/nlohmann/json.hpp"
// ============================================================================
// DiagnosticEngine
// ============================================================================
//
// KULLANIM:
// DiagnosticEngine diag;
// diag.report(makeDiagnostic("E001", loc, "x tanımsız"));
// diag.report(DiagLevel::Warning, "W001", loc2, "y kullanılmıyor");
// if (diag.hasErrors()) diag.printAll(std::cerr);
// ============================================================================
class DiagnosticEngine {
public:
// --- Ekleme ---
void report(const Diagnostic& d) {
diagnostics_.push_back(d);
}
// Kolaylık: koddan üret + ekle (seviye kataloğdan çözülür)
void report(const std::string& code,
const SourceLocation& loc,
const std::string& message,
const std::string& hint = "") {
diagnostics_.push_back(makeDiagnostic(code, loc, message, hint));
}
// Kolaylık: seviyeyi açıkça vererek
void report(DiagLevel level,
const std::string& code,
const SourceLocation& loc,
const std::string& message,
const std::string& hint = "") {
Diagnostic d;
d.level = level; d.code = code; d.loc = loc; d.message = message; d.hint = hint;
diagnostics_.push_back(d);
}
// --- Sorgu ---
bool hasErrors() const { return errorCount() > 0; }
int errorCount() const { return countLevel(DiagLevel::Error); }
int warningCount() const { return countLevel(DiagLevel::Warning); }
int count() const { return static_cast<int>(diagnostics_.size()); }
bool empty() const { return diagnostics_.empty(); }
const std::vector<Diagnostic>& all() const { return diagnostics_; }
void clear() { diagnostics_.clear(); }
// --- İnsan-okur çıktı (ekleme sırasıyla) ---
void printAll(std::ostream& os) const {
for (const auto& d : diagnostics_) {
os << d.loc.toString() << ": "
<< diagLevelNameTr(d.level) << " [" << d.code << "]: "
<< d.message << "\n";
if (!d.hint.empty())
os << " ipucu: " << d.hint << "\n";
}
os << "" << errorCount() << " hata, " << warningCount() << " uyarı\n";
}
// --- Makine-okur çıktı ---
nlohmann::json toJsonObj() const {
nlohmann::json items = nlohmann::json::array();
for (const auto& d : diagnostics_)
items.push_back(d.toJsonObj());
return {
{"diagnostics", items},
{"errorCount", errorCount()},
{"warningCount", warningCount()}
};
}
std::string toJson() const { return toJsonObj().dump(); }
private:
std::vector<Diagnostic> diagnostics_;
int countLevel(DiagLevel level) const {
int n = 0;
for (const auto& d : diagnostics_)
if (d.level == level) ++n;
return n;
}
};
#endif // SAQUT_DIAGNOSTIC_ENGINE

View File

@ -1,232 +0,0 @@
// ============================================================================
// saQut IR — Instruction (Tek Talimat)
//
// Sanal makine bu talimatlara bakarak ne yapacağını anlar.
// Her talimatın bir "opcode"u (ne iş yapacağı) ve birkaç operandı vardır.
// Operandlar ya slot numarasıdır (fonksiyonun yerel değişken/geçici depoları)
// ya da doğrudan bir sayı/isim değeridir.
//
// SLOT NEDİR?
// Her fonksiyon çağrısı kendi "frame"ini açar.
// Frame içinde numaralı kutucuklar vardır: slot[0], slot[1], ...
// Parametreler slot 0'dan başlar. Sonrasında lokal değişkenler
// ve hesaplama sırasında oluşan geçici değerler gelir.
// "slots[5] = 42" demek "5 numaralı kutucuğa 42 değerini koy" demektir.
//
// HANGİ OPCODE HANGİ ALANI KULLANIR?
// LOAD_CONST : dest, intValue
// LOAD_SLOT : dest, src
// ADD/SUB/... : dest, left, right
// LESS/LEQ/... : dest, left, right (sonuç: 1=doğru, 0=yanlış)
// JMP : jumpTarget
// JIF_FALSE : cond, jumpTarget
// JIF_TRUE : cond, jumpTarget
// CALL : dest, functionName, argSlots
// RETURN : src
// CALLHOST : functionName, argSlots
// ============================================================================
#ifndef SAQUT_IR_INSTRUCTION
#define SAQUT_IR_INSTRUCTION
#include <string>
#include <vector>
// ----------------------------------------------------------------------------
// Opcode — Sanal Makinenin Anlayacağı İşlem Kodları
// ----------------------------------------------------------------------------
enum class Opcode {
// --- Değer yükleme ---
LOAD_CONST, // slots[dest] = intValue (tam sayı sabitini slota yükle)
// Örnek: LOAD_CONST dest=3 val=10 → slot[3] = 10
LOAD_STRING, // slots[dest] = stringValue (metin sabitini slota yükle)
LOAD_NULL, // slots[dest] = null (ADR-021: ValueKind::Null)
// Örnek: LOAD_STRING dest=2 val="Merhaba" → slot[2] = "Merhaba"
LOAD_SLOT, // slots[dest] = slots[src]
// Bir slotun değerini başka bir slota kopyalar.
// Atama işlemlerinde (x = y) kullanılır.
// --- Aritmetik (tümü: slots[dest] = slots[left] OP slots[right]) ---
ADD,
SUB,
MUL,
DIV, // UYARI: sıfıra bölme → runtime_error fırlatılır
MOD,
// --- Bitsel (tümü: slots[dest] = slots[left] OP slots[right]) ---
BAND, // slots[left] & slots[right]
BOR, // slots[left] | slots[right]
SHL, // slots[left] << slots[right]
SHR, // slots[left] >> slots[right]
BNOT, // ~slots[src] → slots[dest] (tekli operatör; src kullanır, left/right değil)
// --- Karşılaştırma (sonuç: 1 = doğru, 0 = yanlış) ---
LESS, // slots[left] < slots[right]
LESS_EQUAL, // slots[left] <= slots[right]
GREATER, // slots[left] > slots[right]
GREATER_EQUAL, // slots[left] >= slots[right]
EQUAL_EQUAL, // slots[left] == slots[right]
NOT_EQUAL, // slots[left] != slots[right]
// --- Kontrol akışı ---
JMP, // Koşulsuz atlama: ip = jumpTarget
JIF_FALSE, // Koşullu atlama: slots[cond] falsy ise ip = jumpTarget
JIF_TRUE, // Koşullu atlama: slots[cond] truthy ise ip = jumpTarget
// --- Fonksiyon çağrısı ---
CALL, // Başka bir saQut fonksiyonunu çağır.
// Yeni frame açılır, argümanlar parametre slotlarına kopyalanır.
// Fonksiyon RETURN ile bitince sonuç slots[dest]'e yazılır.
RETURN, // Bu frame'i kapat, slots[src]'yi caller'a ilet.
// --- Float aritmetik (#44) ---
LOAD_FLOAT, // slots[dest] = floatValue (double sabit yükle)
FADD, // slots[dest] = slots[left] + slots[right] (float)
FSUB, // slots[dest] = slots[left] - slots[right] (float)
FMUL, // slots[dest] = slots[left] * slots[right] (float)
FDIV, // slots[dest] = slots[left] / slots[right] (float; sıfır → runtime_error)
FNEG, // slots[dest] = -slots[src] (float tekli eksi)
INT_TO_FLOAT, // slots[dest] = (double)slots[src] — gizli int→float çevrimi (literal atamasında)
FLOAT_TO_INT, // slots[dest] = (int)slots[src] — açık cast (ileride: int(x))
// --- Struct (ADR-020: referans semantiği) ---
STRUCT_NEW, // slots[dest] = yeni StructObject(intValue alan sayısı); functionName = struct tipi adı
FIELD_GET, // slots[dest] = slots[src].fields[intValue] (src=nesne, intValue=alan indeksi)
FIELD_SET, // slots[dest].fields[intValue] = slots[right] (dest=nesne, intValue=alan indeksi, right=değer)
// --- Array (ADR-020: referans semantiği) ---
ARRAY_NEW, // slots[dest] = yeni ArrayObject(intValue eleman kapasitesi)
ARRAY_GET, // slots[dest] = slots[left][slots[right]] — sınır kontrolü
ARRAY_SET, // slots[dest][slots[left]] = slots[right] — sınır kontrolü (dest=dizi, left=idx, right=değer)
ARRAY_LEN, // slots[dest] = slots[src].uzunluk()
// --- Modül-düzeyi değişken erişimi ---
// "Global" değil: her değişken kendi dosyasına (modülüne) aittir.
// Başka modüller bu alana doğrudan erişemez; yalnızca export/import ile ulaşabilir.
// TODO(#modül-scope): IRFunction.moduleId eklenerek çok-modüllü derlemede
// her fonksiyonun kendi modülünün slot alanına bakması sağlanacak (bkz. TODO.md).
LOAD_GLOBAL, // slots[dest] = moduleSlots[intValue] (bu modülün modül-düzeyi değişkeni)
STORE_GLOBAL, // moduleSlots[intValue] = slots[src]
// --- String işlemleri (ADR-024: immutable değer-tipi, içerik ==) ---
STRING_CONCAT, // slots[dest] = slots[left] + slots[right] (yeni string üretir)
// --- Hata yönetimi (ADR-025: UNCHECKED try/catch/throw) ---
ENTER_TRY, // try bloğuna giriş: TryFrame'i yığına it
// dest = catch bloğundaki Error değerinin yazılacağı slot
// jumpTarget = catch bloğunun IR konumu (-1 → backpatch)
// callDepth = VM, callStack.size()'ı kayıt altına alır (unwind için)
LEAVE_TRY, // try bloğundan normal çıkış: TryFrame'i çıkar (istisna olmadı)
THROW, // slots[src] değerini fırlat → en yakın ENTER_TRY'a unwind
// Yakalanmamışsa C++ exception olarak yükseltilir
// --- Dış dünya (FFI — Foreign Function Interface) ---
CALLHOST, // Host (C++) fonksiyonunu çağır. Şu an sadece "print" destekli.
// Dönüş değeri yok; sadece yan etki (stdout'a yazmak gibi).
};
// Hata ayıklama ve IR dump için okunabilir isim
inline const char* opcodeName(Opcode op) {
switch (op) {
case Opcode::LOAD_CONST: return "LOAD_CONST";
case Opcode::LOAD_STRING: return "LOAD_STRING";
case Opcode::LOAD_NULL: return "LOAD_NULL";
case Opcode::LOAD_SLOT: return "LOAD_SLOT";
case Opcode::ADD: return "ADD";
case Opcode::SUB: return "SUB";
case Opcode::MUL: return "MUL";
case Opcode::DIV: return "DIV";
case Opcode::MOD: return "MOD";
case Opcode::BAND: return "BAND";
case Opcode::BOR: return "BOR";
case Opcode::SHL: return "SHL";
case Opcode::SHR: return "SHR";
case Opcode::BNOT: return "BNOT";
case Opcode::LOAD_FLOAT: return "LOAD_FLOAT";
case Opcode::FADD: return "FADD";
case Opcode::FSUB: return "FSUB";
case Opcode::FMUL: return "FMUL";
case Opcode::FDIV: return "FDIV";
case Opcode::FNEG: return "FNEG";
case Opcode::INT_TO_FLOAT: return "INT_TO_FLOAT";
case Opcode::FLOAT_TO_INT: return "FLOAT_TO_INT";
case Opcode::STRUCT_NEW: return "STRUCT_NEW";
case Opcode::FIELD_GET: return "FIELD_GET";
case Opcode::FIELD_SET: return "FIELD_SET";
case Opcode::ARRAY_NEW: return "ARRAY_NEW";
case Opcode::ARRAY_GET: return "ARRAY_GET";
case Opcode::ARRAY_SET: return "ARRAY_SET";
case Opcode::ARRAY_LEN: return "ARRAY_LEN";
case Opcode::LOAD_GLOBAL: return "LOAD_GLOBAL";
case Opcode::STORE_GLOBAL: return "STORE_GLOBAL";
case Opcode::LESS: return "LESS";
case Opcode::LESS_EQUAL: return "LESS_EQUAL";
case Opcode::GREATER: return "GREATER";
case Opcode::GREATER_EQUAL: return "GREATER_EQUAL";
case Opcode::EQUAL_EQUAL: return "EQUAL_EQUAL";
case Opcode::NOT_EQUAL: return "NOT_EQUAL";
case Opcode::JMP: return "JMP";
case Opcode::JIF_FALSE: return "JIF_FALSE";
case Opcode::JIF_TRUE: return "JIF_TRUE";
case Opcode::CALL: return "CALL";
case Opcode::RETURN: return "RETURN";
case Opcode::STRING_CONCAT: return "STRING_CONCAT";
case Opcode::ENTER_TRY: return "ENTER_TRY";
case Opcode::LEAVE_TRY: return "LEAVE_TRY";
case Opcode::THROW: return "THROW";
case Opcode::CALLHOST: return "CALLHOST";
}
return "UNKNOWN";
}
// ----------------------------------------------------------------------------
// Instruction — Tek bir IR talimatı
//
// Okunabilirlik öncelikli bir tasarım: her talimat TÜM alanları içerir,
// kullanılmayanlar varsayılan değerde (-1 veya boş) kalır.
// Bu yaklaşım bellek israfeder ama her talimatın hangi veriyle çalıştığı
// açıkça görünür — karmaşık union/variant yapısı gerekmez.
// ----------------------------------------------------------------------------
struct Instruction {
Opcode opcode;
// Hedef slot — sonucun yazılacağı yer (LOAD_CONST, ADD, CALL vb.)
int dest = -1;
// Kaynak slot — kopyalama veya döndürme için (LOAD_SLOT, RETURN)
int src = -1;
// Aritmetik/karşılaştırma operandları
int left = -1;
int right = -1;
// LOAD_CONST için yüklenecek tam sayı sabiti
int intValue = 0;
// LOAD_FLOAT için yüklenecek double sabiti (#44)
double floatValue = 0.0;
// LOAD_STRING için yüklenecek metin sabiti (tırnak işaretleri olmadan)
std::string stringValue;
// JMP / JIF_FALSE için hedef instruction indeksi
// Üretim sırasında bilinmiyorsa -1 bırakılır, sonradan doldurulur (backpatch).
int jumpTarget = -1;
// JIF_FALSE için kontrol edilecek koşul slotu
int cond = -1;
// CALL / CALLHOST için çağrılacak fonksiyonun adı
std::string functionName;
// CALL / CALLHOST için argüman slot indeksleri (sırayla)
std::vector<int> argSlots;
explicit Instruction(Opcode op) : opcode(op) {}
};
#endif // SAQUT_IR_INSTRUCTION

View File

@ -1,175 +0,0 @@
#include "ir/ir_function.hpp"
#include <iomanip>
#include <iostream>
#include <string>
// ─────────────────────────────────────────────────────────────────────────────
// Yardımcılar
// ─────────────────────────────────────────────────────────────────────────────
// Slot adını kısa göster: s0, s1, ...
static std::string slot(int s) {
if (s == -1) return "?";
return "s" + std::to_string(s);
}
// İkili op sembolü: ADD → "+"
static const char* opSymbol(Opcode op) {
switch (op) {
case Opcode::ADD: return "+";
case Opcode::SUB: return "-";
case Opcode::MUL: return "*";
case Opcode::DIV: return "/";
case Opcode::FADD: return "+.";
case Opcode::FSUB: return "-.";
case Opcode::FMUL: return "*.";
case Opcode::FDIV: return "/.";
case Opcode::MOD: return "%";
case Opcode::BAND: return "&";
case Opcode::BOR: return "|";
case Opcode::SHL: return "<<";
case Opcode::SHR: return ">>";
case Opcode::LESS: return "<";
case Opcode::LESS_EQUAL: return "<=";
case Opcode::GREATER: return ">";
case Opcode::GREATER_EQUAL: return ">=";
case Opcode::EQUAL_EQUAL: return "==";
case Opcode::NOT_EQUAL: return "!=";
default: return "?";
}
}
static bool isBinaryOp(Opcode op) {
switch (op) {
case Opcode::ADD: case Opcode::SUB: case Opcode::MUL:
case Opcode::DIV: case Opcode::MOD:
case Opcode::FADD: case Opcode::FSUB: case Opcode::FMUL: case Opcode::FDIV:
case Opcode::BAND: case Opcode::BOR: case Opcode::SHL: case Opcode::SHR:
case Opcode::LESS: case Opcode::LESS_EQUAL:
case Opcode::GREATER: case Opcode::GREATER_EQUAL:
case Opcode::EQUAL_EQUAL: case Opcode::NOT_EQUAL:
return true;
default: return false;
}
}
// ─────────────────────────────────────────────────────────────────────────────
// IRFunction::dump
// ─────────────────────────────────────────────────────────────────────────────
void IRFunction::dump() const {
// Başlık: fonksiyon adı + slot bilgisi
std::string header = " " + name + "()";
if (paramCount > 0) {
header = " " + name + "(";
for (int i = 0; i < paramCount; i++) {
if (i) header += ", ";
header += "s" + std::to_string(i);
}
header += ")";
}
header += " [" + std::to_string(slotCount) + " slot]";
// Başlık: NAME=fibonacci PARAMS=1 SLOTS=10
std::cout << "NAME=" << name
<< " PARAMS=" << paramCount
<< " SLOTS=" << slotCount
<< "\n";
// Talimatlar
for (int i = 0; i < (int)instructions.size(); i++) {
const Instruction& ins = instructions[i];
// Satır numarası
std::cout << " " << std::setw(3) << std::right << i << " ";
// Opcode sütunu (12 karakter genişlik)
std::cout << std::left << std::setw(12) << opcodeName(ins.opcode);
// Operandlar — opcode'a göre farklı format
if (ins.opcode == Opcode::LOAD_CONST) {
std::cout << slot(ins.dest) << " = " << ins.intValue;
} else if (ins.opcode == Opcode::LOAD_STRING) {
std::cout << slot(ins.dest) << " = \"" << ins.stringValue << "\"";
} else if (ins.opcode == Opcode::LOAD_SLOT) {
std::cout << slot(ins.dest) << " = " << slot(ins.src);
} else if (isBinaryOp(ins.opcode)) {
std::cout << slot(ins.dest) << " = "
<< slot(ins.left) << " " << opSymbol(ins.opcode)
<< " " << slot(ins.right);
} else if (ins.opcode == Opcode::JMP) {
std::cout << "" << ins.jumpTarget;
} else if (ins.opcode == Opcode::JIF_FALSE) {
std::cout << "!" << slot(ins.cond) << "" << ins.jumpTarget;
} else if (ins.opcode == Opcode::CALL) {
std::cout << slot(ins.dest) << " = " << ins.functionName << "(";
for (int j = 0; j < (int)ins.argSlots.size(); j++) {
if (j) std::cout << ", ";
std::cout << slot(ins.argSlots[j]);
}
std::cout << ")";
} else if (ins.opcode == Opcode::CALLHOST) {
std::cout << ins.functionName << "(";
for (int j = 0; j < (int)ins.argSlots.size(); j++) {
if (j) std::cout << ", ";
std::cout << slot(ins.argSlots[j]);
}
std::cout << ")";
} else if (ins.opcode == Opcode::BNOT) {
std::cout << slot(ins.dest) << " = ~" << slot(ins.src);
} else if (ins.opcode == Opcode::LOAD_FLOAT) {
std::cout << slot(ins.dest) << " = " << ins.floatValue;
} else if (ins.opcode == Opcode::INT_TO_FLOAT) {
std::cout << slot(ins.dest) << " = (float)" << slot(ins.src);
} else if (ins.opcode == Opcode::FLOAT_TO_INT) {
std::cout << slot(ins.dest) << " = (int)" << slot(ins.src);
} else if (ins.opcode == Opcode::FNEG) {
std::cout << slot(ins.dest) << " = -" << slot(ins.src);
} else if (ins.opcode == Opcode::STRUCT_NEW) {
std::cout << slot(ins.dest) << " = struct<" << ins.functionName << ">[" << ins.intValue << " alan]";
} else if (ins.opcode == Opcode::FIELD_GET) {
std::cout << slot(ins.dest) << " = " << slot(ins.src) << "." << ins.intValue;
} else if (ins.opcode == Opcode::FIELD_SET) {
std::cout << slot(ins.dest) << "." << ins.intValue << " = " << slot(ins.right);
} else if (ins.opcode == Opcode::ARRAY_NEW) {
std::cout << slot(ins.dest) << " = array[" << ins.intValue << "]";
} else if (ins.opcode == Opcode::ARRAY_GET) {
std::cout << slot(ins.dest) << " = " << slot(ins.left) << "[" << slot(ins.right) << "]";
} else if (ins.opcode == Opcode::ARRAY_SET) {
std::cout << slot(ins.dest) << "[" << slot(ins.left) << "] = " << slot(ins.right);
} else if (ins.opcode == Opcode::ARRAY_LEN) {
std::cout << slot(ins.dest) << " = len(" << slot(ins.src) << ")";
} else if (ins.opcode == Opcode::LOAD_GLOBAL) {
std::cout << slot(ins.dest) << " = global[" << ins.intValue << "]";
} else if (ins.opcode == Opcode::STORE_GLOBAL) {
std::cout << "global[" << ins.intValue << "] = " << slot(ins.src);
} else if (ins.opcode == Opcode::RETURN) {
std::cout << slot(ins.src);
}
std::cout << "\n";
}
std::cout << "\n";
}

View File

@ -1,37 +0,0 @@
// ============================================================================
// saQut IR — IRFunction (Tek Fonksiyonun IR Karşılığı)
//
// Bir IRFunction, kaynak koddaki tek bir fonksiyonun "pişmiş" halidir.
// IRGenerator bu yapıyı doldurur, Interpreter bu yapıyı çalıştırır.
//
// SLOT DÜZENI:
// slot[0 .. paramCount-1] → parametreler (soldan sağa)
// slot[paramCount ..] → lokal değişkenler ve geçici sonuçlar
// slotCount → toplam kaç slot lazım (frame boyutu)
//
// Örnek — fibonacci(int n):
// paramCount = 1 → slot[0] = n
// slotCount = 11 → slot[0..10] (0'ı parametre, 1-10 hesaplamalar)
// ============================================================================
#ifndef SAQUT_IR_FUNCTION
#define SAQUT_IR_FUNCTION
#include <string>
#include <vector>
#include "ir/instruction.hpp"
struct IRFunction {
std::string name; // kaynak koddaki fonksiyon adı
int paramCount; // kaç parametresi var
int slotCount; // frame boyutu (üretim sonunda doldurulur)
std::vector<Instruction> instructions; // bu fonksiyonun talimat listesi
IRFunction(std::string name, int paramCount)
: name(std::move(name)), paramCount(paramCount), slotCount(0) {}
// Okunabilir IR dump — "saqut run" hata ayıklaması veya inceleme için
void dump() const;
};
#endif // SAQUT_IR_FUNCTION

View File

@ -1,975 +0,0 @@
#include "ir/ir_generator.hpp"
#include "tokenizer/token.hpp"
#include "parser/nodes/program.hpp"
#include "parser/nodes/declarations.hpp"
#include "parser/nodes/statements.hpp"
#include "parser/nodes/expressions.hpp"
#include "parser/nodes/binary_expr.hpp"
#include "parser/nodes/identifier.hpp"
#include "parser/nodes/literal.hpp"
#include <stdexcept>
#include <string>
// Error struct alan sırası (ADR-025): makeError için IR tarafından bilinir
// 0=line, 1=col, 2=message, 3=trace, 4=code
static constexpr int ERROR_FIELD_COUNT = 5;
// ─────────────────────────────────────────────────────────────────────────────
// generate — Ana giriş noktası
// ─────────────────────────────────────────────────────────────────────────────
IRProgram IRGenerator::generate(ASTNode* programNode, SymbolTable& symbolTable) {
IRProgram program;
// 0. Geçiş: struct layout haritasını sembol tablosundan al
structLayouts_ = symbolTable.structLayouts;
// 1. Geçiş: modül-düzeyi VariableDecl'leri topla ve kayıt et
// "Global" değil — bu dosyanın (modülün) kendi değişkenleri.
std::vector<VariableDeclNode*> globalVars;
for (ASTNode* child : programNode->getChildren()) {
if (child->kind == ASTKind::VariableDecl) {
auto* vd = (VariableDeclNode*)child;
nameToGlobal_[vd->name] = globalCount_++;
program.globalCount++;
program.globalNames.push_back(vd->name);
globalVars.push_back(vd);
}
}
// 2. Geçiş: fonksiyonları üret
for (ASTNode* child : programNode->getChildren()) {
if (child->kind == ASTKind::FunctionDecl) {
nameToSlot_.clear();
nextSlot_ = 0;
auto* fnDecl = (FunctionDeclNode*)child;
IRFunction irFn(fnDecl->name, (int)fnDecl->params.size());
program.addFunction(std::move(irFn));
currentFunction_ = program.findFunction(fnDecl->name);
// main'in başında global değişkenlerin init ifadelerini üret
if (fnDecl->name == "main") {
for (VariableDeclNode* gv : globalVars) {
if (gv->initExpr) {
int initSlot = generateExpression(gv->initExpr);
emitStoreGlobal(initSlot, nameToGlobal_[gv->name]);
}
}
}
generateFunction(child);
currentFunction_->slotCount = nextSlot_;
}
}
return program;
}
// ─────────────────────────────────────────────────────────────────────────────
// generateFunction — Tek bir fonksiyonu IR'a çevirir
// ─────────────────────────────────────────────────────────────────────────────
void IRGenerator::generateFunction(ASTNode* functionDeclNode) {
auto* fn = (FunctionDeclNode*)functionDeclNode;
// Parametreler slot 0, 1, 2, ... sırasıyla alır.
// Interpreter, CALL sırasında bu slotlara argümanları kopyalar.
for (auto* param : fn->params) {
int slot = freshSlot();
registerVariable(param->name, slot);
}
// Fonksiyon gövdesi — children[0] her zaman BlockNode
auto& children = fn->getChildren();
if (!children.empty()) {
generateStatement(children[0]);
}
}
// ─────────────────────────────────────────────────────────────────────────────
// generateStatement — Deyim türlerine göre talimat üret
// ─────────────────────────────────────────────────────────────────────────────
void IRGenerator::generateStatement(ASTNode* node) {
if (!node) return;
switch (node->kind) {
// ── Blok: içindeki her deyimi sırayla üret ───────────────────────────
case ASTKind::Block: {
for (ASTNode* child : node->getChildren()) {
generateStatement(child);
}
break;
}
// ── Değişken bildirimi: int x = <ifade> / Point p; ────────────────
case ASTKind::VariableDecl: {
auto* vd = (VariableDeclNode*)node;
// Bu değişken için yeni bir slot ayır
int varSlot = freshSlot();
registerVariable(vd->name, varSlot);
if (vd->initExpr) {
int initSlot = generateExpression(vd->initExpr);
// float/double değişkenine int sabit atama → INT_TO_FLOAT
bool targetIsFloat = (vd->varType == "float" || vd->varType == "double");
bool srcIsInt = false;
if (auto* e = dynamic_cast<ExpressionNode*>(vd->initExpr))
srcIsInt = e->resolvedType.isPrimitive() && e->resolvedType.prim == PrimitiveKind::Int;
if (targetIsFloat && srcIsInt) {
int conv = freshSlot();
emitIntToFloat(conv, initSlot);
initSlot = conv;
}
if (initSlot != varSlot) emitLoadSlot(varSlot, initSlot);
} else if (structLayouts_.count(vd->varType)) {
// Struct değişkeni: init ifadesi yoksa boş StructObject oluştur
int fc = getStructFieldCount(vd->varType);
emitStructNew(varSlot, vd->varType, fc);
}
// Sibling VariableDecl'ler: int a, b; → children'da diğer VariableDecl'ler
for (ASTNode* sib : node->getChildren()) {
if (sib->kind == ASTKind::VariableDecl) {
generateStatement(sib);
}
}
break;
}
// ── return <ifade> ───────────────────────────────────────────────────
case ASTKind::ReturnStatement: {
auto* rs = (ReturnStatementNode*)node;
int returnSlot = 0; // varsayılan: slot[0] (void fonksiyon / boş return)
if (rs->value) {
returnSlot = generateExpression(rs->value);
}
emitReturn(returnSlot);
break;
}
// ── if (koşul) { ... } [else { ... }] ───────────────────────────────
case ASTKind::IfStatement: {
auto* ifn = (IfStatementNode*)node;
// Koşulu hesapla
int condSlot = generateExpression(ifn->condition);
// "Koşul yanlışsa atla" → hedef henüz bilinmiyor, backpatch bekliyor
int jumpToElse = emitJumpIfFalse(condSlot);
// Then bloğu
if (ifn->thenBranch) generateStatement(ifn->thenBranch);
if (ifn->elseBranch) {
// Then bitti, else'i atla (then içinde çalışanlar else'e girmemeli)
int jumpOverElse = emitJumpUnconditional(-1);
// Şimdi else'in başlangıç konumunu biliyoruz → jumpToElse'i doldur
patchJump(jumpToElse);
generateStatement(ifn->elseBranch);
// Else bitti → jumpOverElse'i doldur
patchJump(jumpOverElse);
} else {
// Else yok → jumpToElse doğrudan if sonrasına atlıyor
patchJump(jumpToElse);
}
break;
}
// ── while (koşul) { gövde } ──────────────────────────────────────────
case ASTKind::WhileStatement: {
auto* ws = (WhileStatementNode*)node;
int loopStart = currentInstrIndex();
loopContextStack_.push_back({});
int condSlot = generateExpression(ws->condition);
int exitJump = emitJumpIfFalse(condSlot);
if (ws->body) generateStatement(ws->body);
// continue → LOOP_START (hedef baştan beri biliniyor)
for (int idx : loopContextStack_.back().continueJumps)
currentFunction_->instructions[idx].jumpTarget = loopStart;
emitJumpUnconditional(loopStart);
patchJump(exitJump); // OUT burası
// break → OUT
int outTarget = currentInstrIndex();
for (int idx : loopContextStack_.back().breakJumps)
currentFunction_->instructions[idx].jumpTarget = outTarget;
loopContextStack_.pop_back();
break;
}
// ── for (init; koşul; güncelleme) { gövde } ─────────────────────────
//
// IR yapısı (continue C_LABEL'a, break OUT'a atlar):
// [init]
// LOOP_START:
// [koşul] → JIF_FALSE OUT
// [gövde]
// C_LABEL:
// [güncelleme]
// JMP LOOP_START
// OUT:
// ─────────────────────────────────────────────────────────────────────
case ASTKind::ForStatement: {
auto* fs = (ForStatementNode*)node;
if (fs->init) generateStatement(fs->init);
int loopStart = currentInstrIndex();
loopContextStack_.push_back({});
int condSlot = fs->condition ? generateExpression(fs->condition) : -1;
int exitJump = (condSlot != -1) ? emitJumpIfFalse(condSlot) : -1;
if (fs->body) generateStatement(fs->body);
// C_LABEL: güncelleme başlangıcı — continue buraya atlar
int cLabel = currentInstrIndex();
for (int idx : loopContextStack_.back().continueJumps)
currentFunction_->instructions[idx].jumpTarget = cLabel;
if (fs->update) generateExpression(fs->update);
emitJumpUnconditional(loopStart);
if (exitJump != -1) patchJump(exitJump); // OUT burası
// break → OUT
int outTarget = currentInstrIndex();
for (int idx : loopContextStack_.back().breakJumps)
currentFunction_->instructions[idx].jumpTarget = outTarget;
loopContextStack_.pop_back();
break;
}
// ── do { gövde } while (koşul) ───────────────────────────────────────
case ASTKind::DoWhileStatement: {
auto* dw = (DoWhileStatementNode*)node;
int loopStart = currentInstrIndex();
loopContextStack_.push_back({});
if (dw->body) generateStatement(dw->body);
// COND_LABEL: koşul değerlendirmesi — continue buraya atlar
int condLabel = currentInstrIndex();
for (int idx : loopContextStack_.back().continueJumps)
currentFunction_->instructions[idx].jumpTarget = condLabel;
int condSlot = generateExpression(dw->condition);
Instruction jit(Opcode::JIF_TRUE);
jit.cond = condSlot;
jit.jumpTarget = loopStart;
currentFunction_->instructions.push_back(std::move(jit));
// break → OUT (JIF_TRUE'dan sonraki konum)
int outTarget = currentInstrIndex();
for (int idx : loopContextStack_.back().breakJumps)
currentFunction_->instructions[idx].jumpTarget = outTarget;
loopContextStack_.pop_back();
break;
}
// ── İfade deyimi: bir ifadeyi değerlendirip sonucu at ────────────────
// Örnek: print(x) çağrısı, veya x = 5 ataması
case ASTKind::ExpressionStatement: {
auto* es = (ExpressionStatementNode*)node;
if (es->expression) {
generateExpression(es->expression); // sonucu kullanmıyoruz
}
break;
}
case ASTKind::BreakStatement: {
int jumpIdx = emitJumpUnconditional(-1);
if (!loopContextStack_.empty())
loopContextStack_.back().breakJumps.push_back(jumpIdx);
break;
}
case ASTKind::ContinueStatement: {
int jumpIdx = emitJumpUnconditional(-1);
if (!loopContextStack_.empty())
loopContextStack_.back().continueJumps.push_back(jumpIdx);
break;
}
// ── try { body } catch (Error e) { handler } (ADR-025) ────────────
case ASTKind::TryStatement: {
auto* ts = (TryStatementNode*)node;
// Catch değişkeni için slot; VM bu slota Error nesnesini yazar
int errorSlot = freshSlot();
if (!ts->catchVar.empty())
registerVariable(ts->catchVar, errorSlot);
// ENTER_TRY: catch hedefi henüz bilinmiyor (-1), sonradan patchlanır
Instruction enterTry(Opcode::ENTER_TRY);
enterTry.dest = errorSlot;
enterTry.jumpTarget = -1;
currentFunction_->instructions.push_back(std::move(enterTry));
int enterTryIdx = (int)currentFunction_->instructions.size() - 1;
// Try gövdesi
if (ts->body) generateStatement(ts->body);
// Normal çıkış: try frame'ini çıkar
Instruction leaveTry(Opcode::LEAVE_TRY);
currentFunction_->instructions.push_back(std::move(leaveTry));
// Catch bloğunu atla (normal akışta)
int jumpOverCatch = emitJumpUnconditional(-1);
// Catch etiketi: ENTER_TRY buraya atlayacak
int catchLabel = currentInstrIndex();
currentFunction_->instructions[enterTryIdx].jumpTarget = catchLabel;
// Catch gövdesi
if (ts->handler) generateStatement(ts->handler);
// Catch bitti
patchJump(jumpOverCatch);
break;
}
// ── throw <ifade>; (ADR-025) ────────────────────────────────────────
case ASTKind::ThrowStatement: {
auto* th = (ThrowStatementNode*)node;
int valSlot = th->value ? generateExpression(th->value) : freshSlot();
Instruction ins(Opcode::THROW);
ins.src = valSlot;
currentFunction_->instructions.push_back(std::move(ins));
break;
}
default:
break;
}
}
// ─────────────────────────────────────────────────────────────────────────────
// generateExpression — İfadeyi IR'a çevirir, sonucu içeren slot'u döndürür
// ─────────────────────────────────────────────────────────────────────────────
int IRGenerator::generateExpression(ASTNode* node) {
if (!node) return 0;
switch (node->kind) {
// ── Sabit değer: 42, 3.14, true ... ──────────────────────────────────
case ASTKind::Literal: {
auto* lit = (LiteralNode*)node;
int slot = freshSlot();
switch (lit->literalType) {
case LiteralType::INTEGER: {
// Float/double bağlamında tam sayı literali → LOAD_FLOAT (bağlama-göre tip, ADR-010)
bool asFloat = lit->resolvedType.isPrimitive() &&
(lit->resolvedType.prim == PrimitiveKind::Float ||
lit->resolvedType.prim == PrimitiveKind::Double);
if (asFloat) {
double val = 0.0;
if (lit->hasDirectValue) val = (double)lit->directIntValue;
else if (lit->parserToken.token) val = std::stod(lit->parserToken.token->token);
emitLoadFloat(slot, val);
} else {
int value = 0;
if (lit->hasDirectValue) value = lit->directIntValue;
else if (lit->parserToken.token) value = std::stoi(lit->parserToken.token->token);
emitLoadConst(slot, value);
}
break;
}
case LiteralType::BOOLEAN: {
int value = 0;
if (lit->hasDirectValue)
value = lit->directIntValue ? 1 : 0;
else
value = (lit->parserToken.token &&
lit->parserToken.token->token == "true") ? 1 : 0;
emitLoadConst(slot, value);
break;
}
case LiteralType::STRING: {
// StringToken::context tırnak işaretleri olmadan içeriği tutar
std::string content;
if (auto* st = dynamic_cast<StringToken*>(lit->lexerToken))
content = st->context;
else if (lit->parserToken.token) {
// Fallback: token'ın başındaki ve sonundaki " işaretlerini sıyır
std::string raw = lit->parserToken.token->token;
if (raw.size() >= 2 && raw.front() == '"' && raw.back() == '"')
content = raw.substr(1, raw.size() - 2);
else
content = raw;
}
Instruction ins(Opcode::LOAD_STRING);
ins.dest = slot;
ins.stringValue = std::move(content);
currentFunction_->instructions.push_back(std::move(ins));
break;
}
case LiteralType::FLOAT: {
double val = 0.0;
if (lit->parserToken.token)
val = std::stod(lit->parserToken.token->token);
emitLoadFloat(slot, val);
break;
}
case LiteralType::BOŞ:
// null literal → ValueKind::Null (ADR-021)
{ Instruction ins(Opcode::LOAD_NULL); ins.dest = slot;
currentFunction_->instructions.push_back(std::move(ins)); }
break;
}
return slot;
}
// ── Değişken ismi: n, first, second ... ──────────────────────────────
case ASTKind::Identifier: {
auto* id = (IdentifierNode*)node;
std::string name = id->parserToken.token ? id->parserToken.token->token : "";
if (isGlobal(name)) {
int tempSlot = freshSlot();
emitLoadGlobal(tempSlot, getGlobalIndex(name));
return tempSlot;
}
return lookupVariable(name);
}
// ── İkili ifade: x + y, x = y, x < y ... ────────────────────────────
case ASTKind::BinaryExpression: {
auto* bin = (BinaryExpressionNode*)node;
// Atama operatörleri: x = expr ve a[i] = expr
if (bin->Operator == TokenType::EQUAL) {
int rhsSlot = generateExpression(bin->Right);
// a[i] = val → ARRAY_SET
if (bin->Left && bin->Left->kind == ASTKind::IndexExpression) {
auto* idx = (IndexExpressionNode*)bin->Left;
int arrSlot = generateExpression(idx->object);
int idxSlot = generateExpression(idx->index);
emitArraySet(arrSlot, idxSlot, rhsSlot);
return rhsSlot;
}
// p.field = val → FIELD_SET
if (bin->Left && bin->Left->kind == ASTKind::MemberAccess) {
auto* ma = (MemberAccessNode*)bin->Left;
int objSlot = generateExpression(ma->object);
std::string structName;
if (auto* exprObj = dynamic_cast<ExpressionNode*>(ma->object))
structName = exprObj->resolvedType.structName;
int idx2 = getStructFieldIndex(structName, ma->member);
if (idx2 >= 0) emitFieldSet(objSlot, idx2, rhsSlot);
return rhsSlot;
}
auto* lhsId = (IdentifierNode*)bin->Left;
std::string varName = lhsId->parserToken.token->token;
if (isGlobal(varName)) {
emitStoreGlobal(rhsSlot, getGlobalIndex(varName));
return rhsSlot;
}
int varSlot = lookupVariable(varName);
if (rhsSlot != varSlot) emitLoadSlot(varSlot, rhsSlot);
return varSlot;
}
// Birleşik atama: += -= *= /= %= &= |= <<= >>=
// x OP= y ≡ x = x OP y
if (bin->Operator == TokenType::PLUS_EQUAL ||
bin->Operator == TokenType::MINUS_EQUAL ||
bin->Operator == TokenType::STAR_EQUAL ||
bin->Operator == TokenType::SLASH_EQUAL ||
bin->Operator == TokenType::PERCENT_EQUAL ||
bin->Operator == TokenType::AMPERSAND_EQUAL ||
bin->Operator == TokenType::PIPE_EQUAL ||
bin->Operator == TokenType::LSHIFT_EQUAL ||
bin->Operator == TokenType::RSHIFT_EQUAL) {
auto* lhsId = (IdentifierNode*)bin->Left;
std::string varName = lhsId->parserToken.token->token;
int rhsSlot = generateExpression(bin->Right);
Opcode arithOp = Opcode::ADD;
if (bin->Operator == TokenType::MINUS_EQUAL) arithOp = Opcode::SUB;
else if (bin->Operator == TokenType::STAR_EQUAL) arithOp = Opcode::MUL;
else if (bin->Operator == TokenType::SLASH_EQUAL) arithOp = Opcode::DIV;
else if (bin->Operator == TokenType::PERCENT_EQUAL) arithOp = Opcode::MOD;
else if (bin->Operator == TokenType::AMPERSAND_EQUAL) arithOp = Opcode::BAND;
else if (bin->Operator == TokenType::PIPE_EQUAL) arithOp = Opcode::BOR;
else if (bin->Operator == TokenType::LSHIFT_EQUAL) arithOp = Opcode::SHL;
else if (bin->Operator == TokenType::RSHIFT_EQUAL) arithOp = Opcode::SHR;
// string += string → STRING_CONCAT (ADR-024)
if (bin->Operator == TokenType::PLUS_EQUAL) {
if (auto* e = dynamic_cast<ExpressionNode*>(bin->Right))
if (e->resolvedType.isString()) arithOp = Opcode::STRING_CONCAT;
}
int resultSlot = freshSlot();
if (isGlobal(varName)) {
int currentSlot = freshSlot();
emitLoadGlobal(currentSlot, getGlobalIndex(varName));
emitBinaryOp(arithOp, resultSlot, currentSlot, rhsSlot);
emitStoreGlobal(resultSlot, getGlobalIndex(varName));
return resultSlot;
}
int varSlot = lookupVariable(varName);
emitBinaryOp(arithOp, resultSlot, varSlot, rhsSlot);
emitLoadSlot(varSlot, resultSlot);
return varSlot;
}
// Unary prefix: Left = nullptr (ör: -x, !x)
if (!bin->Left) {
int operandSlot = generateExpression(bin->Right);
int resultSlot = freshSlot();
if (bin->Operator == TokenType::MINUS) {
// -x → 0 - x
int zeroSlot = freshSlot();
emitLoadConst(zeroSlot, 0);
emitBinaryOp(Opcode::SUB, resultSlot, zeroSlot, operandSlot);
} else if (bin->Operator == TokenType::BANG) {
// !x → (x == 0): sıfırsa 1, değilse 0
int zeroSlot = freshSlot();
emitLoadConst(zeroSlot, 0);
emitBinaryOp(Opcode::EQUAL_EQUAL, resultSlot, operandSlot, zeroSlot);
} else if (bin->Operator == TokenType::TILDE) {
// ~x — bitsel değil
Instruction ins(Opcode::BNOT);
ins.dest = resultSlot;
ins.src = operandSlot;
currentFunction_->instructions.push_back(std::move(ins));
} else {
emitLoadSlot(resultSlot, operandSlot);
}
return resultSlot;
}
// Aritmetik operatörler
switch (bin->Operator) {
case TokenType::PLUS: return generateBinaryArithmetic(Opcode::ADD, bin->Left, bin->Right);
case TokenType::MINUS: return generateBinaryArithmetic(Opcode::SUB, bin->Left, bin->Right);
case TokenType::STAR: return generateBinaryArithmetic(Opcode::MUL, bin->Left, bin->Right);
case TokenType::SLASH: return generateBinaryArithmetic(Opcode::DIV, bin->Left, bin->Right);
case TokenType::PERCENT: return generateBinaryArithmetic(Opcode::MOD, bin->Left, bin->Right);
// Karşılaştırma operatörleri
case TokenType::LESS: return generateBinaryArithmetic(Opcode::LESS, bin->Left, bin->Right);
case TokenType::LESS_EQUAL: return generateBinaryArithmetic(Opcode::LESS_EQUAL, bin->Left, bin->Right);
case TokenType::GREATER: return generateBinaryArithmetic(Opcode::GREATER, bin->Left, bin->Right);
case TokenType::GREATER_EQUAL: return generateBinaryArithmetic(Opcode::GREATER_EQUAL, bin->Left, bin->Right);
case TokenType::EQUAL_EQUAL: return generateBinaryArithmetic(Opcode::EQUAL_EQUAL, bin->Left, bin->Right);
case TokenType::BANG_EQUAL: return generateBinaryArithmetic(Opcode::NOT_EQUAL, bin->Left, bin->Right);
// Bitsel operatörler
case TokenType::AMPERSAND: return generateBinaryArithmetic(Opcode::BAND, bin->Left, bin->Right);
case TokenType::PIPE: return generateBinaryArithmetic(Opcode::BOR, bin->Left, bin->Right);
case TokenType::LSHIFT: return generateBinaryArithmetic(Opcode::SHL, bin->Left, bin->Right);
case TokenType::RSHIFT: return generateBinaryArithmetic(Opcode::SHR, bin->Left, bin->Right);
// Mantıksal operatörler: kısa devre dallanmasıyla üretilir (ADR-008).
// NOT: sıradan ikili işlem değil — b, a'nın değerine göre atlanabilir.
case TokenType::AMPERSAND_AMPERSAND: {
int slotA = generateExpression(bin->Left);
int result = freshSlot();
emitLoadConst(result, 0); // varsayılan: false
int skipB = emitJumpIfFalse(slotA); // a false → b'yi atla
int slotB = generateExpression(bin->Right);
emitLoadSlot(result, slotB); // result = b
patchJump(skipB);
return result;
}
case TokenType::PIPE_PIPE: {
int slotA = generateExpression(bin->Left);
int result = freshSlot();
emitLoadConst(result, 1); // varsayılan: true
int skipB = emitJumpIfTrue(slotA); // a true → b'yi atla
int slotB = generateExpression(bin->Right);
emitLoadSlot(result, slotB); // result = b
patchJump(skipB);
return result;
}
default: {
// Bilinmeyen operatör — boş slot döndür
int slot = freshSlot();
emitLoadConst(slot, 0);
return slot;
}
}
}
// ── Fonksiyon çağrısı: fibonacci(n-1), print(x) ... ─────────────────
case ASTKind::Call: {
auto* call = (CallExpressionNode*)node;
// Hangi fonksiyon çağrılıyor? Callee bir Identifier
std::string fnName;
bool isBuiltin = false;
if (call->callee && call->callee->kind == ASTKind::Identifier) {
auto* calleeId = (IdentifierNode*)call->callee;
if (calleeId->parserToken.token) {
fnName = calleeId->parserToken.token->token;
}
// Builtin kontrolü: resolvedSymbol->isBuiltin
if (calleeId->resolvedSymbol && calleeId->resolvedSymbol->isBuiltin) {
isBuiltin = true;
}
}
// Her argümanı hesapla, sonuçların slot numaralarını topla
std::vector<int> argSlots;
for (ASTNode* arg : call->arguments) {
argSlots.push_back(generateExpression(arg));
}
if (isBuiltin) {
// CALLHOST: host (C++) fonksiyonu çağır (print gibi), dönüş değeri yok
Instruction ins(Opcode::CALLHOST);
ins.functionName = fnName;
ins.argSlots = argSlots;
currentFunction_->instructions.push_back(std::move(ins));
return -1; // Dönüş değeri yok
} else {
// CALL: saQut fonksiyonu çağır, sonucu yeni slota yaz
int destSlot = freshSlot();
Instruction ins(Opcode::CALL);
ins.dest = destSlot;
ins.functionName = fnName;
ins.argSlots = argSlots;
currentFunction_->instructions.push_back(std::move(ins));
return destSlot;
}
}
// ── Postfix: i++, i-- ────────────────────────────────────────────────
case ASTKind::Postfix: {
auto* pf = (PostfixNode*)node;
// Şu anki değeri döndür, sonra artır/azalt
int operandSlot = generateExpression(pf->operand);
int resultSlot = freshSlot(); // dönüş değeri (artırmadan önceki)
emitLoadSlot(resultSlot, operandSlot);
int oneSlot = freshSlot();
emitLoadConst(oneSlot, 1);
int newSlot = freshSlot();
if (pf->Operator == TokenType::PLUS_PLUS) {
emitBinaryOp(Opcode::ADD, newSlot, operandSlot, oneSlot);
} else {
emitBinaryOp(Opcode::SUB, newSlot, operandSlot, oneSlot);
}
emitLoadSlot(operandSlot, newSlot); // orijinal değişkeni güncelle
return resultSlot; // artırmadan önceki değer
}
// ── Üye erişimi okuma: p.x ───────────────────────────────────────────
case ASTKind::MemberAccess: {
auto* ma = (MemberAccessNode*)node;
int objSlot = generateExpression(ma->object);
int destSlot = freshSlot();
// Nesnenin struct adını resolvedType üstünden al (tip denetleyici yazdı)
std::string structName;
if (auto* exprObj = dynamic_cast<ExpressionNode*>(ma->object))
structName = exprObj->resolvedType.structName;
int idx = getStructFieldIndex(structName, ma->member);
if (idx >= 0) emitFieldGet(destSlot, objSlot, idx);
return destSlot;
}
case ASTKind::ArrayLiteral: {
auto* al = (ArrayLiteralNode*)node;
int arrSlot = freshSlot();
emitArrayNew(arrSlot, (int)al->elements.size());
for (int i = 0; i < (int)al->elements.size(); i++) {
int idxSlot = freshSlot();
emitLoadConst(idxSlot, i);
int valSlot = generateExpression(al->elements[i]);
emitArraySet(arrSlot, idxSlot, valSlot);
}
return arrSlot;
}
// ── Index erişimi okuma: a[i] ─────────────────────────────────────────
case ASTKind::IndexExpression: {
auto* idx = (IndexExpressionNode*)node;
int arrSlot = generateExpression(idx->object);
int idxSlot = generateExpression(idx->index);
int destSlot = freshSlot();
emitArrayGet(destSlot, arrSlot, idxSlot);
return destSlot;
}
default:
// Bilinmeyen ifade türü
return freshSlot(); // boş slot (0 değeriyle)
}
}
// ─────────────────────────────────────────────────────────────────────────────
// generateBinaryArithmetic — İkili op için sol+sağ üret, talimat ekle
// ─────────────────────────────────────────────────────────────────────────────
int IRGenerator::generateBinaryArithmetic(Opcode opcode, ASTNode* leftNode, ASTNode* rightNode) {
int leftSlot = generateExpression(leftNode);
int rightSlot = generateExpression(rightNode);
int destSlot = freshSlot();
// Float tip kontrolü — resolvedType üstünden (tip denetleyici tarafından yazıldı)
bool leftIsFloat = false, rightIsFloat = false;
bool leftIsString = false, rightIsString = false;
if (auto* e = dynamic_cast<ExpressionNode*>(leftNode)) {
leftIsFloat = e->resolvedType.isPrimitive() &&
(e->resolvedType.prim == PrimitiveKind::Float ||
e->resolvedType.prim == PrimitiveKind::Double);
leftIsString = e->resolvedType.isString();
}
if (auto* e = dynamic_cast<ExpressionNode*>(rightNode)) {
rightIsFloat = e->resolvedType.isPrimitive() &&
(e->resolvedType.prim == PrimitiveKind::Float ||
e->resolvedType.prim == PrimitiveKind::Double);
rightIsString = e->resolvedType.isString();
}
// String birleştirme (ADR-024): + → STRING_CONCAT
if ((leftIsString || rightIsString) && opcode == Opcode::ADD) {
emitBinaryOp(Opcode::STRING_CONCAT, destSlot, leftSlot, rightSlot);
return destSlot;
}
if (leftIsFloat || rightIsFloat) {
// Int operandı float'a çevir
if (!leftIsFloat) {
int conv = freshSlot();
emitIntToFloat(conv, leftSlot);
leftSlot = conv;
}
if (!rightIsFloat) {
int conv = freshSlot();
emitIntToFloat(conv, rightSlot);
rightSlot = conv;
}
// Float opcode eşleştirmesi
Opcode floatOp = opcode;
if (opcode == Opcode::ADD) floatOp = Opcode::FADD;
else if (opcode == Opcode::SUB) floatOp = Opcode::FSUB;
else if (opcode == Opcode::MUL) floatOp = Opcode::FMUL;
else if (opcode == Opcode::DIV) floatOp = Opcode::FDIV;
// karşılaştırma opcodeları aynı kalır (LESS, GREATER, vb.)
emitBinaryOp(floatOp, destSlot, leftSlot, rightSlot);
} else {
emitBinaryOp(opcode, destSlot, leftSlot, rightSlot);
}
return destSlot;
}
// ─────────────────────────────────────────────────────────────────────────────
// Slot yönetimi
// ─────────────────────────────────────────────────────────────────────────────
int IRGenerator::freshSlot() {
return nextSlot_++;
}
void IRGenerator::registerVariable(const std::string& name, int slot) {
nameToSlot_[name] = slot;
}
int IRGenerator::lookupVariable(const std::string& name) {
auto it = nameToSlot_.find(name);
if (it == nameToSlot_.end()) {
// Bu noktaya normalde gelinmemeli; sembol toplayıcı E001 üretmiş olur.
// Yine de çökmemek için 0 döndür.
return 0;
}
return it->second;
}
// ─────────────────────────────────────────────────────────────────────────────
// Talimat yazma yardımcıları
// ─────────────────────────────────────────────────────────────────────────────
void IRGenerator::emitLoadConst(int destSlot, int value) {
Instruction ins(Opcode::LOAD_CONST);
ins.dest = destSlot;
ins.intValue = value;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitLoadSlot(int destSlot, int srcSlot) {
Instruction ins(Opcode::LOAD_SLOT);
ins.dest = destSlot;
ins.src = srcSlot;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitLoadGlobal(int destSlot, int globalIndex) {
Instruction ins(Opcode::LOAD_GLOBAL);
ins.dest = destSlot;
ins.intValue = globalIndex;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitStoreGlobal(int srcSlot, int globalIndex) {
Instruction ins(Opcode::STORE_GLOBAL);
ins.src = srcSlot;
ins.intValue = globalIndex;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitLoadFloat(int destSlot, double value) {
Instruction ins(Opcode::LOAD_FLOAT);
ins.dest = destSlot;
ins.floatValue = value;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitIntToFloat(int destSlot, int srcSlot) {
Instruction ins(Opcode::INT_TO_FLOAT);
ins.dest = destSlot;
ins.src = srcSlot;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitStructNew(int destSlot, const std::string& structType, int fieldCount) {
Instruction ins(Opcode::STRUCT_NEW);
ins.dest = destSlot;
ins.intValue = fieldCount;
ins.functionName = structType; // struct tip adı
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitFieldGet(int destSlot, int objSlot, int fieldIdx) {
Instruction ins(Opcode::FIELD_GET);
ins.dest = destSlot;
ins.src = objSlot;
ins.intValue = fieldIdx;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitFieldSet(int objSlot, int fieldIdx, int valSlot) {
Instruction ins(Opcode::FIELD_SET);
ins.dest = objSlot;
ins.intValue = fieldIdx;
ins.right = valSlot;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitArrayNew(int destSlot, int capacity) {
Instruction ins(Opcode::ARRAY_NEW);
ins.dest = destSlot;
ins.intValue = capacity;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitArrayGet(int destSlot, int arrSlot, int idxSlot) {
Instruction ins(Opcode::ARRAY_GET);
ins.dest = destSlot;
ins.left = arrSlot;
ins.right = idxSlot;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitArraySet(int arrSlot, int idxSlot, int valSlot) {
Instruction ins(Opcode::ARRAY_SET);
ins.dest = arrSlot;
ins.left = idxSlot;
ins.right = valSlot;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitArrayLen(int destSlot, int arrSlot) {
Instruction ins(Opcode::ARRAY_LEN);
ins.dest = destSlot;
ins.src = arrSlot;
currentFunction_->instructions.push_back(std::move(ins));
}
int IRGenerator::getStructFieldIndex(const std::string& structType, const std::string& fieldName) const {
auto it = structLayouts_.find(structType);
if (it == structLayouts_.end()) return -1;
for (int i = 0; i < (int)it->second.size(); i++)
if (it->second[i].first == fieldName) return i;
return -1;
}
int IRGenerator::getStructFieldCount(const std::string& structType) const {
auto it = structLayouts_.find(structType);
if (it == structLayouts_.end()) return 0;
return (int)it->second.size();
}
bool IRGenerator::isGlobal(const std::string& name) const {
return nameToGlobal_.count(name) > 0;
}
int IRGenerator::getGlobalIndex(const std::string& name) const {
auto it = nameToGlobal_.find(name);
return (it != nameToGlobal_.end()) ? it->second : -1;
}
void IRGenerator::emitBinaryOp(Opcode op, int destSlot, int leftSlot, int rightSlot) {
Instruction ins(op);
ins.dest = destSlot;
ins.left = leftSlot;
ins.right = rightSlot;
currentFunction_->instructions.push_back(std::move(ins));
}
void IRGenerator::emitReturn(int srcSlot) {
Instruction ins(Opcode::RETURN);
ins.src = srcSlot;
currentFunction_->instructions.push_back(std::move(ins));
}
int IRGenerator::emitJumpUnconditional(int targetInstrIndex) {
Instruction ins(Opcode::JMP);
ins.jumpTarget = targetInstrIndex;
currentFunction_->instructions.push_back(std::move(ins));
return (int)currentFunction_->instructions.size() - 1;
}
int IRGenerator::emitJumpIfFalse(int condSlot) {
Instruction ins(Opcode::JIF_FALSE);
ins.cond = condSlot;
ins.jumpTarget = -1; // henüz bilinmiyor — patchJump() bekliyor
currentFunction_->instructions.push_back(std::move(ins));
return (int)currentFunction_->instructions.size() - 1;
}
int IRGenerator::emitJumpIfTrue(int condSlot) {
Instruction ins(Opcode::JIF_TRUE);
ins.cond = condSlot;
ins.jumpTarget = -1;
currentFunction_->instructions.push_back(std::move(ins));
return (int)currentFunction_->instructions.size() - 1;
}
void IRGenerator::patchJump(int instrIndex) {
// instrIndex'teki JMP veya JIF_FALSE'un hedefini şu anki konuma doldur
currentFunction_->instructions[instrIndex].jumpTarget = currentInstrIndex();
}
int IRGenerator::currentInstrIndex() const {
return (int)currentFunction_->instructions.size();
}

View File

@ -1,123 +0,0 @@
// ============================================================================
// saQut IR — IRGenerator (AST → IR Dönüşümü)
//
// AST'yi (parse edilmiş kaynak kodu) Instruction listelerine çevirir.
// Her fonksiyon için bir IRFunction üretir, hepsini IRProgram'a toplar.
//
// SLOT ATAMA STRATEJİSİ:
// - Her fonksiyon üretiminde nextSlot_ sıfırdan başlar.
// - Parametreler 0, 1, 2, ... slotlarına sırayla atanır.
// - Sonraki her değişken veya geçici sonuç freshSlot() ile yeni slot alır.
// - Slotlar asla geri verilmez (basitlik öncelikli).
// - Fonksiyon bitince nextSlot_ = slotCount.
//
// SINIRLAMALAR (fibonacci için yeterli, genel dil için TODO):
// - Aynı isimli iki değişken farklı iç kapsamlarda olsa bile çakışır.
// (fibonacci.sqt'de bu durum yok; gelecekte scope-aware slot atama gerekir.)
// - Sadece int değerler desteklenir (Value.kind şu an hep Int).
// ============================================================================
#ifndef SAQUT_IR_GENERATOR
#define SAQUT_IR_GENERATOR
#include <string>
#include <unordered_map>
#include <vector>
#include <utility>
#include "ir/ir_program.hpp"
#include "symbol/symbol_table.hpp"
#include "core/type.hpp"
#include "parser/ast_node.hpp"
class IRGenerator {
public:
// Ana giriş noktası: programNode = ProgramNode, tablo = sembol tablosu
IRProgram generate(ASTNode* programNode, SymbolTable& symbolTable);
private:
// ── Fonksiyon üretimi ─────────────────────────────────────────────────
void generateFunction(ASTNode* functionDeclNode);
// ── Deyim (statement) üretimi — talimat listesine yazar ──────────────
void generateStatement(ASTNode* node);
// ── İfade (expression) üretimi — sonucun slotunu döndürür ────────────
// Sonuç her zaman bir slotta bulunur. Identifier zaten bir slotta,
// hesaplamalar freshSlot() ile yeni slot alır.
int generateExpression(ASTNode* node);
// ── İkili operatör (binary op) için ortak yardımcı ───────────────────
int generateBinaryArithmetic(Opcode opcode, ASTNode* leftNode, ASTNode* rightNode);
// ── Slot yönetimi ─────────────────────────────────────────────────────
int freshSlot(); // Yeni slot numarası al (nextSlot_++)
void registerVariable(const std::string& name, int slot); // name → slot kaydı
int lookupVariable(const std::string& name); // name → slot (bulunamazsa hata)
// ── Talimat yazma yardımcıları ────────────────────────────────────────
// Talimatları currentFunction_->instructions'a ekler.
void emitLoadConst(int destSlot, int value);
void emitLoadFloat(int destSlot, double value);
void emitIntToFloat(int destSlot, int srcSlot);
void emitLoadSlot(int destSlot, int srcSlot);
void emitLoadGlobal(int destSlot, int globalIndex);
void emitStoreGlobal(int srcSlot, int globalIndex);
void emitStructNew(int destSlot, const std::string& structType, int fieldCount);
void emitFieldGet(int destSlot, int objSlot, int fieldIdx);
void emitFieldSet(int objSlot, int fieldIdx, int valSlot);
void emitArrayNew(int destSlot, int capacity);
void emitArrayGet(int destSlot, int arrSlot, int idxSlot);
void emitArraySet(int arrSlot, int idxSlot, int valSlot);
void emitArrayLen(int destSlot, int arrSlot);
void emitBinaryOp(Opcode op, int destSlot, int leftSlot, int rightSlot);
void emitReturn(int srcSlot);
// Koşulsuz atlama yazar; instruction indeksini döndürür (backpatch için).
// Hedef bilinmiyorsa -1 geçilir, patchJump() ile doldurulur.
int emitJumpUnconditional(int targetInstrIndex);
// JIF_FALSE talimatını -1 hedefle yazar, instruction indeksini döndürür.
// Döndürülen indeks ileride patchJump() ile doldurulur (backpatch).
int emitJumpIfFalse(int condSlot);
// JIF_TRUE talimatını -1 hedefle yazar, instruction indeksini döndürür.
int emitJumpIfTrue(int condSlot);
// Daha önce -1 hedefle yazılan jump'ın hedefini şu anki pozisyona doldur.
void patchJump(int instrIndex);
// Şu an kaç talimat üretildi? (jump hedefi belirlemek için)
int currentInstrIndex() const;
// ── Döngü bağlamı yığını — break/continue hedefleri ─────────────────
// Her döngüye girerken bir giriş push'lanır, çıkınca pop'lanır.
// İç içe döngülerde en üstteki giriş en içteki döngüye aittir.
struct LoopContext {
std::vector<int> breakJumps; // patch bekleyen break JMP indeksleri
std::vector<int> continueJumps; // patch bekleyen continue JMP indeksleri
};
std::vector<LoopContext> loopContextStack_;
// ── Per-function üretim durumu ────────────────────────────────────────
IRFunction* currentFunction_ = nullptr; // şu an üretilen fonksiyon
int nextSlot_ = 0; // sıradaki boş slot numarası
// Değişken ismi → slot numarası (lokal).
std::unordered_map<std::string, int> nameToSlot_;
// Global değişken ismi → global index
std::unordered_map<std::string, int> nameToGlobal_;
int globalCount_ = 0;
// Struct alan düzeni: struct adı → sıralı [(alan adı, Type)] listesi
// Sembol tablosundan generate() başında kopyalanır.
std::unordered_map<std::string, std::vector<std::pair<std::string, Type>>> structLayouts_;
int getStructFieldIndex(const std::string& structType, const std::string& fieldName) const;
int getStructFieldCount(const std::string& structType) const;
bool isGlobal(const std::string& name) const;
int getGlobalIndex(const std::string& name) const;
};
#endif // SAQUT_IR_GENERATOR

View File

@ -1,19 +0,0 @@
#include "ir/ir_program.hpp"
#include <iostream>
void IRProgram::dump() const {
std::cout << "IR DUMP\n\n";
if (globalCount > 0) {
std::cout << "GLOBALS (" << globalCount << ")\n";
for (int i = 0; i < (int)globalNames.size(); i++)
std::cout << " global[" << i << "] = " << globalNames[i] << "\n";
std::cout << "\n";
}
for (const auto& name : functionOrder) {
auto it = functions.find(name);
if (it != functions.end()) it->second.dump();
}
std::cout << "END\n";
}

View File

@ -1,56 +0,0 @@
// ============================================================================
// saQut IR — IRProgram (Bir .sqt Dosyasının Tüm IR İçeriği)
//
// IRProgram, üretilen tüm fonksiyonları tutar.
// Interpreter programı çalıştırmak için bu yapıyı kullanır.
//
// NEDEN İKİ YAPIDA TUTUYORUZ?
// - functionOrder: fonksiyonları tanımlandıkları sırayla tutar (dump için)
// - functions (unordered_map): CALL instruction'larında isimle hızlı arama için
//
// NOT: unordered_map değer semantiğiyle (IRFunction by value) tutar.
// findFunction() bir pointer döndürür — bu pointer tüm addFunction() çağrıları
// bittikten sonra alınmalıdır. Interpreter program üretildikten sonra çalıştığı
// için bu kural otomatik olarak sağlanır.
// ============================================================================
#ifndef SAQUT_IR_PROGRAM
#define SAQUT_IR_PROGRAM
#include <string>
#include <unordered_map>
#include <vector>
#include "ir/ir_function.hpp"
struct IRProgram {
// Fonksiyon adı → IRFunction (hızlı arama için)
std::unordered_map<std::string, IRFunction> functions;
// Ekleme sırası (dump'ta orijinal sırayla göstermek için)
std::vector<std::string> functionOrder;
// Modül-düzeyi değişkenler (LOAD_GLOBAL / STORE_GLOBAL için)
// Bunlar "global" değil — bu IRProgram'ın temsil ettiği tek modüle aittir.
// Çok-modüllü derlemede her modülün kendi IRProgram'ı (veya ayrı slot alanı) olur.
// TODO(#modül-scope): moduleId alanı eklenince Interpreter bu alana
// frame.function->moduleId üzerinden erişecek (bkz. TODO.md).
int globalCount = 0;
std::vector<std::string> globalNames; // index → isim (dump için)
// Yeni fonksiyon ekle
void addFunction(IRFunction fn) {
functionOrder.push_back(fn.name);
functions.emplace(fn.name, std::move(fn));
}
// İsimle ara — bulunamazsa nullptr döner
IRFunction* findFunction(const std::string& name) {
auto it = functions.find(name);
return (it != functions.end()) ? &it->second : nullptr;
}
// Tüm fonksiyonları ekleme sırasıyla yazdır
void dump() const;
};
#endif // SAQUT_IR_PROGRAM

View File

@ -79,7 +79,7 @@ std::string Lexer::getPositionRange() {
// --------------------------------------------------------------------------
// include: Belirtilen kelime mevcut konumda başlıyor mu?
// --------------------------------------------------------------------------
bool Lexer::include(std::string_view word, bool accept) {
bool Lexer::include(std::string word, bool accept) {
beginPosition();
for (size_t i = 0; i < word.size(); i++) {
if (isEnd()) {

View File

@ -22,7 +22,6 @@
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
#include "core/location.hpp"
#include "core/sourcefile.hpp"
@ -68,7 +67,7 @@ public:
std::string getPositionRange(); // Pozisyon aralığındaki metni döndür
// --- Desen Eşleme ---
bool include(std::string_view word, bool accept = true);
bool include(std::string word, bool accept = true);
// --- Konum Okuma/Yazma ---
int getOffset(); // Mevcut offset'i döndür

View File

@ -27,8 +27,6 @@
#include "cli/commands/tokens.hpp"
#include "cli/commands/ast.hpp"
#include "cli/commands/symbols.hpp"
#include "cli/commands/check.hpp"
#include "cli/commands/ir.hpp"
int main(int argc, char* argv[]) {
// Komutları kaydet
@ -50,14 +48,6 @@ int main(int argc, char* argv[]) {
"Sembol tablosu (fonksiyonlar, değişkenler)",
false, cmdSymbols});
cli.registerCommand({"check",
"Semantik analiz — tip denetimi + yapısal doğrulama",
false, cmdCheck});
cli.registerCommand({"ir",
"IR talimat listesini göster (ara temsil — bytecode öncesi)",
false, cmdIr});
// --- Gelecek komutlar (TODO) ---
cli.registerCommand({"compile",
"TODO: Kaynak kodu derle",

View File

@ -1,286 +0,0 @@
// ============================================================================
// saQut — AST Derin Klonlama (ADR-007)
//
// deepClone(node): tüm ağacı kopyalar, parent pointer'ları yeniden bağlar.
// IdentifierNode::resolvedSymbol orijinal sembol tablosunu gösterir (read-only,
// optimizasyon için yeterli — ADR-007).
// ============================================================================
#ifndef SAQUT_OPT_AST_CLONE
#define SAQUT_OPT_AST_CLONE
#include "parser/ast_node.hpp"
#include "parser/nodes/program.hpp"
#include "parser/nodes/declarations.hpp"
#include "parser/nodes/statements.hpp"
#include "parser/nodes/expressions.hpp"
#include "parser/nodes/binary_expr.hpp"
#include "parser/nodes/literal.hpp"
#include "parser/nodes/identifier.hpp"
inline ASTNode* deepClone(ASTNode* node);
// ── Yardımcı: typed pointer klonla ve parent'ı bağla ────────────────────────
static inline ASTNode* cloneChild(ASTNode* child, ASTNode* newParent) {
if (!child) return nullptr;
ASTNode* c = deepClone(child);
c->parent = newParent;
return c;
}
inline ASTNode* deepClone(ASTNode* node) {
if (!node) return nullptr;
switch (node->kind) {
// ── ProgramNode ──────────────────────────────────────────────────────────
case ASTKind::Program: {
auto* src = static_cast<ProgramNode*>(node);
auto* dst = new ProgramNode();
dst->loc = src->loc;
for (auto* ch : src->getChildren()) dst->addChild(deepClone(ch));
return dst;
}
// ── FunctionDeclNode ─────────────────────────────────────────────────────
case ASTKind::FunctionDecl: {
auto* src = static_cast<FunctionDeclNode*>(node);
auto* dst = new FunctionDeclNode();
dst->loc = src->loc;
dst->name = src->name;
dst->returnType = src->returnType;
for (auto* p : src->params) {
auto* cp = static_cast<VariableDeclNode*>(deepClone(p));
cp->parent = dst;
dst->params.push_back(cp);
}
for (auto* ch : src->getChildren()) dst->addChild(deepClone(ch));
return dst;
}
// ── VariableDeclNode ─────────────────────────────────────────────────────
case ASTKind::VariableDecl: {
auto* src = static_cast<VariableDeclNode*>(node);
auto* dst = new VariableDeclNode();
dst->loc = src->loc;
dst->name = src->name;
dst->varType = src->varType;
dst->isReachable = src->isReachable;
if (src->initExpr) dst->initExpr = cloneChild(src->initExpr, dst);
for (auto* ch : src->getChildren()) dst->addChild(deepClone(ch));
return dst;
}
// ── StructDeclNode ───────────────────────────────────────────────────────
case ASTKind::StructDecl: {
auto* src = static_cast<StructDeclNode*>(node);
auto* dst = new StructDeclNode();
dst->loc = src->loc;
dst->name = src->name;
for (auto* ch : src->getChildren()) dst->addChild(deepClone(ch));
return dst;
}
// ── BlockNode ────────────────────────────────────────────────────────────
case ASTKind::Block: {
auto* src = static_cast<BlockNode*>(node);
auto* dst = new BlockNode();
dst->loc = src->loc;
dst->isReachable = src->isReachable;
for (auto* ch : src->getChildren()) dst->addChild(deepClone(ch));
return dst;
}
// ── IfStatementNode ──────────────────────────────────────────────────────
case ASTKind::IfStatement: {
auto* src = static_cast<IfStatementNode*>(node);
auto* dst = new IfStatementNode();
dst->loc = src->loc;
dst->isReachable = src->isReachable;
dst->condition = cloneChild(src->condition, dst);
dst->thenBranch = cloneChild(src->thenBranch, dst);
dst->elseBranch = cloneChild(src->elseBranch, dst);
return dst;
}
// ── WhileStatementNode ───────────────────────────────────────────────────
case ASTKind::WhileStatement: {
auto* src = static_cast<WhileStatementNode*>(node);
auto* dst = new WhileStatementNode();
dst->loc = src->loc;
dst->isReachable = src->isReachable;
dst->condition = cloneChild(src->condition, dst);
dst->body = cloneChild(src->body, dst);
return dst;
}
// ── ForStatementNode ─────────────────────────────────────────────────────
case ASTKind::ForStatement: {
auto* src = static_cast<ForStatementNode*>(node);
auto* dst = new ForStatementNode();
dst->loc = src->loc;
dst->isReachable = src->isReachable;
dst->init = cloneChild(src->init, dst);
dst->condition = cloneChild(src->condition, dst);
dst->update = cloneChild(src->update, dst);
dst->body = cloneChild(src->body, dst);
return dst;
}
// ── DoWhileStatementNode ─────────────────────────────────────────────────
case ASTKind::DoWhileStatement: {
auto* src = static_cast<DoWhileStatementNode*>(node);
auto* dst = new DoWhileStatementNode();
dst->loc = src->loc;
dst->isReachable = src->isReachable;
dst->body = cloneChild(src->body, dst);
dst->condition = cloneChild(src->condition, dst);
return dst;
}
// ── ReturnStatementNode ──────────────────────────────────────────────────
case ASTKind::ReturnStatement: {
auto* src = static_cast<ReturnStatementNode*>(node);
auto* dst = new ReturnStatementNode();
dst->loc = src->loc;
dst->isReachable = src->isReachable;
dst->value = cloneChild(src->value, dst);
return dst;
}
// ── BreakStatementNode ───────────────────────────────────────────────────
case ASTKind::BreakStatement: {
auto* src = static_cast<BreakStatementNode*>(node);
auto* dst = new BreakStatementNode();
dst->loc = src->loc;
dst->isReachable = src->isReachable;
return dst;
}
// ── ContinueStatementNode ────────────────────────────────────────────────
case ASTKind::ContinueStatement: {
auto* src = static_cast<ContinueStatementNode*>(node);
auto* dst = new ContinueStatementNode();
dst->loc = src->loc;
dst->isReachable = src->isReachable;
return dst;
}
// ── ExpressionStatementNode ──────────────────────────────────────────────
case ASTKind::ExpressionStatement: {
auto* src = static_cast<ExpressionStatementNode*>(node);
auto* dst = new ExpressionStatementNode();
dst->loc = src->loc;
dst->isReachable = src->isReachable;
dst->expression = cloneChild(src->expression, dst);
return dst;
}
// ── BinaryExpressionNode ─────────────────────────────────────────────────
case ASTKind::BinaryExpression: {
auto* src = static_cast<BinaryExpressionNode*>(node);
auto* dst = new BinaryExpressionNode();
dst->loc = src->loc;
dst->Operator = src->Operator;
dst->resolvedType = src->resolvedType;
dst->isConstant = src->isConstant;
dst->Left = cloneChild(src->Left, dst);
dst->Right = cloneChild(src->Right, dst);
return dst;
}
// ── LiteralNode ──────────────────────────────────────────────────────────
case ASTKind::Literal: {
auto* src = static_cast<LiteralNode*>(node);
auto* dst = new LiteralNode();
dst->loc = src->loc;
dst->literalType = src->literalType;
dst->literalBase = src->literalBase;
dst->isFloatValue = src->isFloatValue;
dst->lexerToken = src->lexerToken; // orijinal token, salt-okunur
dst->parserToken = src->parserToken; // aynı token pointer, salt-okunur
dst->resolvedType = src->resolvedType;
dst->isConstant = src->isConstant;
dst->hasDirectValue = src->hasDirectValue;
dst->directIntValue = src->directIntValue;
return dst;
}
// ── IdentifierNode ───────────────────────────────────────────────────────
case ASTKind::Identifier: {
auto* src = static_cast<IdentifierNode*>(node);
auto* dst = new IdentifierNode();
dst->loc = src->loc;
dst->lexerToken = src->lexerToken;
dst->parserToken = src->parserToken;
dst->resolvedSymbol = src->resolvedSymbol; // orijinal tablo, salt-okunur
dst->resolvedType = src->resolvedType;
dst->isConstant = src->isConstant;
return dst;
}
// ── PostfixNode ──────────────────────────────────────────────────────────
case ASTKind::Postfix: {
auto* src = static_cast<PostfixNode*>(node);
auto* dst = new PostfixNode();
dst->loc = src->loc;
dst->Operator = src->Operator;
dst->resolvedType = src->resolvedType;
dst->isConstant = src->isConstant;
dst->operand = cloneChild(src->operand, dst);
return dst;
}
// ── CallExpressionNode ───────────────────────────────────────────────────
case ASTKind::Call: {
auto* src = static_cast<CallExpressionNode*>(node);
auto* dst = new CallExpressionNode();
dst->loc = src->loc;
dst->resolvedType = src->resolvedType;
dst->isConstant = src->isConstant;
dst->callee = cloneChild(src->callee, dst);
for (auto* arg : src->arguments) {
ASTNode* ca = deepClone(arg);
ca->parent = dst;
dst->arguments.push_back(ca);
}
return dst;
}
// ── MemberAccessNode ─────────────────────────────────────────────────────
case ASTKind::MemberAccess: {
auto* src = static_cast<MemberAccessNode*>(node);
auto* dst = new MemberAccessNode();
dst->loc = src->loc;
dst->resolvedType = src->resolvedType;
dst->isConstant = src->isConstant;
dst->member = src->member;
dst->arrow = src->arrow;
dst->object = cloneChild(src->object, dst);
return dst;
}
// ── IndexExpressionNode ──────────────────────────────────────────────────
case ASTKind::IndexExpression: {
auto* src = static_cast<IndexExpressionNode*>(node);
auto* dst = new IndexExpressionNode();
dst->loc = src->loc;
dst->resolvedType = src->resolvedType;
dst->isConstant = src->isConstant;
dst->object = cloneChild(src->object, dst);
dst->index = cloneChild(src->index, dst);
return dst;
}
// ── UnaryExpression ──────────────────────────────────────────────────────
// UnaryExpression şu anda ayrı bir sınıf değil; parser tarafından
// BinaryExpression veya PostfixNode olarak temsil ediliyor.
// Gelecekte eklenmesi gerekirse buraya eklenecek.
default:
// Bilinmeyen node tipi — klonlanamaz; orijinal döndür (güvenli değil ama
// derleme aşamasında tüm tipler yukarıda kaplanmalı).
return node;
}
}
#endif // SAQUT_OPT_AST_CLONE

View File

@ -1,371 +0,0 @@
// ============================================================================
// saQut — Sabit Katlama (Constant Folding) Pass (ADR-009)
//
// BinaryExpression(Literal, OP, Literal) → Literal
// Sadece tam sayı sabitleri katlanır; kayan nokta şimdilik dışarıda.
// Derleme zamanı sıfıra bölme: W002 uyarısı verilir, katlama yapılmaz.
// ============================================================================
#ifndef SAQUT_OPT_CONSTANT_FOLDING
#define SAQUT_OPT_CONSTANT_FOLDING
#include <string>
#include "opt/optimization_pass.hpp"
#include "parser/nodes/binary_expr.hpp"
#include "parser/nodes/literal.hpp"
#include "parser/nodes/identifier.hpp"
#include "parser/nodes/statements.hpp"
#include "parser/nodes/expressions.hpp"
#include "parser/nodes/declarations.hpp"
#include "parser/nodes/program.hpp"
#include "diagnostic/diagnostic_engine.hpp"
class ConstantFoldingPass : public OptimizationPass {
public:
explicit ConstantFoldingPass(DiagnosticEngine& diag) : diag_(diag) {}
bool run(ASTNode* root, SymbolTable*) override {
changed_ = false;
fold(root);
return changed_;
}
const std::string& name() const override {
static std::string n = "constant-folding";
return n;
}
private:
DiagnosticEngine& diag_;
bool changed_ = false;
// ── Literal değer okuma ──────────────────────────────────────────────────
static bool isIntLit(ASTNode* node) {
auto* lit = dynamic_cast<LiteralNode*>(node);
return lit && lit->literalType == LiteralType::INTEGER;
}
// Boolean veya integer literal — unary ! için her ikisi de geçerli
static bool isScalarLit(ASTNode* node) {
auto* lit = dynamic_cast<LiteralNode*>(node);
return lit && (lit->literalType == LiteralType::INTEGER ||
lit->literalType == LiteralType::BOOLEAN);
}
static int getIntVal(LiteralNode* lit) {
if (lit->hasDirectValue) return lit->directIntValue;
if (lit->parserToken.token) return std::stoi(lit->parserToken.token->token);
return 0;
}
// Boolean literali int'e çevir: "true"→1, "false"→0
static int getScalarVal(LiteralNode* lit) {
if (lit->literalType == LiteralType::BOOLEAN) {
if (!lit->parserToken.token) return 0;
return (lit->parserToken.token->token == "true") ? 1 : 0;
}
return getIntVal(lit);
}
// Unary operatör katlama
static bool canFoldUnary(TokenType op) {
switch (op) {
case TokenType::BANG: // !
case TokenType::TILDE: // ~
case TokenType::MINUS: // - (negatif)
case TokenType::PLUS: // + (pozitif, no-op)
return true;
default:
return false;
}
}
static int computeUnary(TokenType op, int v) {
switch (op) {
case TokenType::BANG: return !v ? 1 : 0;
case TokenType::TILDE: return ~v;
case TokenType::MINUS: return -v;
case TokenType::PLUS: return v;
default: return v;
}
}
// ── Operatör hesaplama ───────────────────────────────────────────────────
static bool canFoldOp(TokenType op) {
switch (op) {
case TokenType::PLUS:
case TokenType::MINUS:
case TokenType::STAR:
case TokenType::SLASH:
case TokenType::PERCENT:
case TokenType::EQUAL_EQUAL:
case TokenType::BANG_EQUAL:
case TokenType::LESS:
case TokenType::GREATER:
case TokenType::LESS_EQUAL:
case TokenType::GREATER_EQUAL:
case TokenType::AMPERSAND:
case TokenType::PIPE:
case TokenType::LSHIFT:
case TokenType::RSHIFT:
case TokenType::AMPERSAND_AMPERSAND:
case TokenType::PIPE_PIPE:
return true;
default:
return false;
}
}
static int computeOp(TokenType op, int l, int r) {
switch (op) {
case TokenType::PLUS: return l + r;
case TokenType::MINUS: return l - r;
case TokenType::STAR: return l * r;
case TokenType::SLASH: return l / r;
case TokenType::PERCENT: return l % r;
case TokenType::EQUAL_EQUAL: return l == r ? 1 : 0;
case TokenType::BANG_EQUAL: return l != r ? 1 : 0;
case TokenType::LESS: return l < r ? 1 : 0;
case TokenType::GREATER: return l > r ? 1 : 0;
case TokenType::LESS_EQUAL: return l <= r ? 1 : 0;
case TokenType::GREATER_EQUAL: return l >= r ? 1 : 0;
case TokenType::AMPERSAND: return l & r;
case TokenType::PIPE: return l | r;
case TokenType::LSHIFT: return l << r;
case TokenType::RSHIFT: return l >> r;
case TokenType::AMPERSAND_AMPERSAND: return (l && r) ? 1 : 0;
case TokenType::PIPE_PIPE: return (l || r) ? 1 : 0;
default: return 0;
}
}
// ── Sentetik literal oluştur ─────────────────────────────────────────────
static LiteralNode* makeFoldedLit(int value, const SourceLocation& loc, const Type& type) {
auto* lit = new LiteralNode();
lit->loc = loc;
lit->literalType = LiteralType::INTEGER;
lit->hasDirectValue = true;
lit->directIntValue = value;
lit->resolvedType = type;
lit->isConstant = true;
return lit;
}
// ── Ana ziyaretçi: bottom-up, pointer-by-reference ───────────────────────
// Dönüş değeri: aynı node veya yerine geçen yeni node.
// Folding yapıldıysa orijinal node silinir, yeni node döndürülür.
ASTNode* fold(ASTNode* node) {
if (!node) return nullptr;
switch (node->kind) {
// ── İfadeler ────────────────────────────────────────────────────────
case ASTKind::BinaryExpression: {
auto* bin = static_cast<BinaryExpressionNode*>(node);
// Alt ağaçları önce kat
ASTNode* newLeft = fold(bin->Left);
if (newLeft != bin->Left) { bin->Left = newLeft; if (newLeft) newLeft->parent = bin; }
ASTNode* newRight = fold(bin->Right);
if (newRight != bin->Right) { bin->Right = newRight; if (newRight) newRight->parent = bin; }
// ── Unary dal: Left==nullptr → !x, ~x, -x, +x ──────────────────
if (bin->Left == nullptr) {
if (!isScalarLit(bin->Right)) return bin;
if (!canFoldUnary(bin->Operator)) return bin;
auto* rlit = static_cast<LiteralNode*>(bin->Right);
int rv = getScalarVal(rlit);
int result = computeUnary(bin->Operator, rv);
LiteralNode* lit = makeFoldedLit(result, bin->loc, bin->resolvedType);
delete bin->Right;
delete bin;
changed_ = true;
return lit;
}
// ── Binary dal: iki taraf da tam sayı sabiti ────────────────────
if (!isIntLit(bin->Left) || !isIntLit(bin->Right)) return bin;
if (!canFoldOp(bin->Operator)) return bin;
auto* llit = static_cast<LiteralNode*>(bin->Left);
auto* rlit = static_cast<LiteralNode*>(bin->Right);
int lv = getIntVal(llit);
int rv = getIntVal(rlit);
// W002: Derleme zamanı sıfıra bölme
if ((bin->Operator == TokenType::SLASH || bin->Operator == TokenType::PERCENT) && rv == 0) {
Diagnostic d;
d.level = DiagLevel::Warning;
d.code = "W002";
d.loc = bin->loc;
d.message = "Derleme zamanı sıfıra bölme — katlama yapılmadı";
diag_.report(d);
return bin; // fold etme
}
int result = computeOp(bin->Operator, lv, rv);
LiteralNode* lit = makeFoldedLit(result, bin->loc, bin->resolvedType);
delete bin->Left;
delete bin->Right;
delete bin;
changed_ = true;
return lit;
}
case ASTKind::Postfix: {
auto* pf = static_cast<PostfixNode*>(node);
ASTNode* newOp = fold(pf->operand);
if (newOp != pf->operand) { pf->operand = newOp; if (newOp) newOp->parent = pf; }
return pf;
}
case ASTKind::Call: {
auto* call = static_cast<CallExpressionNode*>(node);
if (call->callee) {
ASTNode* nc = fold(call->callee);
if (nc != call->callee) { call->callee = nc; if (nc) nc->parent = call; }
}
for (auto*& arg : call->arguments) {
ASTNode* na = fold(arg);
if (na != arg) { arg = na; if (na) na->parent = call; }
}
return call;
}
case ASTKind::MemberAccess: {
auto* ma = static_cast<MemberAccessNode*>(node);
ASTNode* no = fold(ma->object);
if (no != ma->object) { ma->object = no; if (no) no->parent = ma; }
return ma;
}
case ASTKind::IndexExpression: {
auto* ix = static_cast<IndexExpressionNode*>(node);
ASTNode* no = fold(ix->object);
if (no != ix->object) { ix->object = no; if (no) no->parent = ix; }
ASTNode* ni = fold(ix->index);
if (ni != ix->index) { ix->index = ni; if (ni) ni->parent = ix; }
return ix;
}
// Literal ve Identifier değişmez
case ASTKind::Literal:
case ASTKind::Identifier:
return node;
// ── Deyimler (çocuklara iner) ────────────────────────────────────────
case ASTKind::ExpressionStatement: {
auto* es = static_cast<ExpressionStatementNode*>(node);
if (es->expression) {
ASTNode* ne = fold(es->expression);
if (ne != es->expression) { es->expression = ne; if (ne) ne->parent = es; }
}
return es;
}
case ASTKind::ReturnStatement: {
auto* rs = static_cast<ReturnStatementNode*>(node);
if (rs->value) {
ASTNode* nv = fold(rs->value);
if (nv != rs->value) { rs->value = nv; if (nv) nv->parent = rs; }
}
return rs;
}
case ASTKind::VariableDecl: {
auto* vd = static_cast<VariableDeclNode*>(node);
if (vd->initExpr) {
ASTNode* ni = fold(vd->initExpr);
if (ni != vd->initExpr) { vd->initExpr = ni; if (ni) ni->parent = vd; }
}
for (auto*& ch : vd->getChildren()) {
ASTNode* nc = fold(ch);
if (nc != ch) { ch = nc; if (nc) nc->parent = vd; }
}
return vd;
}
case ASTKind::IfStatement: {
auto* ifs = static_cast<IfStatementNode*>(node);
if (ifs->condition) {
ASTNode* nc = fold(ifs->condition);
if (nc != ifs->condition) { ifs->condition = nc; if (nc) nc->parent = ifs; }
}
if (ifs->thenBranch) fold(ifs->thenBranch);
if (ifs->elseBranch) fold(ifs->elseBranch);
return ifs;
}
case ASTKind::WhileStatement: {
auto* ws = static_cast<WhileStatementNode*>(node);
if (ws->condition) {
ASTNode* nc = fold(ws->condition);
if (nc != ws->condition) { ws->condition = nc; if (nc) nc->parent = ws; }
}
if (ws->body) fold(ws->body);
return ws;
}
case ASTKind::ForStatement: {
auto* fs = static_cast<ForStatementNode*>(node);
if (fs->init) { ASTNode* n = fold(fs->init); if (n != fs->init) { fs->init = n; if (n) n->parent = fs; } }
if (fs->condition) { ASTNode* n = fold(fs->condition); if (n != fs->condition) { fs->condition = n; if (n) n->parent = fs; } }
if (fs->update) { ASTNode* n = fold(fs->update); if (n != fs->update) { fs->update = n; if (n) n->parent = fs; } }
if (fs->body) fold(fs->body);
return fs;
}
case ASTKind::DoWhileStatement: {
auto* dw = static_cast<DoWhileStatementNode*>(node);
if (dw->body) fold(dw->body);
if (dw->condition) {
ASTNode* nc = fold(dw->condition);
if (nc != dw->condition) { dw->condition = nc; if (nc) nc->parent = dw; }
}
return dw;
}
// ── Blok ve üst düzey ────────────────────────────────────────────────
case ASTKind::Block: {
auto* blk = static_cast<BlockNode*>(node);
for (auto*& ch : blk->getChildren()) {
ASTNode* nc = fold(ch);
if (nc != ch) { ch = nc; if (nc) nc->parent = blk; }
}
return blk;
}
case ASTKind::FunctionDecl: {
auto* fn = static_cast<FunctionDeclNode*>(node);
for (auto*& ch : fn->getChildren()) {
ASTNode* nc = fold(ch);
if (nc != ch) { ch = nc; if (nc) nc->parent = fn; }
}
return fn;
}
case ASTKind::Program: {
auto* prog = static_cast<ProgramNode*>(node);
for (auto*& ch : prog->getChildren()) {
ASTNode* nc = fold(ch);
if (nc != ch) { ch = nc; if (nc) nc->parent = prog; }
}
return prog;
}
default:
// Bilinmeyen veya işlenmeyen node — olduğu gibi bırak
for (auto*& ch : node->getChildren()) {
ASTNode* nc = fold(ch);
if (nc != ch) { ch = nc; if (nc) nc->parent = node; }
}
return node;
}
}
};
#endif // SAQUT_OPT_CONSTANT_FOLDING

View File

@ -1,117 +0,0 @@
// ============================================================================
// saQut — Ölü Kod Eleme (Dead Code Elimination) Pass (ADR-009)
//
// Bir Block içinde ilk return/break/continue'dan sonra gelen deyimler
// erişilemez (unreachable) olarak işaretlenir ve silinir.
// ============================================================================
#ifndef SAQUT_OPT_DEAD_CODE_ELIM
#define SAQUT_OPT_DEAD_CODE_ELIM
#include <string>
#include <algorithm>
#include "opt/optimization_pass.hpp"
#include "parser/nodes/statements.hpp"
#include "parser/nodes/declarations.hpp"
#include "parser/nodes/expressions.hpp"
#include "parser/nodes/program.hpp"
#include "diagnostic/diagnostic_engine.hpp"
class DeadCodeElimPass : public OptimizationPass {
public:
explicit DeadCodeElimPass(DiagnosticEngine& diag) : diag_(diag) {}
bool run(ASTNode* root, SymbolTable*) override {
changed_ = false;
visit(root);
return changed_;
}
const std::string& name() const override {
static std::string n = "dead-code-elim";
return n;
}
private:
DiagnosticEngine& diag_;
bool changed_ = false;
void visit(ASTNode* node) {
if (!node) return;
switch (node->kind) {
// ── Block: ana DCE mantığı ───────────────────────────────────────────
case ASTKind::Block: {
auto* blk = static_cast<BlockNode*>(node);
auto& ch = blk->getChildren();
bool term = false;
for (auto* child : ch) {
if (term) {
if (auto* sn = dynamic_cast<StatementNode*>(child)) {
if (sn->isReachable) {
sn->isReachable = false;
changed_ = true;
diag_.report("W003", sn->loc,
"Bu kod hiçbir zaman çalışmaz (return/break/continue sonrası)");
}
}
}
if (child->kind == ASTKind::ReturnStatement ||
child->kind == ASTKind::BreakStatement ||
child->kind == ASTKind::ContinueStatement)
term = true;
}
// remove_if erişilemez düğümleri sona taşır (silmez), sonra delete
auto toErase = std::remove_if(ch.begin(), ch.end(),
[](ASTNode* n) {
auto* sn = dynamic_cast<StatementNode*>(n);
return sn && !sn->isReachable;
});
for (auto it = toErase; it != ch.end(); ++it) delete *it;
ch.erase(toErase, ch.end());
// Alt bloklara da in
for (auto* child : ch) visit(child);
break;
}
// ── İf/While/For gövdelerine in ─────────────────────────────────────
case ASTKind::IfStatement: {
auto* ifs = static_cast<IfStatementNode*>(node);
visit(ifs->thenBranch);
visit(ifs->elseBranch);
break;
}
case ASTKind::WhileStatement: {
auto* ws = static_cast<WhileStatementNode*>(node);
visit(ws->body);
break;
}
case ASTKind::ForStatement: {
auto* fs = static_cast<ForStatementNode*>(node);
visit(fs->body);
break;
}
case ASTKind::DoWhileStatement: {
auto* dw = static_cast<DoWhileStatementNode*>(node);
visit(dw->body);
break;
}
// ── Üst düzey: fonksiyon gövdelerine in ─────────────────────────────
case ASTKind::FunctionDecl:
case ASTKind::Program:
default:
for (auto* ch : node->getChildren()) visit(ch);
break;
}
}
};
#endif // SAQUT_OPT_DEAD_CODE_ELIM

View File

@ -1,70 +0,0 @@
// ============================================================================
// saQut — Optimizasyon Yöneticisi (ADR-007, ADR-009)
//
// İKİ KULLANIM YOLU:
//
// 1. runPassesInPlace(root, table)
// Pass'leri verilen AST üstünde doğrudan çalıştırır — klon yok.
// run / ir / transpile gibi "tek seferlik" komutlar bu yolu kullanır:
// AST'nin tek versiyonu gerekiyor, orijinali saklamaya gerek yok.
//
// 2. optimize(root, table) [sadece ast komutu için]
// Önce deepClone, sonra runPassesInPlace. Orijinali dokunulmaz bırakır.
// Çıktı: optimize edilmiş klon (caller delete eder).
// ast komutunun "öncesi / sonrası" karşılaştırması için zorunlu.
// Diğer komutlar bu yolu ÇAĞIRMAMALI — gereksiz klon maliyeti.
//
// Fixpoint garantisi: her pass yalnızca küçülten dönüşümler yapar
// (katlama: n düğüm → 1 düğüm; DCE: düğüm siler). Büyüten pass
// (inlining vb.) eklenirse maxFixpointRounds tavanı zorunludur (ADR-009).
// ============================================================================
#ifndef SAQUT_OPT_MANAGER
#define SAQUT_OPT_MANAGER
#include <memory>
#include <vector>
#include "core/config.hpp"
#include "opt/ast_clone.hpp"
#include "opt/optimization_pass.hpp"
#include "opt/constant_folding.hpp"
#include "opt/dead_code_elim.hpp"
#include "diagnostic/diagnostic_engine.hpp"
#include "symbol/symbol_table.hpp"
class OptimizationManager {
public:
explicit OptimizationManager(const CompilerConfig& cfg, DiagnosticEngine& diag) {
if (cfg.optConstantFolding)
passes_.push_back(std::make_unique<ConstantFoldingPass>(diag));
if (cfg.optDeadCodeElim)
passes_.push_back(std::make_unique<DeadCodeElimPass>(diag));
maxRounds_ = cfg.maxFixpointRounds;
}
// Pass'leri verilen AST üstünde yerinde çalıştırır — klon yok.
// run / ir ve diğer tek-versiyon komutları bu yolu kullanır.
void runPassesInPlace(ASTNode* root, SymbolTable* table) {
for (int round = 0; round < maxRounds_; ++round) {
bool anyChange = false;
for (auto& pass : passes_)
if (pass->run(root, table)) anyChange = true;
if (!anyChange) break;
}
}
// Önce deepClone, sonra runPassesInPlace. Orijinal dokunulmaz.
// SADECE ast komutu kullanır — öncesi/sonrası karşılaştırması için.
// Dönen pointer caller'a aittir (delete edilmeli).
ASTNode* optimize(ASTNode* root, SymbolTable* table) {
ASTNode* clone = deepClone(root);
runPassesInPlace(clone, table);
return clone;
}
private:
std::vector<std::unique_ptr<OptimizationPass>> passes_;
int maxRounds_ = 10;
};
#endif // SAQUT_OPT_MANAGER

View File

@ -1,19 +0,0 @@
#ifndef SAQUT_OPT_PASS
#define SAQUT_OPT_PASS
#include <string>
#include "parser/ast_node.hpp"
#include "symbol/symbol_table.hpp"
class OptimizationPass {
public:
virtual ~OptimizationPass() = default;
// Pass'i çalıştırır. En az bir dönüşüm yaptıysa true döndürür.
// root: optimize edilecek klonlanmış AST kökü (sahiplik değişmez).
virtual bool run(ASTNode* root, SymbolTable* table) = 0;
virtual const std::string& name() const = 0;
};
#endif // SAQUT_OPT_PASS

View File

@ -79,15 +79,11 @@ public:
// JsonObject — Yapıcı
// PARAMETRE: depth — JSON girinti seviyesi (0 = en dış)
// YAN ETKİ: m_ss'e açılış süslü parantezi yazar
// NOT: Açılış süslü parantezi kasıtlı olarak girintisiz yazılır.
// str() çıktısı her zaman bir "key": ya da dizi elemanı konumuna
// gömülür ve o konum zaten kendi girintisini sağlar; burada ayrıca
// m_indent eklenirse aynı boşluklar iki kez yazılır (bkz. addRaw/addItem).
JsonObject(int depth)
: m_indent(jsonIndent(depth)),
m_indentInner(jsonIndent(depth + 1))
{
m_ss << "{\n";
m_ss << m_indent << "{\n";
}
// add() — String alan ekle
@ -100,15 +96,6 @@ public:
addRaw(key, "\"" + jsonEscape(value) + "\"");
}
// add() — C string alanı ekle
// const char* literalleri (örn. "Block") bool overload'a kaymasın diye
// ayrı bir overload gerekir; aksi halde örtük const char* -> bool
// dönüşümü std::string'e öncelikli olur ve "kind": true gibi hatalı
// çıktı üretir.
void add(const std::string& key, const char* value) {
add(key, std::string(value));
}
// add() — Sayısal alan ekle
// PARAMETRELER:
// key — JSON anahtarı
@ -185,12 +172,9 @@ public:
template<typename Fn>
void addArray(const std::string& key, Fn callback) {
if (m_hasFields) m_ss << ",\n";
m_ss << m_indentInner << "\"" << jsonEscape(key) << "\": [";
m_ss << m_indentInner << "\"" << jsonEscape(key) << "\": [\n";
m_arrayDepth++;
bool saved = m_hasArrayItem;
m_hasArrayItem = false; // her dizi kendi virgül sayacıyla başlar
callback();
m_hasArrayItem = saved;
m_arrayDepth--;
m_ss << "\n" << m_indentInner << "]";
m_hasFields = true;

View File

@ -31,7 +31,6 @@
#include <string>
#include <vector>
#include "core/location.hpp"
#include "core/type.hpp"
#include "parser/token.hpp"
#include "tools.hpp"
@ -87,8 +86,6 @@ enum class ASTKind {
ExpressionStatement, // ifade + noktalı virgül (;)
// children: [expression]
// Örn: x = 5; veya foo();
TryStatement, // try { body } catch (Error e) { handler } (ADR-025)
ThrowStatement, // throw <ifade>; (ADR-025)
/* ====== İfadeler (Expressions) ====== */
BinaryExpression, // İkili işlem: sol OP sağ.
@ -109,8 +106,6 @@ enum class ASTKind {
// children: [object], [member]
IndexExpression, // Dizi/indeks erişimi: a[i].
// children: [object], [index]
ArrayLiteral, // Dizi literali: [1, 2, 3].
// children: [element0, element1, ...]
};
// ============================================================================
@ -240,12 +235,10 @@ public:
// KARMAŞIKLIK: O(1) — referans döndürür
std::vector<ASTNode*>& getChildren() { return children; }
// ~ASTNode() — children vektörünü özyinelemeli siler.
// Typed pointer'lar (condition, thenBranch vb.) alt sınıf yıkıcılarına bırakılır;
// children vektörü ile typed pointer'lar örtüşmediği için double-delete olmaz.
virtual ~ASTNode() {
for (auto* ch : children) delete ch;
}
// ~ASTNode() — Sanal yıkıcı (polimorfik silme için)
// delete ASTNode* yapıldığında doğru alt sınıf yıkıcısı çağrılır.
// Bu olmazsa türetilmiş sınıfların kaynakları sızdırılır.
virtual ~ASTNode() = default;
protected:
// children — Alt düğümlerin vektörü.
@ -254,47 +247,6 @@ protected:
std::vector<ASTNode*> children;
};
// ============================================================================
// ExpressionNode — Değer Üreten Düğümlerin Tabanı (Faz 1, ADR-012)
// ============================================================================
//
// Bir DEĞER üreten her düğüm (Literal, Identifier, BinaryExpression, Call,
// Postfix, MemberAccess, IndexExpression) buradan türer. Bir ifadenin bir
// TİPİ vardır; analiz/optimizasyon alanları burada toplanır.
//
class ExpressionNode : public ASTNode {
public:
// TODO(faz-3): tip denetleyici doldurur. Şimdilik Error = "henüz çözülmedi".
Type resolvedType;
// TODO(faz-4): sabit katlama (constant folding) bayrağı.
bool isConstant = false;
// TODO(faz-4): foldedValue — katlanmış sabit değer (temsil Faz 4'te netleşir).
// resolvedType'ın JSON karşılığı (henüz çözülmemişse null gösterilir).
std::string resolvedTypeJson() const {
return resolvedType.isError() ? std::string("null") : resolvedType.toJson();
}
};
// ============================================================================
// StatementNode — Eylem/Kontrol Akışı Yürüten Düğümlerin Tabanı (Faz 1)
// ============================================================================
//
// Değer üretmeyen, bir iş/kontrol akışı yürüten her düğüm (Block, If, For,
// While, DoWhile, Return, Break, Continue, ExpressionStatement ve şimdilik
// VariableDecl) buradan türer. Tipi yoktur; akış-analizi alanları taşır.
//
// TODO(faz-1 gözden geçirme): VariableDecl/FunctionDecl/StructDecl'in tam
// sınıflandırması provizyonel — VariableDecl burada (blok içinde erişilebilirliğe
// tabi), Function/StructDecl doğrudan ASTNode altında kaldı.
//
class StatementNode : public ASTNode {
public:
// TODO(faz-3/4): erişilebilirlik (dead-code) analizi günceller.
bool isReachable = true;
};
// ============================================================================
// childrenToJson — Düğümün çocuklarını JSON array olarak yaz
// ============================================================================

View File

@ -18,7 +18,6 @@ std::string BinaryExpressionNode::toJson(int depth) {
obj.add("operator", std::string(OPERATOR_MAP_REV.count(Operator) ? OPERATOR_MAP_REV.at(Operator) : "?"));
if (Left) obj.addRaw("left", Left->toJson(depth + 1));
if (Right) obj.addRaw("right", Right->toJson(depth + 1));
obj.addRaw("resolvedType", resolvedTypeJson());
obj.addRaw("location", loc.toJson());
return obj.str();
}

View File

@ -3,14 +3,13 @@
#include "parser/ast_node.hpp"
class BinaryExpressionNode : public ExpressionNode {
class BinaryExpressionNode : public ASTNode {
public:
TokenType Operator;
ASTNode* Left = nullptr;
ASTNode* Right = nullptr;
BinaryExpressionNode();
~BinaryExpressionNode() override { delete Left; delete Right; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};

View File

@ -3,7 +3,6 @@
// FunctionDeclNode
FunctionDeclNode::FunctionDeclNode() { kind = ASTKind::FunctionDecl; }
FunctionDeclNode::~FunctionDeclNode() { for (auto* p : params) delete p; }
void FunctionDeclNode::log(int indent) {
std::cout << jsonIndent(indent) << "FunctionDecl (" << name << " : " << returnType << ")\n";
for (auto* child : children) child->log(indent + 1);
@ -13,9 +12,6 @@ std::string FunctionDeclNode::toJson(int depth) {
obj.add("kind", "FunctionDecl");
obj.add("name", name);
obj.add("returnType", returnType);
obj.addArray("params", [&]() {
for (auto* p : params) obj.addItem(p->toJson(depth + 2));
});
obj.addArray("children", [&]() {
for (auto* child : children) obj.addItem(child->toJson(depth + 2));
});
@ -34,7 +30,6 @@ std::string VariableDeclNode::toJson(int depth) {
obj.add("kind", "VariableDecl");
obj.add("name", name);
obj.add("varType", varType);
obj.add("isReachable", isReachable);
if (initExpr) obj.addRaw("init", initExpr->toJson(depth + 1));
obj.addRaw("location", loc.toJson());
return obj.str();

View File

@ -3,26 +3,21 @@
#include "parser/ast_node.hpp"
class VariableDeclNode; // fwd — FunctionDeclNode::params için
class FunctionDeclNode : public ASTNode {
public:
std::string name;
std::string returnType;
std::vector<VariableDeclNode*> params; // TODO(faz2): parametreler
FunctionDeclNode();
~FunctionDeclNode() override;
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class VariableDeclNode : public StatementNode {
class VariableDeclNode : public ASTNode {
public:
std::string varType;
std::string name;
ASTNode* initExpr = nullptr;
VariableDeclNode();
~VariableDeclNode() override { delete initExpr; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};

View File

@ -12,7 +12,6 @@ std::string PostfixNode::toJson(int depth) {
obj.add("kind", "Postfix");
obj.add("operator", std::string(OPERATOR_MAP_REV.count(Operator) ? OPERATOR_MAP_REV.at(Operator) : "?"));
if (operand) obj.addRaw("operand", operand->toJson(depth + 1));
obj.addRaw("resolvedType", resolvedTypeJson());
obj.addRaw("location", loc.toJson());
return obj.str();
}
@ -31,7 +30,6 @@ std::string CallExpressionNode::toJson(int depth) {
obj.addArray("arguments", [&]() {
for (auto* arg : arguments) obj.addItem(arg->toJson(depth + 2));
});
obj.addRaw("resolvedType", resolvedTypeJson());
obj.addRaw("location", loc.toJson());
return obj.str();
}
@ -48,24 +46,6 @@ std::string MemberAccessNode::toJson(int depth) {
obj.add("member", member);
obj.add("arrow", arrow);
if (object) obj.addRaw("object", object->toJson(depth + 1));
obj.addRaw("resolvedType", resolvedTypeJson());
obj.addRaw("location", loc.toJson());
return obj.str();
}
// ArrayLiteralNode
ArrayLiteralNode::ArrayLiteralNode() { kind = ASTKind::ArrayLiteral; }
void ArrayLiteralNode::log(int indent) {
std::cout << jsonIndent(indent) << "ArrayLiteral [" << elements.size() << " eleman]\n";
for (auto* e : elements) e->log(indent + 1);
}
std::string ArrayLiteralNode::toJson(int depth) {
JsonObject obj(depth);
obj.add("kind", "ArrayLiteral");
obj.addArray("elements", [&]() {
for (auto* e : elements) obj.addItem(e->toJson(depth + 2));
});
obj.addRaw("resolvedType", resolvedTypeJson());
obj.addRaw("location", loc.toJson());
return obj.str();
}
@ -82,7 +62,6 @@ std::string IndexExpressionNode::toJson(int depth) {
obj.add("kind", "IndexExpression");
if (object) obj.addRaw("object", object->toJson(depth + 1));
if (index) obj.addRaw("index", index->toJson(depth + 1));
obj.addRaw("resolvedType", resolvedTypeJson());
obj.addRaw("location", loc.toJson());
return obj.str();
}

View File

@ -3,52 +3,39 @@
#include "parser/ast_node.hpp"
class PostfixNode : public ExpressionNode {
class PostfixNode : public ASTNode {
public:
ASTNode* operand = nullptr;
TokenType Operator;
PostfixNode();
~PostfixNode() override { delete operand; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class CallExpressionNode : public ExpressionNode {
class CallExpressionNode : public ASTNode {
public:
ASTNode* callee = nullptr;
std::vector<ASTNode*> arguments;
CallExpressionNode();
~CallExpressionNode() override { delete callee; for (auto* a : arguments) delete a; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class MemberAccessNode : public ExpressionNode {
class MemberAccessNode : public ASTNode {
public:
ASTNode* object = nullptr;
std::string member;
bool arrow = false;
MemberAccessNode();
~MemberAccessNode() override { delete object; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class IndexExpressionNode : public ExpressionNode {
class IndexExpressionNode : public ASTNode {
public:
ASTNode* object = nullptr;
ASTNode* index = nullptr;
IndexExpressionNode();
~IndexExpressionNode() override { delete object; delete index; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class ArrayLiteralNode : public ExpressionNode {
public:
std::vector<ASTNode*> elements;
ArrayLiteralNode();
~ArrayLiteralNode() override { for (auto* e : elements) delete e; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};

View File

@ -1,5 +1,6 @@
#include "parser/nodes/identifier.hpp"
#include <iostream>
#include <sstream>
#include "parser/ast_json.hpp"
IdentifierNode::IdentifierNode() { kind = ASTKind::Identifier; }
@ -10,10 +11,13 @@ void IdentifierNode::log(int indent) {
}
std::string IdentifierNode::toJson(int depth) {
JsonObject obj(depth);
obj.add("kind", "Identifier");
obj.add("name", parserToken.token ? parserToken.token->token : "?");
obj.addRaw("resolvedType", resolvedTypeJson());
obj.addRaw("location", loc.toJson());
return obj.str();
std::string in = jsonIndent(depth);
std::string name = parserToken.token ? parserToken.token->token : "?";
std::ostringstream ss;
ss << in << "{\n"
<< in << " \"kind\": \"Identifier\",\n"
<< in << " \"name\": \"" << jsonEscape(name) << "\",\n"
<< in << " \"location\": " << loc.toJson() << "\n"
<< in << "}";
return ss.str();
}

View File

@ -3,16 +3,11 @@
#include "parser/ast_node.hpp"
struct Symbol; // TODO(faz-2): sembol tablosu (Symbol) tanımlandığında bağlanacak
class IdentifierNode : public ExpressionNode {
class IdentifierNode : public ASTNode {
public:
Token* lexerToken = nullptr;
ParserToken parserToken;
// TODO(faz-2): isim çözümlemede sembol tablosundaki tanıma bağlanır.
Symbol* resolvedSymbol = nullptr;
IdentifierNode();
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;

View File

@ -1,33 +1,34 @@
#include "parser/nodes/literal.hpp"
#include <iostream>
#include <sstream>
#include "parser/ast_json.hpp"
LiteralNode::LiteralNode() { kind = ASTKind::Literal; }
void LiteralNode::log(int indent) {
std::string val = hasDirectValue ? std::to_string(directIntValue)
: (parserToken.token ? parserToken.token->token : "?");
std::cout << padRight("", indent)
<< "Literal {" << val << "} "
<< "Literal {" << (parserToken.token ? parserToken.token->token : "?") << "} "
<< literalTypeToString(literalType);
if (isConstant) std::cout << " [folded]";
if (literalType == LiteralType::INTEGER && literalBase != 10)
std::cout << " (base " << literalBase << ")";
std::cout << "\n";
}
std::string LiteralNode::toJson(int depth) {
std::string val = hasDirectValue ? std::to_string(directIntValue)
: (parserToken.token ? parserToken.token->token : "?");
JsonObject obj(depth);
obj.add("kind", "Literal");
obj.add("literalType", literalTypeToString(literalType));
obj.add("value", val);
if (literalType == LiteralType::INTEGER && literalBase != 10)
obj.add("base", literalBase);
if (literalType == LiteralType::FLOAT)
obj.add("isFloat", true);
obj.addRaw("resolvedType", resolvedTypeJson());
obj.addRaw("location", loc.toJson());
return obj.str();
std::string in = jsonIndent(depth);
std::string val = parserToken.token ? parserToken.token->token : "?";
std::ostringstream ss;
ss << in << "{\n"
<< in << " \"kind\": \"Literal\",\n"
<< in << " \"literalType\": \"" << literalTypeToString(literalType) << "\",\n"
<< in << " \"value\": \"" << jsonEscape(val) << "\"";
if (literalType == LiteralType::INTEGER && literalBase != 10) {
ss << ",\n" << in << " \"base\": " << literalBase;
}
if (literalType == LiteralType::FLOAT) {
ss << ",\n" << in << " \"isFloat\": true";
}
ss << ",\n" << in << " \"location\": " << loc.toJson() << "\n"
<< in << "}";
return ss.str();
}

View File

@ -3,7 +3,7 @@
#include "parser/ast_node.hpp"
class LiteralNode : public ExpressionNode {
class LiteralNode : public ASTNode {
public:
Token* lexerToken = nullptr;
ParserToken parserToken;
@ -12,11 +12,6 @@ public:
int literalBase = 10;
bool isFloatValue = false;
// Sabit katlama (constant folding) tarafından üretilen sentetik literal.
// parserToken.token yerine bu değer kullanılır.
bool hasDirectValue = false;
int directIntValue = 0;
LiteralNode();
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;

View File

@ -13,7 +13,6 @@ std::string BlockNode::toJson(int depth) {
obj.addArray("children", [&]() {
for (auto* child : children) obj.addItem(child->toJson(depth + 2));
});
obj.add("isReachable", isReachable);
obj.addRaw("location", loc.toJson());
return obj.str();
}
@ -32,7 +31,6 @@ std::string IfStatementNode::toJson(int depth) {
if (condition) obj.addRaw("condition", condition->toJson(depth + 1));
if (thenBranch) obj.addRaw("then", thenBranch->toJson(depth + 1));
if (elseBranch) obj.addRaw("else", elseBranch->toJson(depth + 1));
obj.add("isReachable", isReachable);
obj.addRaw("location", loc.toJson());
return obj.str();
}
@ -49,7 +47,6 @@ std::string WhileStatementNode::toJson(int depth) {
obj.add("kind", "WhileStatement");
if (condition) obj.addRaw("condition", condition->toJson(depth + 1));
if (body) obj.addRaw("body", body->toJson(depth + 1));
obj.add("isReachable", isReachable);
obj.addRaw("location", loc.toJson());
return obj.str();
}
@ -70,7 +67,6 @@ std::string ForStatementNode::toJson(int depth) {
if (condition) obj.addRaw("condition", condition->toJson(depth + 1));
if (update) obj.addRaw("update", update->toJson(depth + 1));
if (body) obj.addRaw("body", body->toJson(depth + 1));
obj.add("isReachable", isReachable);
obj.addRaw("location", loc.toJson());
return obj.str();
}
@ -87,7 +83,6 @@ std::string DoWhileStatementNode::toJson(int depth) {
obj.add("kind", "DoWhileStatement");
if (condition) obj.addRaw("condition", condition->toJson(depth + 1));
if (body) obj.addRaw("body", body->toJson(depth + 1));
obj.add("isReachable", isReachable);
obj.addRaw("location", loc.toJson());
return obj.str();
}
@ -102,7 +97,6 @@ std::string ReturnStatementNode::toJson(int depth) {
JsonObject obj(depth);
obj.add("kind", "ReturnStatement");
if (value) obj.addRaw("value", value->toJson(depth + 1));
obj.add("isReachable", isReachable);
obj.addRaw("location", loc.toJson());
return obj.str();
}
@ -115,7 +109,6 @@ void BreakStatementNode::log(int indent) {
std::string BreakStatementNode::toJson(int depth) {
JsonObject obj(depth);
obj.add("kind", "BreakStatement");
obj.add("isReachable", isReachable);
obj.addRaw("location", loc.toJson());
return obj.str();
}
@ -128,7 +121,6 @@ void ContinueStatementNode::log(int indent) {
std::string ContinueStatementNode::toJson(int depth) {
JsonObject obj(depth);
obj.add("kind", "ContinueStatement");
obj.add("isReachable", isReachable);
obj.addRaw("location", loc.toJson());
return obj.str();
}
@ -143,40 +135,6 @@ std::string ExpressionStatementNode::toJson(int depth) {
JsonObject obj(depth);
obj.add("kind", "ExpressionStatement");
if (expression) obj.addRaw("expression", expression->toJson(depth + 1));
obj.add("isReachable", isReachable);
obj.addRaw("location", loc.toJson());
return obj.str();
}
// TryStatementNode (ADR-025)
TryStatementNode::TryStatementNode() { kind = ASTKind::TryStatement; }
void TryStatementNode::log(int indent) {
std::cout << jsonIndent(indent) << "TryStatement (catch " << catchVar << ")\n";
if (body) body->log(indent + 1);
if (handler) handler->log(indent + 1);
}
std::string TryStatementNode::toJson(int depth) {
JsonObject obj(depth);
obj.add("kind", "TryStatement");
obj.add("catchVar", catchVar);
if (body) obj.addRaw("body", body->toJson(depth + 1));
if (handler) obj.addRaw("handler", handler->toJson(depth + 1));
obj.add("isReachable", isReachable);
obj.addRaw("location", loc.toJson());
return obj.str();
}
// ThrowStatementNode (ADR-025)
ThrowStatementNode::ThrowStatementNode() { kind = ASTKind::ThrowStatement; }
void ThrowStatementNode::log(int indent) {
std::cout << jsonIndent(indent) << "ThrowStatement\n";
if (value) value->log(indent + 1);
}
std::string ThrowStatementNode::toJson(int depth) {
JsonObject obj(depth);
obj.add("kind", "ThrowStatement");
if (value) obj.addRaw("value", value->toJson(depth + 1));
obj.add("isReachable", isReachable);
obj.addRaw("location", loc.toJson());
return obj.str();
}

View File

@ -3,106 +3,78 @@
#include "parser/ast_node.hpp"
class BlockNode : public StatementNode {
class BlockNode : public ASTNode {
public:
BlockNode();
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class IfStatementNode : public StatementNode {
class IfStatementNode : public ASTNode {
public:
ASTNode* condition = nullptr;
ASTNode* thenBranch = nullptr;
ASTNode* elseBranch = nullptr;
IfStatementNode();
~IfStatementNode() override { delete condition; delete thenBranch; delete elseBranch; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class WhileStatementNode : public StatementNode {
class WhileStatementNode : public ASTNode {
public:
ASTNode* condition = nullptr;
ASTNode* body = nullptr;
WhileStatementNode();
~WhileStatementNode() override { delete condition; delete body; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class ForStatementNode : public StatementNode {
class ForStatementNode : public ASTNode {
public:
ASTNode* init = nullptr;
ASTNode* condition = nullptr;
ASTNode* update = nullptr;
ASTNode* body = nullptr;
ForStatementNode();
~ForStatementNode() override { delete init; delete condition; delete update; delete body; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class DoWhileStatementNode : public StatementNode {
class DoWhileStatementNode : public ASTNode {
public:
ASTNode* condition = nullptr;
ASTNode* body = nullptr;
DoWhileStatementNode();
~DoWhileStatementNode() override { delete body; delete condition; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class ReturnStatementNode : public StatementNode {
class ReturnStatementNode : public ASTNode {
public:
ASTNode* value = nullptr;
ReturnStatementNode();
~ReturnStatementNode() override { delete value; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class BreakStatementNode : public StatementNode {
class BreakStatementNode : public ASTNode {
public:
BreakStatementNode();
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class ContinueStatementNode : public StatementNode {
class ContinueStatementNode : public ASTNode {
public:
ContinueStatementNode();
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
class ExpressionStatementNode : public StatementNode {
class ExpressionStatementNode : public ASTNode {
public:
ASTNode* expression = nullptr;
ExpressionStatementNode();
~ExpressionStatementNode() override { delete expression; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
// ADR-025: try { body } catch (Error catchVar) { handler }
class TryStatementNode : public StatementNode {
public:
ASTNode* body = nullptr;
std::string catchVar; // catch değişken adı (ör. "e")
ASTNode* handler = nullptr;
TryStatementNode();
~TryStatementNode() override { delete body; delete handler; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};
// ADR-025: throw <ifade>;
class ThrowStatementNode : public StatementNode {
public:
ASTNode* value = nullptr;
ThrowStatementNode();
~ThrowStatementNode() override { delete value; }
void log(int indent = 0) override;
std::string toJson(int depth = 0) override;
};

View File

@ -63,13 +63,11 @@ ASTNode* Parser::parseProgram() {
ProgramNode* program = new ProgramNode();
while (currentToken().type != TokenType::SVR_VOID) {
int prevPos = current;
ASTNode* decl = parseDeclaration();
if (decl)
program->addChild(decl);
// İlerleme olmadıysa token atla — syntax hatasında sonsuz döngüyü önler
if (current == prevPos)
nextToken();
else
break;
}
return program;
@ -85,36 +83,14 @@ ASTNode* Parser::parseDeclaration() {
})) {
auto la1 = lookahead(1);
auto la2 = lookahead(2);
// int name( → fonksiyon
if (la1.type == TokenType::IDENTIFIER && la2.type == TokenType::LPAREN)
return parseFunctionDecl();
// int? name( → nullable dönüş tipli fonksiyon (ADR-021)
if (la1.type == TokenType::TERNARY) {
auto la3 = lookahead(3);
if (la2.type == TokenType::IDENTIFIER && la3.type == TokenType::LPAREN)
return parseFunctionDecl();
}
return parseVariableDecl();
}
if (ct.type == TokenType::KW_STRUCT)
return parseStructDecl();
// Kullanıcı tanımlı tip adı (struct tipi) ile değişken/fonksiyon bildirimi
if (ct.type == TokenType::IDENTIFIER) {
auto la1 = lookahead(1);
auto la2 = lookahead(2);
if (la1.type == TokenType::IDENTIFIER && la2.type == TokenType::LPAREN)
return parseFunctionDecl();
if (la1.type == TokenType::TERNARY) {
auto la3 = lookahead(3);
if (la2.type == TokenType::IDENTIFIER && la3.type == TokenType::LPAREN)
return parseFunctionDecl();
}
if (la1.type == TokenType::IDENTIFIER)
return parseVariableDecl();
}
return parseStatement();
}
@ -162,23 +138,6 @@ ASTNode* Parser::parseNullDenotation() {
return expr;
}
// Array literal: [expr, expr, ...]
if (ct.type == TokenType::LBRACKET) {
nextToken();
ArrayLiteralNode* arr = new ArrayLiteralNode();
arr->loc = ct.token ? ct.token->loc : SourceLocation{};
if (currentToken().type != TokenType::RBRACKET) {
arr->elements.push_back(parseExpression(0));
while (currentToken().type == TokenType::COMMA) {
nextToken();
arr->elements.push_back(parseExpression(0));
}
}
if (currentToken().type == TokenType::RBRACKET)
nextToken();
return arr;
}
if (ct.is({
TokenType::PLUS_PLUS, TokenType::MINUS_MINUS,
TokenType::PLUS, TokenType::MINUS,
@ -328,46 +287,14 @@ ASTNode* Parser::parseFunctionDecl() {
fn->returnType = currentToken().token->token;
nextToken();
// ADR-021: nullable dönüş tipi — int? f()
if (currentToken().type == TokenType::TERNARY)
{ nextToken(); fn->returnType += "?"; }
fn->name = currentToken().token->token;
nextToken();
if (currentToken().type == TokenType::LPAREN) {
nextToken();
while (currentToken().type != TokenType::RPAREN &&
currentToken().type != TokenType::SVR_VOID) {
auto typeTok = currentToken();
bool isTypeKw = typeTok.is({
TokenType::KW_VOID, TokenType::KW_INT, TokenType::KW_FLOAT_TYPE,
TokenType::KW_DOUBLE, TokenType::KW_BOOL, TokenType::KW_CHAR,
TokenType::KW_STRING_TYPE, TokenType::KW_AUTO
}) || typeTok.type == TokenType::IDENTIFIER;
if (!isTypeKw || !typeTok.token) break;
std::string paramType = typeTok.token->token;
currentToken().type != TokenType::SVR_VOID)
nextToken();
// int[] a — tip sonrasında [] varsa array tipi
if (currentToken().type == TokenType::LBRACKET) {
nextToken();
if (currentToken().type == TokenType::RBRACKET)
nextToken();
paramType += "[]";
}
// ADR-021: nullable parametre — int? a
if (currentToken().type == TokenType::TERNARY)
{ nextToken(); paramType += "?"; }
if (currentToken().type != TokenType::IDENTIFIER || !currentToken().token) break;
VariableDeclNode* param = new VariableDeclNode();
param->loc = currentToken().token->loc;
param->varType = paramType;
param->name = currentToken().token->token;
nextToken();
fn->params.push_back(param);
if (currentToken().type == TokenType::COMMA)
nextToken();
}
if (currentToken().type == TokenType::RPAREN)
nextToken();
}
@ -407,18 +334,6 @@ ASTNode* Parser::parseVariableDecl() {
vd->varType = currentToken().token->token;
nextToken();
// Java/C# stili: int[] x — tip adından hemen sonra [] gelir
if (currentToken().type == TokenType::LBRACKET) {
nextToken();
if (currentToken().type == TokenType::RBRACKET)
nextToken();
vd->varType += "[]";
}
// ADR-021: nullable soneki — int? x
if (currentToken().type == TokenType::TERNARY)
{ nextToken(); vd->varType += "?"; }
if (currentToken().type != TokenType::IDENTIFIER) {
std::cerr << "Parser hatası: değişken ismi bekleniyor\n";
return vd;
@ -427,7 +342,6 @@ ASTNode* Parser::parseVariableDecl() {
vd->name = currentToken().token->token;
nextToken();
// C stili: int x[] — geriye dönük uyumluluk (postfix [])
if (currentToken().type == TokenType::LBRACKET) {
nextToken();
while (currentToken().type != TokenType::RBRACKET &&
@ -436,7 +350,6 @@ ASTNode* Parser::parseVariableDecl() {
nextToken();
if (currentToken().type == TokenType::RBRACKET)
nextToken();
if (vd->varType.back() != ']') vd->varType += "[]";
}
if (currentToken().type == TokenType::EQUAL) {
@ -509,12 +422,6 @@ ASTNode* Parser::parseStatement() {
if (ct.type == TokenType::KW_CONTINUE)
return parseContinueStatement();
if (ct.type == TokenType::KW_TRY)
return parseTryStatement();
if (ct.type == TokenType::KW_THROW)
return parseThrowStatement();
if (ct.is({
TokenType::KW_VOID, TokenType::KW_INT, TokenType::KW_FLOAT_TYPE,
TokenType::KW_DOUBLE, TokenType::KW_BOOL, TokenType::KW_CHAR,
@ -526,15 +433,6 @@ ASTNode* Parser::parseStatement() {
if (ct.type == TokenType::KW_STRUCT)
return parseStructDecl();
// Kullanıcı tanımlı struct tipiyle değişken bildirimi: Point p; veya Point p = ...;
if (ct.type == TokenType::IDENTIFIER) {
auto la1 = lookahead(1);
// "TypeName varName" veya "TypeName varName = ..." → değişken bildirimi
// (TypeName LPAREN → ifade; o durumda parseExpressionStatement devam eder)
if (la1.type == TokenType::IDENTIFIER)
return parseVariableDecl();
}
return parseExpressionStatement();
}
@ -699,43 +597,3 @@ ASTNode* Parser::parseExpressionStatement() {
return es;
}
// ADR-025: try { body } catch (Error catchVar) { handler }
ASTNode* Parser::parseTryStatement() {
TryStatementNode* ts = new TryStatementNode();
ts->loc = currentToken().token->loc;
nextToken(); // tüket: try
ts->body = parseBlock();
// catch (Error e)
if (currentToken().type == TokenType::KW_CATCH) {
nextToken(); // tüket: catch
if (currentToken().type == TokenType::LPAREN)
nextToken(); // tüket: (
// "Error" tip adını atla
if (currentToken().type == TokenType::IDENTIFIER ||
currentToken().type == TokenType::KW_STRING_TYPE)
nextToken(); // tüket: Error (ya da herhangi bir tip adı)
// catch değişken adını al
if (currentToken().type == TokenType::IDENTIFIER && currentToken().token)
ts->catchVar = currentToken().token->token;
nextToken(); // tüket: değişken adı
if (currentToken().type == TokenType::RPAREN)
nextToken(); // tüket: )
ts->handler = parseBlock();
}
return ts;
}
// ADR-025: throw <ifade>;
ASTNode* Parser::parseThrowStatement() {
ThrowStatementNode* th = new ThrowStatementNode();
th->loc = currentToken().token->loc;
nextToken(); // tüket: throw
th->value = parseExpression();
if (currentToken().type == TokenType::SEMICOLON)
nextToken();
return th;
}

View File

@ -51,8 +51,6 @@ private:
ASTNode* parseBreakStatement();
ASTNode* parseContinueStatement();
ASTNode* parseExpressionStatement();
ASTNode* parseTryStatement();
ASTNode* parseThrowStatement();
// --- İfadeler (Pratt parser) ---
ASTNode* parseExpression();

View File

@ -1,95 +0,0 @@
#include "semantic/structural_validator.hpp"
#include "parser/nodes/declarations.hpp"
#include "parser/nodes/statements.hpp"
void StructuralValidator::validate(ASTNode* program) {
if (!program) return;
for (ASTNode* child : program->getChildren())
walkDecl(child);
}
void StructuralValidator::walkDecl(ASTNode* node) {
if (!node) return;
if (node->kind == ASTKind::FunctionDecl) {
auto* fn = (FunctionDeclNode*)node;
inFunction_ = true;
auto& ch = fn->getChildren();
if (!ch.empty()) walkStmt(ch[0]);
inFunction_ = false;
}
// VariableDecl / StructDecl: yapısal kural yok
}
void StructuralValidator::walkStmt(ASTNode* node) {
if (!node) return;
switch (node->kind) {
case ASTKind::Block:
for (ASTNode* child : node->getChildren()) walkStmt(child);
break;
case ASTKind::IfStatement: {
auto* ifn = (IfStatementNode*)node;
if (ifn->thenBranch) walkStmt(ifn->thenBranch);
if (ifn->elseBranch) walkStmt(ifn->elseBranch);
break;
}
case ASTKind::WhileStatement: {
auto* ws = (WhileStatementNode*)node;
loopDepth_++;
if (ws->body) walkStmt(ws->body);
loopDepth_--;
break;
}
case ASTKind::DoWhileStatement: {
auto* dw = (DoWhileStatementNode*)node;
loopDepth_++;
if (dw->body) walkStmt(dw->body);
loopDepth_--;
break;
}
case ASTKind::ForStatement: {
auto* fs = (ForStatementNode*)node;
loopDepth_++;
if (fs->init) walkStmt(fs->init);
if (fs->body) walkStmt(fs->body);
loopDepth_--;
break;
}
case ASTKind::BreakStatement:
if (loopDepth_ == 0)
diag_.report("E004", node->loc,
"'break' döngü dışında kullanılamaz");
break;
case ASTKind::ContinueStatement:
if (loopDepth_ == 0)
diag_.report("E004", node->loc,
"'continue' döngü dışında kullanılamaz");
break;
case ASTKind::ReturnStatement:
if (!inFunction_)
diag_.report("E005", node->loc,
"'return' fonksiyon dışında kullanılamaz");
break;
case ASTKind::VariableDecl: {
// sibling'leri de gez
for (ASTNode* sib : node->getChildren())
if (sib->kind == ASTKind::VariableDecl) walkStmt(sib);
break;
}
case ASTKind::ExpressionStatement:
break; // ifade içinde return/break olamaz
default:
break;
}
}

View File

@ -1,22 +0,0 @@
#ifndef SAQUT_SEMANTIC_STRUCTURAL_VALIDATOR
#define SAQUT_SEMANTIC_STRUCTURAL_VALIDATOR
#include "diagnostic/diagnostic_engine.hpp"
#include "parser/ast_node.hpp"
class StructuralValidator {
public:
explicit StructuralValidator(DiagnosticEngine& diag) : diag_(diag) {}
void validate(ASTNode* program);
private:
void walkDecl(ASTNode* node);
void walkStmt(ASTNode* node);
DiagnosticEngine& diag_;
int loopDepth_ = 0;
bool inFunction_ = false;
};
#endif // SAQUT_SEMANTIC_STRUCTURAL_VALIDATOR

View File

@ -1,572 +0,0 @@
#include "semantic/type_checker.hpp"
#include "parser/nodes/program.hpp"
#include "parser/nodes/declarations.hpp"
#include "parser/nodes/statements.hpp"
#include "parser/nodes/expressions.hpp"
#include "parser/nodes/binary_expr.hpp"
#include "parser/nodes/identifier.hpp"
#include "parser/nodes/literal.hpp"
// ─────────────────────────────────────────────────────────────────────────────
// Yardımcılar
// ─────────────────────────────────────────────────────────────────────────────
int TypeChecker::numericRank(const Type& t) {
if (!t.isPrimitive()) return -1;
switch (t.prim) {
case PrimitiveKind::Int: return 0;
case PrimitiveKind::Float: return 1;
case PrimitiveKind::Double: return 2;
default: return -1;
}
}
// ADR-021: "a != null" / "a == null" kalıbını ayrıştır
// Dönüş: {varName, isNotNull} — varName boşsa kalıp tanınmadı.
std::pair<std::string, bool> TypeChecker::extractNullCheck(ASTNode* cond) {
if (!cond || cond->kind != ASTKind::BinaryExpression) return {"", false};
auto* bin = (BinaryExpressionNode*)cond;
bool isNE = (bin->Operator == TokenType::BANG_EQUAL);
bool isEE = (bin->Operator == TokenType::EQUAL_EQUAL);
if (!isNE && !isEE) return {"", false};
// Hangi taraf null literal?
auto isNullLit = [](ASTNode* n) -> bool {
if (!n || n->kind != ASTKind::Literal) return false;
return ((LiteralNode*)n)->literalType == LiteralType::BOŞ;
};
auto identName = [](ASTNode* n) -> std::string {
if (!n || n->kind != ASTKind::Identifier) return "";
auto* id = (IdentifierNode*)n;
return id->parserToken.token ? id->parserToken.token->token : "";
};
std::string var;
if (isNullLit(bin->Right)) var = identName(bin->Left);
else if (isNullLit(bin->Left)) var = identName(bin->Right);
if (var.empty()) return {"", false};
return {var, isNE}; // isNE=true → "a != null"; false → "a == null"
}
// ADR-021: guard pattern — bu statement her zaman çıkış yapıyor mu?
bool TypeChecker::alwaysExits(ASTNode* stmt) {
if (!stmt) return false;
switch (stmt->kind) {
case ASTKind::ReturnStatement:
case ASTKind::ThrowStatement:
case ASTKind::BreakStatement:
case ASTKind::ContinueStatement:
return true;
case ASTKind::Block: {
auto& ch = stmt->getChildren();
return !ch.empty() && alwaysExits(ch.back());
}
default: return false;
}
}
// ─────────────────────────────────────────────────────────────────────────────
// check — giriş noktası
// ─────────────────────────────────────────────────────────────────────────────
void TypeChecker::check(ASTNode* program) {
if (!program) return;
for (ASTNode* child : program->getChildren()) {
switch (child->kind) {
case ASTKind::FunctionDecl: checkFunction(child); break;
case ASTKind::VariableDecl: checkStmt(child); break;
default: break;
}
}
}
// ─────────────────────────────────────────────────────────────────────────────
// checkFunction
// ─────────────────────────────────────────────────────────────────────────────
void TypeChecker::checkFunction(ASTNode* fnNode) {
auto* fn = (FunctionDeclNode*)fnNode;
inFunction_ = true;
currentReturnType_ = Type::fromName(fn->returnType);
if (currentReturnType_.isError() && fn->returnType != "void")
currentReturnType_ = Type::Void(); // bilinmeyen dönüş tipi → void gibi davran
auto& ch = fn->getChildren();
if (!ch.empty()) checkStmt(ch[0]); // body Block
inFunction_ = false;
}
// ─────────────────────────────────────────────────────────────────────────────
// checkAssign — atama uyumu + uyarı/hata raporlama
// ─────────────────────────────────────────────────────────────────────────────
bool TypeChecker::checkAssign(const Type& target, const Type& src,
bool srcIsLiteral,
const SourceLocation& loc,
const std::string& ctx) {
if (target.isError() || src.isError()) return true; // önceki hata, sessiz geç
// ADR-021: null literal ataması
if (src.isNullLiteral()) {
if (target.nullable) return true; // T? ← null → OK
diag_.report("E003", loc,
"'" + ctx + "': null non-null tipine (" + target.toString() + ") atanamaz");
return false;
}
// ADR-021: nullable uyumu
// T? ← T → OK (widening: non-null, nullable'a gider)
// T ← T? → E (narrowing: nullable, non-null'a gidemez; narrowing gerekli)
if (src.nullable && !target.nullable && src.equalsBase(target)) {
diag_.report("E003", loc,
"'" + ctx + "': " + src.toString() +
" nullable tipi non-null " + target.toString() + " tipine atanamaz"
" (if ile null kontrolü yapın)");
return false;
}
// T? ← T → OK (equalsBase eşleşiyorsa, nullable farkı widening)
if (!src.nullable && target.nullable && src.equalsBase(target)) return true;
if (target.equals(src)) return true;
int tRank = numericRank(target);
int sRank = numericRank(src);
if (tRank >= 0 && sRank >= 0) {
if (tRank > sRank) {
if (srcIsLiteral) return true;
diag_.report("W004", loc,
"'" + ctx + "': " + src.toString() +
"" + target.toString() + " örtük genişletme");
return true;
} else {
diag_.report("E003", loc,
"'" + ctx + "': " + src.toString() +
"" + target.toString() + " daraltma (veri kaybı)");
return false;
}
}
diag_.report("E003", loc,
"'" + ctx + "': " + src.toString() +
" tipi " + target.toString() + " tipine atanamaz");
return false;
}
// ─────────────────────────────────────────────────────────────────────────────
// checkStmt
// ─────────────────────────────────────────────────────────────────────────────
void TypeChecker::checkStmt(ASTNode* node) {
if (!node) return;
switch (node->kind) {
case ASTKind::Block: {
// ADR-021: guard/sıralı narrowing — if (a == null) return; → sonrasında a non-null
std::vector<std::string> guardNarrowed; // bu blokta guard'la daraltılanlar
for (ASTNode* child : node->getChildren()) {
checkStmt(child);
// guard kontrolü: if (a == null) { return/throw/break/continue; }
if (child->kind == ASTKind::IfStatement) {
auto* ifn = (IfStatementNode*)child;
if (!ifn->elseBranch && ifn->thenBranch && alwaysExits(ifn->thenBranch)) {
auto [var, isNotNull] = extractNullCheck(ifn->condition);
if (!var.empty() && !isNotNull) { // "a == null" → guard
narrowedNonNull_.insert(var);
guardNarrowed.push_back(var);
}
}
}
}
for (auto& v : guardNarrowed) narrowedNonNull_.erase(v);
break;
}
case ASTKind::VariableDecl: {
auto* vd = (VariableDeclNode*)node;
Type targetType = Type::fromName(vd->varType);
if (targetType.isError() && table_.structLayouts.count(vd->varType))
targetType = Type::structType(vd->varType);
if (vd->initExpr) {
Type srcType = checkExpr(vd->initExpr, targetType);
bool isLit = vd->initExpr->kind == ASTKind::Literal;
checkAssign(targetType, srcType, isLit, vd->loc, vd->name);
}
// sibling VariableDecl'ler (int a, b;)
for (ASTNode* sib : vd->getChildren()) {
if (sib->kind == ASTKind::VariableDecl) checkStmt(sib);
}
break;
}
case ASTKind::ExpressionStatement: {
auto* es = (ExpressionStatementNode*)node;
if (es->expression) checkExpr(es->expression);
break;
}
case ASTKind::ReturnStatement: {
auto* rs = (ReturnStatementNode*)node;
if (!rs->value) {
if (inFunction_ && !currentReturnType_.isVoid())
diag_.report("E006", rs->loc,
"Değersiz return; fonksiyon " +
currentReturnType_.toString() + " döndürmeli");
break;
}
Type valType = checkExpr(rs->value, currentReturnType_);
bool isLit = rs->value->kind == ASTKind::Literal;
checkAssign(currentReturnType_, valType, isLit, rs->loc, "return");
break;
}
case ASTKind::IfStatement: {
auto* ifn = (IfStatementNode*)node;
if (ifn->condition) checkExpr(ifn->condition);
// ADR-021: nested narrowing — if (a != null) { a non-null } else { a null }
auto [narrowVar, isNotNull] = extractNullCheck(ifn->condition);
if (!narrowVar.empty() && isNotNull) // "a != null" → then'de non-null
narrowedNonNull_.insert(narrowVar);
if (ifn->thenBranch) checkStmt(ifn->thenBranch);
if (!narrowVar.empty() && isNotNull)
narrowedNonNull_.erase(narrowVar);
if (!narrowVar.empty() && !isNotNull) // "a == null" → else'de non-null
narrowedNonNull_.insert(narrowVar);
if (ifn->elseBranch) checkStmt(ifn->elseBranch);
if (!narrowVar.empty() && !isNotNull)
narrowedNonNull_.erase(narrowVar);
break;
}
case ASTKind::WhileStatement: {
auto* ws = (WhileStatementNode*)node;
if (ws->condition) checkExpr(ws->condition);
if (ws->body) checkStmt(ws->body);
break;
}
case ASTKind::ForStatement: {
auto* fs = (ForStatementNode*)node;
if (fs->init) {
if (fs->init->kind == ASTKind::VariableDecl) checkStmt(fs->init);
else checkExpr(fs->init);
}
if (fs->condition) checkExpr(fs->condition);
if (fs->update) checkExpr(fs->update);
if (fs->body) checkStmt(fs->body);
break;
}
case ASTKind::DoWhileStatement: {
auto* dw = (DoWhileStatementNode*)node;
if (dw->body) checkStmt(dw->body);
if (dw->condition) checkExpr(dw->condition);
break;
}
case ASTKind::BreakStatement:
case ASTKind::ContinueStatement:
break; // yapısal doğrulama StructuralValidator'ın işi
// ADR-025: try { body } catch (Error e) { handler }
case ASTKind::TryStatement: {
auto* ts = (TryStatementNode*)node;
if (ts->body) checkStmt(ts->body);
if (ts->handler) checkStmt(ts->handler);
break;
}
// ADR-025: throw <ifade>; — unchecked, herhangi bir değer atılabilir
case ASTKind::ThrowStatement: {
auto* th = (ThrowStatementNode*)node;
if (th->value) checkExpr(th->value);
break;
}
default:
break;
}
}
// ─────────────────────────────────────────────────────────────────────────────
// checkExpr — tip çıkarımı + resolvedType ataması
// ─────────────────────────────────────────────────────────────────────────────
Type TypeChecker::checkExpr(ASTNode* node, const Type& expected) {
if (!node) return Type::error();
Type result = Type::error();
switch (node->kind) {
// ── Literal ────────────────────────────────────────────────────────────
case ASTKind::Literal: {
auto* lit = (LiteralNode*)node;
int expRank = numericRank(expected);
switch (lit->literalType) {
case LiteralType::INTEGER:
// Bağlam daha geniş sayısal tip ise literal o tip olarak tiplenir.
if (expRank > 0) result = expected; // float veya double bekleniyor
else result = Type::Int();
break;
case LiteralType::FLOAT:
// float literal → double bağlamında double olur; int bağlamında E003.
if (!expected.isError() && expected.equals(Type::Double()))
result = Type::Double();
else if (!expected.isError() && numericRank(expected) == 0) {
// int bekleniyor ama float literal: E003
diag_.report("E003", lit->loc,
"Float literal int bağlamında kullanılamaz (veri kaybı)");
result = Type::error();
} else {
result = Type::Float();
}
break;
case LiteralType::BOOLEAN: result = Type::Bool(); break;
case LiteralType::STRING: result = Type::String(); break;
case LiteralType::BOŞ:
// null literal: bağlam nullable ise o tip, değilse Void+nullable (null sentinel)
if (!expected.isError() && expected.nullable)
result = expected;
else
result = Type::Void().asNullable(); // null sentinel
break;
default: result = Type::error(); break;
}
break;
}
// ── Identifier ─────────────────────────────────────────────────────────
case ASTKind::Identifier: {
auto* id = (IdentifierNode*)node;
result = id->resolvedSymbol ? id->resolvedSymbol->type : Type::error();
// ADR-021: narrowing — bu değişken null kontrolünden geçtiyse non-null say
if (result.nullable && id->parserToken.token) {
std::string name = id->parserToken.token->token;
if (narrowedNonNull_.count(name))
result = result.asNonNull();
}
break;
}
// ── BinaryExpression ───────────────────────────────────────────────────
case ASTKind::BinaryExpression: {
auto* bin = (BinaryExpressionNode*)node;
// Atama operatörleri
if (bin->Operator == TokenType::EQUAL ||
bin->Operator == TokenType::PLUS_EQUAL ||
bin->Operator == TokenType::MINUS_EQUAL ||
bin->Operator == TokenType::STAR_EQUAL ||
bin->Operator == TokenType::SLASH_EQUAL ||
bin->Operator == TokenType::PERCENT_EQUAL) {
Type leftType = checkExpr(bin->Left);
Type rightType = checkExpr(bin->Right, leftType);
bool isLit = bin->Right && bin->Right->kind == ASTKind::Literal;
checkAssign(leftType, rightType, isLit, bin->loc, "atama");
result = leftType;
break;
}
// Unary (Left = nullptr): -, +, !, ~
if (!bin->Left) {
Type rightType = checkExpr(bin->Right);
if (bin->Operator == TokenType::BANG) {
result = Type::Bool();
} else {
result = rightType.isNumeric() ? rightType : Type::error();
if (result.isError() && !rightType.isError())
diag_.report("E003", bin->loc, "Sayısal olmayan operand");
}
break;
}
Type leftType = checkExpr(bin->Left);
// ADR-021: && kısa-devre sağ taraf narrowing — "a != null && a.field"
if (bin->Operator == TokenType::AMPERSAND_AMPERSAND) {
auto [narrowVar, isNotNull] = extractNullCheck(bin->Left);
if (!narrowVar.empty() && isNotNull)
narrowedNonNull_.insert(narrowVar);
checkExpr(bin->Right);
if (!narrowVar.empty() && isNotNull)
narrowedNonNull_.erase(narrowVar);
result = Type::Bool();
break;
}
Type rightType = checkExpr(bin->Right);
// Mantıksal (||)
if (bin->Operator == TokenType::PIPE_PIPE) {
result = Type::Bool();
break;
}
// Eşitlik karşılaştırması: string dahil herhangi tiple çalışır
if (bin->Operator == TokenType::EQUAL_EQUAL ||
bin->Operator == TokenType::BANG_EQUAL) {
result = Type::Bool();
break;
}
// Sıralama karşılaştırması: YALNIZCA sayısal tipler
if (bin->Operator == TokenType::LESS ||
bin->Operator == TokenType::LESS_EQUAL ||
bin->Operator == TokenType::GREATER ||
bin->Operator == TokenType::GREATER_EQUAL) {
if (leftType.isError() || rightType.isError()) {
result = Type::error(); // önceki hata, sessiz geç
} else if (leftType.isNumeric() && rightType.isNumeric()) {
result = Type::Bool();
} else {
diag_.report("E003", bin->loc,
"Sıralama operatörü yalnızca sayısal tiplerle kullanılabilir: " +
leftType.toString() +
" — string için yalnızca == ve != kullanın");
result = Type::error();
}
break;
}
// ADR-021: katı operand kuralı — non-null bağlamda nullable operand yasak
// (eşitlik / null karşılaştırmaları için geçerli değil)
if (!leftType.isError() && !rightType.isError() &&
(leftType.nullable || rightType.nullable)) {
diag_.report("E003", bin->loc,
"Nullable operand: '" + leftType.toString() + "' ve '" +
rightType.toString() + "' — null kontrolü yapın veya daraltın");
result = Type::error();
break;
}
// String birleştirme: yalnızca + operatörü (ADR-024)
if (bin->Operator == TokenType::PLUS &&
leftType.isString() && rightType.isString()) {
result = Type::String();
break;
}
// Aritmetik: +, -, *, /, %
int lRank = numericRank(leftType);
int rRank = numericRank(rightType);
if (lRank >= 0 && rRank >= 0) {
// Aynı tip veya otomatik genişletme; sonuç daha geniş tip.
result = (lRank >= rRank) ? leftType : rightType;
} else if (!leftType.isError() && !rightType.isError()) {
diag_.report("E003", bin->loc,
"Aritmetik operatör sayısal olmayan tip: " +
leftType.toString() + " ve " + rightType.toString());
result = Type::error();
} else {
result = Type::error();
}
break;
}
// ── Call ───────────────────────────────────────────────────────────────
case ASTKind::Call: {
auto* call = (CallExpressionNode*)node;
Type calleeType = checkExpr(call->callee);
if (!calleeType.isFunction()) {
if (!calleeType.isError())
diag_.report("E003", call->loc,
"Çağrılabilir değil: " + calleeType.toString());
result = Type::error();
// Argümanları yine de gez (cascade hatayı önle)
for (auto* arg : call->arguments) checkExpr(arg);
break;
}
// Argüman sayısı kontrolü — builtin print hariç (paramTypes boş = değişken arity)
if (!calleeType.paramTypes.empty()) {
size_t expected_count = calleeType.paramTypes.size();
size_t got_count = call->arguments.size();
if (got_count != expected_count) {
diag_.report("E008", call->loc,
std::to_string(expected_count) + " argüman bekleniyor, " +
std::to_string(got_count) + " verildi");
}
}
// Argüman tiplerini kontrol et
for (size_t i = 0; i < call->arguments.size(); ++i) {
Type paramType = (i < calleeType.paramTypes.size())
? calleeType.paramTypes[i]
: Type::error();
Type argType = checkExpr(call->arguments[i], paramType);
bool isLit = call->arguments[i]->kind == ASTKind::Literal;
if (!paramType.isError())
checkAssign(paramType, argType, isLit,
call->arguments[i]->loc, "argüman");
}
result = calleeType.returnType ? *calleeType.returnType : Type::Void();
break;
}
// ── Postfix ++/-- ──────────────────────────────────────────────────────
case ASTKind::Postfix: {
auto* pf = (PostfixNode*)node;
Type opType = checkExpr(pf->operand);
if (!opType.isNumeric() && !opType.isError())
diag_.report("E003", pf->loc,
"++ / -- sayısal olmayan tip: " + opType.toString());
result = opType;
break;
}
// ── MemberAccess / IndexExpression ─────────────────────────────────────
case ASTKind::MemberAccess: {
auto* ma = (MemberAccessNode*)node;
Type objType = checkExpr(ma->object);
// ADR-021: nullable nesne üstünde doğrudan alan erişimi yasak
if (objType.nullable) {
diag_.report("E003", node->loc,
"Nullable tip '" + objType.toString() + "' üstünde doğrudan erişim"
" — if ile null kontrolü yapın");
result = Type::error();
break;
}
if (objType.isStruct()) {
result = table_.getFieldType(objType.structName, ma->member);
if (result.isError())
diag_.report("E001", node->loc,
"'" + objType.structName + "' struct'ında '" + ma->member + "' alanı yok");
} else {
result = Type::error();
}
break;
}
case ASTKind::IndexExpression: {
auto* ie = (IndexExpressionNode*)node;
Type objType = checkExpr(ie->object);
if (ie->index) checkExpr(ie->index);
// array eleman tipi
if (objType.isArray() && objType.elementType)
result = *objType.elementType;
else
result = Type::Int(); // varsayılan (tip çıkarımı tam değil)
break;
}
default:
result = Type::error();
break;
}
// resolvedType'a yaz (ExpressionNode'dan türeyen tüm node'lar için)
if (auto* exprNode = dynamic_cast<ExpressionNode*>(node))
exprNode->resolvedType = result;
return result;
}

View File

@ -1,52 +0,0 @@
#ifndef SAQUT_SEMANTIC_TYPE_CHECKER
#define SAQUT_SEMANTIC_TYPE_CHECKER
#include <unordered_set>
#include <string>
#include "symbol/symbol_table.hpp"
#include "diagnostic/diagnostic_engine.hpp"
#include "parser/ast_node.hpp"
#include "core/type.hpp"
class TypeChecker {
public:
TypeChecker(SymbolTable& table, DiagnosticEngine& diag)
: table_(table), diag_(diag) {}
void check(ASTNode* program);
private:
// İfadeyi gez, resolvedType ata, tipi döndür.
// expected: bağlam tipi — literal genişletme kararı için.
Type checkExpr(ASTNode* node, const Type& expected = Type::error());
void checkStmt(ASTNode* node);
void checkFunction(ASTNode* fnNode);
// Atama / parametre uyumu: true = geçerli (uyarı dahil).
// srcIsLiteral: RHS doğrudan bir Literal node'u mu?
bool checkAssign(const Type& target, const Type& src,
bool srcIsLiteral,
const SourceLocation& loc,
const std::string& context);
// İki sayısal tipin genişlik sırası: int=0, float=1, double=2; -1 = sayısal değil.
static int numericRank(const Type& t);
// ADR-021: if-narrowing — null kontrolü kalıbını ayrıştır
// Dönüş: {varName, isNotNull} — "a != null" → {a, true}; "a == null" → {a, false}; {"", _} = kalıp yok
static std::pair<std::string, bool> extractNullCheck(ASTNode* cond);
// Bir statement her zaman çıkış yapıyor mu? (return/throw/break/continue)
static bool alwaysExits(ASTNode* stmt);
SymbolTable& table_;
DiagnosticEngine& diag_;
Type currentReturnType_; // aktif fonksiyonun beklenen dönüş tipi
bool inFunction_ = false;
// ADR-021: akış-duyarlı null daraltma — bu kapsamda non-null olduğu bilinen değişkenler
std::unordered_set<std::string> narrowedNonNull_;
};
#endif // SAQUT_SEMANTIC_TYPE_CHECKER

View File

@ -1,37 +0,0 @@
#ifndef SAQUT_SYMBOL_SCOPE
#define SAQUT_SYMBOL_SCOPE
#include <unordered_map>
#include <vector>
#include "symbol/symbol.hpp"
class Scope {
public:
Scope* parent = nullptr;
explicit Scope(Scope* p = nullptr) : parent(p) {}
// Bu scope'a ekle. Aynı adda varsa nullptr (duplicate → çağıran E002 verir).
Symbol* defineLocal(Symbol* s) {
if (table.count(s->name)) return nullptr;
table[s->name] = s;
order.push_back(s);
s->scope = this;
return s;
}
Symbol* lookupLocal(const std::string& n) {
auto it = table.find(n);
return it == table.end() ? nullptr : it->second;
}
Symbol* resolve(const std::string& n) {
for (Scope* s = this; s; s = s->parent)
if (auto* r = s->lookupLocal(n)) return r;
return nullptr;
}
std::unordered_map<std::string, Symbol*> table; // non-owning
std::vector<Symbol*> order; // ekleme sırası
};
#endif // SAQUT_SYMBOL_SCOPE

Some files were not shown because too many files have changed in this diff Show More