Compare commits
100 Commits
feature/fr
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
fe8d73a13c | |
|
|
786812c717 | |
|
|
996868efeb | |
|
|
435c8bcb96 | |
|
|
f1cb983b69 | |
|
|
c5f62a3a9d | |
|
|
ec61290e68 | |
|
|
91fd64d06a | |
|
|
34447d082e | |
|
|
3c31f606d6 | |
|
|
808efc5b4a | |
|
|
4fedcc1bde | |
|
|
d0ef368849 | |
|
|
04465afaef | |
|
|
326a8d8950 | |
|
|
2d641863d8 | |
|
|
4accdf8484 | |
|
|
77bcd1c9d6 | |
|
|
636bfcc6d5 | |
|
|
e5e0cdb2b3 | |
|
|
f69654bbca | |
|
|
06e4136705 | |
|
|
a4fb3cfc4f | |
|
|
7c93f12304 | |
|
|
450f16008f | |
|
|
8509d09ca8 | |
|
|
c5fb57412a | |
|
|
98bf8385d2 | |
|
|
ab47e42954 | |
|
|
913b42026c | |
|
|
ac96ad810c | |
|
|
85d955ec62 | |
|
|
698d03f4dd | |
|
|
d51e48dbb2 | |
|
|
0bcdabab8a | |
|
|
3d5912f991 | |
|
|
d5cdc00682 | |
|
|
044655d675 | |
|
|
36ad5d0db5 | |
|
|
b6e4d75bde | |
|
|
6b3631bbb6 | |
|
|
580f9f8c5f | |
|
|
dbe49f909d | |
|
|
539e08e521 | |
|
|
0b3f14e4d7 | |
|
|
a4bd5110b3 | |
|
|
62280cd530 | |
|
|
7c7f886e9c | |
|
|
214ecadf21 | |
|
|
9b486942c0 | |
|
|
e488f29c23 | |
|
|
8453dcd796 | |
|
|
490db7ca31 | |
|
|
2b9888c021 | |
|
|
68a9e07f8e | |
|
|
aa4d9fb8c2 | |
|
|
ecaba688ae | |
|
|
e84828b631 | |
|
|
999edaeaa9 | |
|
|
b071dab54c | |
|
|
9227b92549 | |
|
|
dc41a5df59 | |
|
|
1923524056 | |
|
|
e223995f20 | |
|
|
a37f6b0ff1 | |
|
|
ba08bf4511 | |
|
|
c8ee926912 | |
|
|
ea5bcee490 | |
|
|
68d52d744d | |
|
|
6b5a67343b | |
|
|
482fe14a45 | |
|
|
f3358473ac | |
|
|
1c5178168e | |
|
|
63ad3e2dcf | |
|
|
71c67317c4 | |
|
|
cbc7a3ddb5 | |
|
|
dc37b69b67 | |
|
|
e2a82f9bb9 | |
|
|
389a40a98e | |
|
|
dae55d5907 | |
|
|
051354befa | |
|
|
df5bb6187f | |
|
|
11a64d637d | |
|
|
1859cea9a1 | |
|
|
1232748f9f | |
|
|
a554d83238 | |
|
|
cf6f706449 | |
|
|
3e459bde64 | |
|
|
f7467f18b3 | |
|
|
5e51c55773 | |
|
|
b986f0cb26 | |
|
|
7c5a86c39b | |
|
|
3f6c2ee4c9 | |
|
|
93cbc7db3a | |
|
|
0a15cfe706 | |
|
|
0fbe742de0 | |
|
|
12356d8a73 | |
|
|
6948384134 | |
|
|
d9db17c732 | |
|
|
d4d912f01e |
|
|
@ -9,3 +9,12 @@ 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/*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,160 @@
|
|||
# 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):** açı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 0–4 → 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):**
|
||||
- **#69–73** `faz-plani` — Faz 0–4 (Tip+Diagnostic, AST refactor, Symbol Table,
|
||||
Semantik Analiz, Optimizasyon). Format: Giriş/Gelişme/Sonuç-Başarı Kriterleri +
|
||||
mühendis-olmayan analiz.
|
||||
- **#74–98, #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).
|
||||
- **#99–105** `test-senaryosu` — kaynak kod + beklenen çıktı içeren golden-test'ler.
|
||||
- **#106–110** `cli-ux`/`kalite-mimari` — CLI fikirleri, C/Java/Go tarzı tavsiyeler.
|
||||
- LSP (#91) ve CLI (#107) **Tier 0–4** katmanlı yetenek haritası olarak yazıldı;
|
||||
#111 ekosistem bağımlılık sırası.
|
||||
|
||||
## Lisans (LICENSE.md — bu oturumda yeniden yazıldı)
|
||||
- **Model:** "Kaynağı Açı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.
|
||||
|
|
@ -20,3 +20,99 @@ 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()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,234 @@
|
|||
## 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ğı Açı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ğı açı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ı açı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.
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
# 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.
|
||||
|
||||
Açı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.
|
|
@ -1,60 +1,34 @@
|
|||
# ninja log v7
|
||||
0 1451 1779867877701788943 CMakeFiles/saqut.dir/src/core/sourcefile.cpp.o da6f5fc90e87e6b1
|
||||
0 1246 1779867877703024703 CMakeFiles/saqut.dir/src/lexer/lexer.cpp.o 90eeec811f2137e6
|
||||
1451 2772 1779867879152793461 CMakeFiles/saqut.dir/src/tokenizer/tokenizer.cpp.o a01677f8bb4f4dbc
|
||||
1246 2891 1779867878947792823 CMakeFiles/saqut.dir/src/parser/parser.cpp.o 2c65b7be26cead32
|
||||
5 2061 1779867877706788958 CMakeFiles/saqut.dir/src/parser/nodes/program.cpp.o ac5bbcd74d87561a
|
||||
1 2213 1779867877703621428 CMakeFiles/saqut.dir/src/parser/nodes/identifier.cpp.o eb96bb4b1eb4ad80
|
||||
1 2296 1779867877703518257 CMakeFiles/saqut.dir/src/parser/nodes/expressions.cpp.o 4057e3d63c63a1ab
|
||||
1 2529 1779867877703709398 CMakeFiles/saqut.dir/src/parser/nodes/literal.cpp.o 78f2c4da7c9b2281
|
||||
7 2335 1779867877708788964 CMakeFiles/saqut.dir/src/parser/nodes/statements.cpp.o b5c20724bbf3648c
|
||||
0 2098 1779867877703316205 CMakeFiles/saqut.dir/src/parser/nodes/binary_expr.cpp.o d2e2bb2f8a63c6d2
|
||||
0 2499 1779867877703412857 CMakeFiles/saqut.dir/src/parser/nodes/declarations.cpp.o b6c56f04a257f685
|
||||
0 2892 1779867877703230815 CMakeFiles/saqut.dir/src/main.cpp.o 110c26cb1d0c3a23
|
||||
2892 2983 1779867880593797950 saqut 89052e51305cb697
|
||||
0 22 1779868368456818650 build.ninja 1876a59d627a585
|
||||
0 22 1779868368456217236 /home/saqut/Masaüstü/saqutcompiler/build/cmake_install.cmake 1876a59d627a585
|
||||
1 1528 1779868368464217284 CMakeFiles/saqut.dir/src/lexer/lexer.cpp.o 90eeec811f2137e6
|
||||
1 1768 1779868368465401047 CMakeFiles/saqut.dir/src/parser/nodes/program.cpp.o ac5bbcd74d87561a
|
||||
1 2006 1779868368464927313 CMakeFiles/saqut.dir/src/parser/nodes/binary_expr.cpp.o d2e2bb2f8a63c6d2
|
||||
1 2109 1779868368465099051 CMakeFiles/saqut.dir/src/parser/nodes/expressions.cpp.o 4057e3d63c63a1ab
|
||||
1 2216 1779868368465200112 CMakeFiles/saqut.dir/src/parser/nodes/identifier.cpp.o eb96bb4b1eb4ad80
|
||||
4 2421 1779868368467294710 CMakeFiles/saqut.dir/src/parser/nodes/statements.cpp.o b5c20724bbf3648c
|
||||
1 2425 1779868368465010538 CMakeFiles/saqut.dir/src/parser/nodes/declarations.cpp.o b6c56f04a257f685
|
||||
1 2450 1779868368465293953 CMakeFiles/saqut.dir/src/parser/nodes/literal.cpp.o 78f2c4da7c9b2281
|
||||
4 2468 1779868368468417782 CMakeFiles/saqut.dir/src/parser/parser.cpp.o 2c65b7be26cead32
|
||||
1528 2575 1779868369991226412 CMakeFiles/saqut.dir/src/tokenizer/tokenizer.cpp.o a01677f8bb4f4dbc
|
||||
1 2887 1779868368464815959 CMakeFiles/saqut.dir/src/main.cpp.o 110c26cb1d0c3a23
|
||||
2887 2980 1779868371350234528 saqut 89052e51305cb697
|
||||
2 1845 1781360349526488567 CMakeFiles/saqut.dir/src/tokenizer/tokenizer.cpp.o a01677f8bb4f4dbc
|
||||
2 1991 1781360349525864955 CMakeFiles/saqut.dir/src/parser/parser.cpp.o 2c65b7be26cead32
|
||||
1 2031 1781360349525052844 CMakeFiles/saqut.dir/src/parser/nodes/binary_expr.cpp.o d2e2bb2f8a63c6d2
|
||||
1 2080 1781360349525452259 CMakeFiles/saqut.dir/src/parser/nodes/literal.cpp.o 78f2c4da7c9b2281
|
||||
1 2083 1781360349525558767 CMakeFiles/saqut.dir/src/parser/nodes/program.cpp.o ac5bbcd74d87561a
|
||||
1 2090 1781360349525147077 CMakeFiles/saqut.dir/src/parser/nodes/declarations.cpp.o b6c56f04a257f685
|
||||
2 2155 1781360349525690109 CMakeFiles/saqut.dir/src/parser/nodes/statements.cpp.o b5c20724bbf3648c
|
||||
1 2240 1781360349525339814 CMakeFiles/saqut.dir/src/parser/nodes/identifier.cpp.o eb96bb4b1eb4ad80
|
||||
1 2355 1781360349525238105 CMakeFiles/saqut.dir/src/parser/nodes/expressions.cpp.o 4057e3d63c63a1ab
|
||||
1 2750 1781360349524108829 CMakeFiles/saqut.dir/src/main.cpp.o 110c26cb1d0c3a23
|
||||
2750 2867 1781360352273116183 saqut 89052e51305cb697
|
||||
1 1640 1781361120993563298 CMakeFiles/saqut.dir/src/parser/nodes/literal.cpp.o 78f2c4da7c9b2281
|
||||
1 1661 1781361120993456534 CMakeFiles/saqut.dir/src/parser/nodes/identifier.cpp.o eb96bb4b1eb4ad80
|
||||
2 1669 1781361120993689645 CMakeFiles/saqut.dir/src/parser/nodes/program.cpp.o ac5bbcd74d87561a
|
||||
1 1681 1781361120993213226 CMakeFiles/saqut.dir/src/parser/nodes/declarations.cpp.o b6c56f04a257f685
|
||||
1 1686 1781361120993117012 CMakeFiles/saqut.dir/src/parser/nodes/binary_expr.cpp.o d2e2bb2f8a63c6d2
|
||||
3 1712 1781361120994511341 CMakeFiles/saqut.dir/src/parser/nodes/statements.cpp.o b5c20724bbf3648c
|
||||
1 1723 1781361120993344591 CMakeFiles/saqut.dir/src/parser/nodes/expressions.cpp.o 4057e3d63c63a1ab
|
||||
1 2281 1781361120992511333 CMakeFiles/saqut.dir/src/main.cpp.o 110c26cb1d0c3a23
|
||||
2281 2374 1781361123272520466 saqut 89052e51305cb697
|
||||
2 1202 1781361145332901008 CMakeFiles/saqut.dir/src/parser/nodes/statements.cpp.o b5c20724bbf3648c
|
||||
2 1435 1781361145332608544 CMakeFiles/saqut.dir/src/parser/nodes/literal.cpp.o 78f2c4da7c9b2281
|
||||
1 1472 1781361145332432199 CMakeFiles/saqut.dir/src/parser/nodes/expressions.cpp.o 4057e3d63c63a1ab
|
||||
2 1506 1781361145332792284 CMakeFiles/saqut.dir/src/parser/nodes/program.cpp.o ac5bbcd74d87561a
|
||||
1 1544 1781361145332547154 CMakeFiles/saqut.dir/src/parser/nodes/identifier.cpp.o eb96bb4b1eb4ad80
|
||||
1 1549 1781361145331608540 CMakeFiles/saqut.dir/src/parser/nodes/binary_expr.cpp.o d2e2bb2f8a63c6d2
|
||||
1 1569 1781361145332294897 CMakeFiles/saqut.dir/src/parser/nodes/declarations.cpp.o b6c56f04a257f685
|
||||
1569 1661 1781361146899614781 saqut 89052e51305cb697
|
||||
1 1470 1781361261444064707 CMakeFiles/saqut.dir/src/main.cpp.o 110c26cb1d0c3a23
|
||||
1471 1563 1781361262914070415 saqut 89052e51305cb697
|
||||
0 1462 1781361334065345164 CMakeFiles/saqut.dir/src/main.cpp.o 110c26cb1d0c3a23
|
||||
1462 1555 1781361335527350781 saqut 89052e51305cb697
|
||||
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
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ CMAKE_AR:FILEPATH=/usr/bin/ar
|
|||
// MinSizeRel ...
|
||||
CMAKE_BUILD_TYPE:STRING=Debug
|
||||
|
||||
//CXX compiler
|
||||
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++
|
||||
//No help, variable specified on the command line.
|
||||
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++
|
||||
|
||||
//A wrapper around 'ar' adding the appropriate '--plugin' option
|
||||
// for the GCC compiler
|
||||
|
|
@ -50,6 +50,9 @@ 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
|
||||
|
||||
|
|
@ -71,8 +74,8 @@ CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
|||
//Enable/Disable output of build database during the build.
|
||||
CMAKE_EXPORT_BUILD_DATABASE:BOOL=
|
||||
|
||||
//Enable/Disable output of compile commands during generation.
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=
|
||||
//No help, variable specified on the command line.
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE
|
||||
|
||||
//Value Computed by CMake.
|
||||
CMAKE_FIND_PACKAGE_REDIRECTS_DIR:STATIC=/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/pkgRedirects
|
||||
|
|
@ -235,7 +238,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=2
|
||||
CMAKE_CACHE_PATCH_VERSION:INTERNAL=3
|
||||
//Path to CMake executable.
|
||||
CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
|
||||
//Path to cpack program executable.
|
||||
|
|
|
|||
|
|
@ -1,102 +0,0 @@
|
|||
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.
|
|
@ -1,15 +0,0 @@
|
|||
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)
|
||||
|
|
@ -1,949 +0,0 @@
|
|||
/* 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;
|
||||
}
|
||||
|
|
@ -1,11 +1,276 @@
|
|||
|
||||
---
|
||||
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:
|
||||
-
|
||||
kind: "find-v1"
|
||||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineSystem.cmake:12 (find_program)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_UNAME"
|
||||
description: "Path to a program."
|
||||
|
|
@ -20,7 +285,6 @@ 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/"
|
||||
|
|
@ -33,13 +297,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/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -55,14 +319,14 @@ events:
|
|||
kind: "message-v1"
|
||||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineSystem.cmake:212 (message)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
message: |
|
||||
The system is: Linux - 7.0.9-1-MANJARO - x86_64
|
||||
The system is: Linux - 7.0.10-1-MANJARO - x86_64
|
||||
-
|
||||
kind: "find-v1"
|
||||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeNinjaFindMake.cmake:5 (find_program)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_MAKE_PROGRAM"
|
||||
description: "Program used to build from build.ninja files."
|
||||
|
|
@ -79,7 +343,6 @@ 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/"
|
||||
|
|
@ -92,9 +355,6 @@ 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"
|
||||
|
|
@ -105,7 +365,8 @@ events:
|
|||
found: "/usr/bin/ninja"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -122,7 +383,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCompiler.cmake:73 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:69 (_cmake_find_compiler)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_CXX_COMPILER"
|
||||
description: "CXX compiler"
|
||||
|
|
@ -146,7 +407,6 @@ 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/"
|
||||
|
|
@ -159,13 +419,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/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -185,7 +445,7 @@ events:
|
|||
- "/usr/share/cmake/Modules/CMakeDetermineCompilerId.cmake:8 (CMAKE_DETERMINE_COMPILER_ID_BUILD)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCompilerId.cmake:64 (__determine_compiler_id_test)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:125 (CMAKE_DETERMINE_COMPILER_ID)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "file"
|
||||
variable: "src_in"
|
||||
description: "Path to a file."
|
||||
|
|
@ -204,7 +464,8 @@ events:
|
|||
found: "/usr/share/cmake/Modules/CMakeCXXCompilerId.cpp.in"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -222,7 +483,7 @@ events:
|
|||
- "/usr/share/cmake/Modules/CMakeDetermineCompilerId.cmake:17 (message)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCompilerId.cmake:64 (__determine_compiler_id_test)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:125 (CMAKE_DETERMINE_COMPILER_ID)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
message: |
|
||||
Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded.
|
||||
Compiler: /usr/bin/c++
|
||||
|
|
@ -236,14 +497,14 @@ 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.2/CompilerIdCXX/a.out
|
||||
/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/4.3.3/CompilerIdCXX/a.out
|
||||
|
||||
-
|
||||
kind: "find-v1"
|
||||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake:243 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:206 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_AR"
|
||||
description: "Path to a program."
|
||||
|
|
@ -259,7 +520,6 @@ 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/"
|
||||
|
|
@ -273,7 +533,8 @@ events:
|
|||
found: "/usr/bin/ar"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -290,7 +551,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake:243 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:206 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_RANLIB"
|
||||
description: "Path to a program."
|
||||
|
|
@ -306,7 +567,6 @@ 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/"
|
||||
|
|
@ -320,7 +580,8 @@ events:
|
|||
found: "/usr/bin/ranlib"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -337,7 +598,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake:243 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:206 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_STRIP"
|
||||
description: "Path to a program."
|
||||
|
|
@ -353,7 +614,6 @@ 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/"
|
||||
|
|
@ -367,7 +627,8 @@ events:
|
|||
found: "/usr/bin/strip"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -384,7 +645,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake:243 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:206 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_LINKER"
|
||||
description: "Path to a program."
|
||||
|
|
@ -400,7 +661,6 @@ 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/"
|
||||
|
|
@ -414,7 +674,8 @@ events:
|
|||
found: "/usr/bin/ld"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -431,7 +692,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake:243 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:206 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_NM"
|
||||
description: "Path to a program."
|
||||
|
|
@ -447,7 +708,6 @@ 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/"
|
||||
|
|
@ -461,7 +721,8 @@ events:
|
|||
found: "/usr/bin/nm"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -478,7 +739,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake:243 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:206 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_OBJDUMP"
|
||||
description: "Path to a program."
|
||||
|
|
@ -494,7 +755,6 @@ 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/"
|
||||
|
|
@ -508,7 +768,8 @@ events:
|
|||
found: "/usr/bin/objdump"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -525,7 +786,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake:243 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:206 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_OBJCOPY"
|
||||
description: "Path to a program."
|
||||
|
|
@ -541,7 +802,6 @@ 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/"
|
||||
|
|
@ -555,7 +815,8 @@ events:
|
|||
found: "/usr/bin/objcopy"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -572,7 +833,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake:243 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:206 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_READELF"
|
||||
description: "Path to a program."
|
||||
|
|
@ -588,7 +849,6 @@ 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/"
|
||||
|
|
@ -602,7 +862,8 @@ events:
|
|||
found: "/usr/bin/readelf"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -619,7 +880,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake:243 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:206 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_DLLTOOL"
|
||||
description: "Path to a program."
|
||||
|
|
@ -635,7 +896,6 @@ 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/"
|
||||
|
|
@ -648,7 +908,6 @@ 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"
|
||||
|
|
@ -662,7 +921,8 @@ events:
|
|||
found: false
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -679,7 +939,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake:243 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:206 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_ADDR2LINE"
|
||||
description: "Path to a program."
|
||||
|
|
@ -695,7 +955,6 @@ 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/"
|
||||
|
|
@ -709,7 +968,8 @@ events:
|
|||
found: "/usr/bin/addr2line"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -726,7 +986,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake:243 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:206 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_TAPI"
|
||||
description: "Path to a program."
|
||||
|
|
@ -742,7 +1002,6 @@ 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/"
|
||||
|
|
@ -755,7 +1014,6 @@ 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"
|
||||
|
|
@ -769,7 +1027,8 @@ events:
|
|||
found: false
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -786,7 +1045,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/Compiler/GNU-FindBinUtils.cmake:18 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:207 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_CXX_COMPILER_AR"
|
||||
description: "A wrapper around 'ar' adding the appropriate '--plugin' option for the GCC compiler"
|
||||
|
|
@ -805,7 +1064,6 @@ 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/"
|
||||
|
|
@ -818,7 +1076,6 @@ 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"
|
||||
|
|
@ -830,7 +1087,6 @@ 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"
|
||||
|
|
@ -842,7 +1098,6 @@ 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"
|
||||
|
|
@ -856,7 +1111,8 @@ events:
|
|||
found: "/usr/bin/gcc-ar"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -873,7 +1129,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/Compiler/GNU-FindBinUtils.cmake:30 (find_program)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:207 (include)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
mode: "program"
|
||||
variable: "CMAKE_CXX_COMPILER_RANLIB"
|
||||
description: "A wrapper around 'ranlib' adding the appropriate '--plugin' option for the GCC compiler"
|
||||
|
|
@ -892,7 +1148,6 @@ 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/"
|
||||
|
|
@ -905,7 +1160,6 @@ 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"
|
||||
|
|
@ -917,7 +1171,6 @@ 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"
|
||||
|
|
@ -929,7 +1182,6 @@ 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"
|
||||
|
|
@ -943,7 +1195,8 @@ events:
|
|||
found: "/usr/bin/gcc-ranlib"
|
||||
search_context:
|
||||
ENV{PATH}:
|
||||
- "/home/saqut/.vscode/extensions/vadimcn.vscode-lldb-1.12.0/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/home/saqut/.local/bin"
|
||||
- "/usr/local/bin"
|
||||
- "/usr/bin"
|
||||
|
|
@ -960,12 +1213,12 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCompilerABI.cmake:83 (try_compile)"
|
||||
- "/usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
checks:
|
||||
- "Detecting CXX compiler ABI info"
|
||||
directories:
|
||||
source: "/home/saqut/Masa\u00fcst\u00fc/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-tE3Uvz"
|
||||
binary: "/home/saqut/Masa\u00fcst\u00fc/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-tE3Uvz"
|
||||
source: "/home/saqut/Masa\u00fcst\u00fc/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-bNmRFu"
|
||||
binary: "/home/saqut/Masa\u00fcst\u00fc/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-bNmRFu"
|
||||
cmakeVariables:
|
||||
CMAKE_CXX_FLAGS: ""
|
||||
CMAKE_CXX_FLAGS_DEBUG: "-g"
|
||||
|
|
@ -976,10 +1229,10 @@ events:
|
|||
variable: "CMAKE_CXX_ABI_COMPILED"
|
||||
cached: true
|
||||
stdout: |
|
||||
Change Dir: '/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-tE3Uvz'
|
||||
Change Dir: '/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-bNmRFu'
|
||||
|
||||
Run Build Command(s): /usr/bin/ninja -v cmTC_3d12d
|
||||
[1/2] /usr/bin/c++ -v -o CMakeFiles/cmTC_3d12d.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp
|
||||
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
|
||||
Using built-in specs.
|
||||
COLLECT_GCC=/usr/bin/c++
|
||||
Target: x86_64-pc-linux-gnu
|
||||
|
|
@ -987,8 +1240,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_3d12d.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_3d12d.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_3d12d.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -version -o /tmp/ccHXl8ac.s
|
||||
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
|
||||
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
|
||||
|
||||
|
|
@ -1005,13 +1258,13 @@ events:
|
|||
/usr/include
|
||||
End of search list.
|
||||
Compiler executable checksum: d47d0c990a24bc0dbaf3bd00656bd5f3
|
||||
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_3d12d.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_3d12d.dir/'
|
||||
as -v --64 -o CMakeFiles/cmTC_3d12d.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccHXl8ac.s
|
||||
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
|
||||
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_3d12d.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_3d12d.dir/CMakeCXXCompilerABI.cpp.'
|
||||
[2/2] : && /usr/bin/c++ -v -Wl,-v CMakeFiles/cmTC_3d12d.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_3d12d && :
|
||||
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 && :
|
||||
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
|
||||
|
|
@ -1022,12 +1275,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_3d12d' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_3d12d.'
|
||||
/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/ccq9todA.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_3d12d /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_3d12d.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_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
|
||||
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/ccq9todA.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_3d12d /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_3d12d.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/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
|
||||
GNU ld (GNU Binutils) 2.46.0
|
||||
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_3d12d' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_3d12d.'
|
||||
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_a8847' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_a8847.'
|
||||
|
||||
exitCode: 0
|
||||
-
|
||||
|
|
@ -1035,7 +1288,7 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCompilerABI.cmake:217 (message)"
|
||||
- "/usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
message: |
|
||||
Parsed CXX implicit include dir info: rv=done
|
||||
found start of include info
|
||||
|
|
@ -1061,15 +1314,15 @@ events:
|
|||
backtrace:
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCompilerABI.cmake:253 (message)"
|
||||
- "/usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
message: |
|
||||
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-tE3Uvz']
|
||||
ignore line: [Change Dir: '/home/saqut/Masaüstü/saqutcompiler/build/CMakeFiles/CMakeScratch/TryCompile-bNmRFu']
|
||||
ignore line: []
|
||||
ignore line: [Run Build Command(s): /usr/bin/ninja -v cmTC_3d12d]
|
||||
ignore line: [[1/2] /usr/bin/c++ -v -o CMakeFiles/cmTC_3d12d.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp]
|
||||
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: [Using built-in specs.]
|
||||
ignore line: [COLLECT_GCC=/usr/bin/c++]
|
||||
ignore line: [Target: x86_64-pc-linux-gnu]
|
||||
|
|
@ -1077,8 +1330,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_3d12d.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_3d12d.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_3d12d.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -version -o /tmp/ccHXl8ac.s]
|
||||
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: [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: []
|
||||
|
|
@ -1095,13 +1348,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_3d12d.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_3d12d.dir/']
|
||||
ignore line: [ as -v --64 -o CMakeFiles/cmTC_3d12d.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccHXl8ac.s]
|
||||
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: [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_3d12d.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_3d12d.dir/CMakeCXXCompilerABI.cpp.']
|
||||
ignore line: [[2/2] : && /usr/bin/c++ -v -Wl -v CMakeFiles/cmTC_3d12d.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_3d12d && :]
|
||||
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: [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]
|
||||
|
|
@ -1112,13 +1365,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_3d12d' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_3d12d.']
|
||||
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/ccq9todA.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_3d12d /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_3d12d.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_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]
|
||||
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/ccq9todA.res] ==> ignore
|
||||
arg [-plugin-opt=-fresolution=/tmp/cce2Bg9n.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
|
||||
|
|
@ -1134,7 +1387,7 @@ events:
|
|||
arg [/lib64/ld-linux-x86-64.so.2] ==> ignore
|
||||
arg [-pie] ==> ignore
|
||||
arg [-o] ==> ignore
|
||||
arg [cmTC_3d12d] ==> ignore
|
||||
arg [cmTC_a8847] ==> 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]
|
||||
|
|
@ -1146,7 +1399,7 @@ events:
|
|||
arg [-L/lib] ==> dir [/lib]
|
||||
arg [-L/usr/lib] ==> dir [/usr/lib]
|
||||
arg [-v] ==> ignore
|
||||
arg [CMakeFiles/cmTC_3d12d.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore
|
||||
arg [CMakeFiles/cmTC_a8847.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore
|
||||
arg [-lstdc++] ==> lib [stdc++]
|
||||
arg [-lm] ==> lib [m]
|
||||
arg [-lgcc_s] ==> lib [gcc_s]
|
||||
|
|
@ -1158,7 +1411,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/ccq9todA.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_3d12d /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_3d12d.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/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]
|
||||
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]
|
||||
|
|
@ -1182,7 +1435,7 @@ events:
|
|||
- "/usr/share/cmake/Modules/Internal/CMakeDetermineLinkerId.cmake:38 (message)"
|
||||
- "/usr/share/cmake/Modules/CMakeDetermineCompilerABI.cmake:299 (cmake_determine_linker_id)"
|
||||
- "/usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
|
||||
- "CMakeLists.txt:51 (project)"
|
||||
- "CMakeLists.txt:2 (project)"
|
||||
message: |
|
||||
Running the CXX compiler's linker: "/usr/bin/ld" "-v"
|
||||
GNU ld (GNU Binutils) 2.46.0
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
# 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()
|
||||
|
|
@ -0,0 +1 @@
|
|||
# This file is generated by CMake for checking of the VerifyGlobs.cmake file
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
rule CXX_SCAN__saqut_Debug
|
||||
depfile = $DEP_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
|
||||
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
|
||||
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/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
|
||||
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
|
||||
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/c++ $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
|
||||
command = ${LAUNCHER}${CODE_CHECK}/usr/bin/g++ $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/c++ $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
|
||||
command = $PRE_LINK && /usr/bin/g++ $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
|
||||
description = Linking CXX executable $TARGET_FILE
|
||||
restat = $RESTAT
|
||||
|
||||
|
|
@ -79,6 +79,15 @@ 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.
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
# 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
|
|
@ -0,0 +1,39 @@
|
|||
# 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()
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# 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()
|
||||
|
|
@ -10,12 +10,11 @@
|
|||
> Tartışmanın tam akışı için bkz. `docs/transkript-frontend-tasarim.md`.
|
||||
> Uygulama planı için bkz. `docs/roadmap-frontend.md`.
|
||||
>
|
||||
> ⚠️ **Yapılan vs planlanan:** Bu belgedeki ADR-006…019 **tasarım kararlarıdır**;
|
||||
> tarif edilen makine (sembol tablosu, semantik analiz, tip sistemi, diagnostic,
|
||||
> optimizasyon, IR+VM) **henüz kodlanmamıştır.** Bugün çalışan: lexer, tokenizer,
|
||||
> Pratt parser, AST, AST'nin JSON serileştirmesi, CLI iskeleti, konum takibi ve
|
||||
> basit aritmetiği düşüren minimal bir IR deneyi. Hiçbir ADR, var olmayan bir
|
||||
> mekanizmayı varmış gibi anlatmaz.
|
||||
> ✅ **Uygulama durumu:** Bu belgedeki ADR-006…019 kararlarında tarif edilen
|
||||
> makine **kodlandı ve çalışıyor.** Sembol tablosu, semantik analiz, tip sistemi,
|
||||
> diagnostic motoru, optimizasyon (constant folding + DCE), IR üreteci ve bytecode
|
||||
> VM'in tamamı uygulandı. `examples/fibonacci.sqt` uçtan uca çalışıyor.
|
||||
> Güncel "çalışıyor / henüz yok" listesi için bkz. `CLAUDE.md`.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -105,46 +104,45 @@ sembol tablosunun optimizasyondan önceki ve sonraki halini ayrı ayrı görebil
|
|||
symbol bağı, erişilebilirlik, constness ekler). Ağacı **bozmaz**, zenginleştirir.
|
||||
Orijinal AST hâlâ kaynak kodun tam izdüşümüdür.
|
||||
|
||||
2. **Optimizasyon dönüşümü, ağacın bir KOPYASI (klon) üzerinde yapılır.**
|
||||
Orijinal analizli AST = "öncesi"; klon + dönüştürülmüş AST = "sonrası".
|
||||
Ağaç klonlamak ucuz ve basittir, yalnızca `--optimized` istendiğinde yapılır.
|
||||
2. **Optimizasyon dönüşümü iki yolla yapılabilir:**
|
||||
|
||||
**Sonuç:** Hem "bellek canavarı" felsefesi korunur (orijinal AST her şeyi tutar),
|
||||
hem optimizasyon yapılır, hem de öncesi/sonrası ayrı ayrı incelenebilir.
|
||||
a. **`ast` komutu için klon:** orijinal AST dokunulmadan kalır, klon üstünde
|
||||
pass'ler çalışır. Kullanıcı "öncesi" ve "sonrası" AST'yi ayrı ayrı
|
||||
görebilir. `OptimizationManager::optimize()` bu yolu kullanır.
|
||||
|
||||
b. **Diğer tüm komutlar için yerinde (in-place):** `run --optimized`,
|
||||
`ir --optimized` vb. tek versiyon üretiyor — orijinali saklamaya gerek yok.
|
||||
`OptimizationManager::runPassesInPlace()` bu yolu kullanır, klon maliyeti yok.
|
||||
|
||||
**Sonuç:** "bellek canavarı" felsefesi `ast` komutunda korunur; diğer komutlar
|
||||
gereksiz klon maliyeti taşımaz.
|
||||
|
||||
```
|
||||
saqut ast file.sqt → ham + annotate edilmiş AST (1+2 burada durur)
|
||||
saqut ast file.sqt --optimized → klon, folding uygulanmış (3 var)
|
||||
saqut run file.sqt --optimized → yerinde optimize → IR → VM (klon yok)
|
||||
saqut ir file.sqt --optimized → yerinde optimize → IR dump (klon yok)
|
||||
```
|
||||
|
||||
### Güncelleme — Klon maliyeti yük taşır (load-bearing)
|
||||
### Güncelleme — Klon ve sembol tablosu paylaşımı
|
||||
|
||||
İlk metin "ağaç klonlamak ucuz ve basittir" diyordu; bu **klon maliyetini hafife
|
||||
alıyor** ve bir **tutarlılık (coherence) problemini** atlıyordu. Düzeltme:
|
||||
`deepClone` sembol tablosunu yeniden eşlemez (remap etmez) — klondaki
|
||||
`IdentifierNode::resolvedSymbol` orijinal `Symbol` nesnelerini gösterir. Bu
|
||||
**güvenlidir**, çünkü:
|
||||
|
||||
`ASTNode::clone()` "belki gerekir" değil, **merkezi ve spesifiye edilmesi
|
||||
zorunlu** bir bileşendir; tüm öncesi/sonrası hikâyesi ona dayanır (bkz. roadmap
|
||||
Faz 4'te clone() yükseltildi).
|
||||
- `Symbol::references` bir **konum listesi** (`std::vector<SourceLocation>`),
|
||||
referans sayacı değildir. Klonda bir `IdentifierNode` silindiğinde bu liste
|
||||
değişmez.
|
||||
- `IdentifierNode` destructor'ı yoktur; `resolvedSymbol`'e dokunan hiçbir yıkıcı
|
||||
kodu çalışmaz.
|
||||
- Klondaki pass'ler Symbol nesnelerini **okur** (slot numarası, tip vb.),
|
||||
**yazmaz** — paylaşım salt-okunur (read-only) kullanımdır.
|
||||
|
||||
**Klonlanırken karar verilmesi gereken iki nokta (açıkça belgele):**
|
||||
**Parent pointer'lar** ise yeniden bağlanır — klon node'larının `parent`'ı
|
||||
orijinali değil, klonu gösterir (deepClone bunu zaten yapar).
|
||||
|
||||
1. **Parent pointer'lar yeniden bağlanmalı.** Klon node'larının `parent`'ı
|
||||
orijinali değil, klonu göstermeli; yoksa yapısal doğrulama ve dönüşümler
|
||||
yanlış ağaçta gezinir.
|
||||
|
||||
2. **`IdentifierNode → Symbol` bağları: paylaş mı, yeniden eşle mi?**
|
||||
- **Paylaş** (klon ve orijinal aynı sembol tablosuna işaret eder): ucuz, ama
|
||||
klonu optimize etmek orijinalin **referans sayımlarını bozar** (DCE klonda
|
||||
bir kullanımı silince orijinalin Symbol ref-count'u da düşer).
|
||||
- **Yeniden eşle** (klona ait bir sembol tablosu kopyası): doğru, ama ucuz
|
||||
değil.
|
||||
- **Karar:** `--optimized` istendiğinde sembol tablosu da **klonlanır ve
|
||||
yeniden eşlenir** (remap). Doğruluk, ucuzluğa tercih edilir; klon zaten
|
||||
yalnızca optimizasyon istendiğinde üretilir, sıcak yol değildir. "Ucuz"
|
||||
iddiası kaldırıldı.
|
||||
|
||||
Bu, ADR-013'teki "ref-count Symbol'da yaşar" kararıyla tutarlıdır: ref-count
|
||||
Symbol'da olduğu için, klonun kendi Symbol'larına sahip olması şarttır.
|
||||
Önceki versiyon "sembol tablosu klonlanır ve remap edilir" diyordu; bu hem hiç
|
||||
implement edilmedi hem de gerekli değildi. Düzeltildi.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -513,6 +511,11 @@ bir yükümlülüktür ama **frontend'i bloklamaz** ve kolay yolu vardır:
|
|||
|
||||
### Güncelleme — Scope-tabanlı bellek artık GEREKÇELİ (bağımlılığı belgele)
|
||||
|
||||
> ⚠️ **İPTAL — bu güncelleme ADR-020 ile geçersiz kılındı.** Bileşik tipler artık
|
||||
> runtime'da referans (JS/Java/C# modeli); bileşikler scope'tan kaçar, bellek
|
||||
> erişilebilirliğe bağlı, geri-kazanım stratejisi (#56) gerekecek. Aşağıdaki
|
||||
> "GC gerekmez" sonucu **artık geçerli değildir** — tarihsel bağlam için bırakıldı.
|
||||
|
||||
Önceki kaygı ("scope çıkışında free, aliasing/escape altında bozulur") kilitli
|
||||
dil kimliğiyle **lehte çözüldü:**
|
||||
|
||||
|
|
@ -662,12 +665,457 @@ modelini birlikte zorlar — ikisi de bu yüzden ertelendi.
|
|||
|
||||
---
|
||||
|
||||
## ADR-020: Değer vs Referans Semantiği — Bileşik Tipler Runtime'da Referanstır
|
||||
|
||||
### Bağlam
|
||||
|
||||
ADR-014/018/019 boyunca bellek modeli tek bir **taşıyıcı varsayıma** dayanıyordu:
|
||||
|
||||
> "kullanıcı pointer'ı yok + kaçan referans yok → array/struct scope'tan kaçamaz
|
||||
> → scope-tabanlı bellek çalışır, **GC gerekmez**."
|
||||
|
||||
Bu varsayım, `interface`'in (ADR-018) ve closure'ın ertelenmesinin de ikinci
|
||||
gerekçesiydi. Tasarım oturumunda **bilinçli olarak değiştirildi.** "Pointer yok"
|
||||
ilkesinin gerçekte ne demek olduğu netleşti:
|
||||
|
||||
> **"Pointer/referans yok" = kullanıcıya `&`/`*` *sözdizimi* verilmez.**
|
||||
> Bu bir *value-semantics* iddiası değildi; amacı sözdizimsel pointer kontrolünü
|
||||
> kullanıcıdan almaktı. Derleyici ve runtime, bileşik değerleri her aşamada
|
||||
> **referansla** taşır — aksi halde her atama/çağrı/dönüşte derin kopya yaşanır
|
||||
> ve bağlı yapılar (node) imkânsızlaşırdı.
|
||||
|
||||
### Karar
|
||||
|
||||
✅ **İki katmanlı semantik (JavaScript / Java / C# nesne modeli):**
|
||||
|
||||
| Kategori | Tipler | Atama / parametre semantiği |
|
||||
|---|---|---|
|
||||
| **Primitive** | `int`, `float`, `bool`, (`char` vb.) | **Saf değer** — kopyalanır |
|
||||
| **Bileşik (referans)** | `struct`, `array`, `string`\*, (ileride `class`, `function`) | **Referans** — paylaşılır |
|
||||
|
||||
- `a=0; b=a; b=5` → `a` hâlâ `0` (primitive kopya). Fonksiyon parametresinde de aynı.
|
||||
- `func(arr)` → array'in **kendisi** geçer; `func` içinde değişen çağıranı **etkiler**.
|
||||
- `func(arr[0])` → eleman primitive → **kopya**; çağıranı **etkilemez**.
|
||||
- \* `string`'in primitive-gibi mi (immutable değer) yoksa referans mı sayılacağı
|
||||
ayrı bir alt-karar; #40 ile beraber netleşecek.
|
||||
|
||||
✅ **`class` ve `function` tipleri sözdizimsel olarak rezerve** — şu an semantik
|
||||
yok, backend'i ilgilendirmez; ileride referans tip olarak gelecekler. Lexer/parser
|
||||
keyword'leri tanıyıp "henüz desteklenmiyor" diyebilir. (ADR-014'teki "class yok
|
||||
sayılır" maddesi bu yönde yumuşatıldı: yok sayılmaz, rezerve edilir.)
|
||||
|
||||
### Bilinçli geri açtığımız problem: kaçma / yaşam-süresi
|
||||
|
||||
Bu karar, ADR-014'ün "scope-tabanlı bellek GEREKÇELİ / GC gerekmez" sonucunu
|
||||
**iptal eder.** Referansla:
|
||||
|
||||
1. **Aliasing gerçek.** `b = a; b.x = 5` → `a.x` de değişir. "Takma ad yok, akıl
|
||||
yürütmesi kolay" sadeliği takas edildi. **Determinizm korunur** — tek
|
||||
iş-parçacığı, deterministik kayıt-tekrar / time-travel debug hâlâ doğal; takas
|
||||
edilen yalnızca aliasing-özgürlüğüdür.
|
||||
2. **Bileşikler scope'tan kaçar.** Bir node `return` edilebilir veya başka bir
|
||||
struct'ın alanında saklanabilir → "scope çıkışında free" **artık yanlış.**
|
||||
Sahiplik scope'a değil **erişilebilirliğe** bağlı.
|
||||
3. **Döngüsel yapılar artık meşru ve istenen.** `struct Node { Node next; }`
|
||||
ADR-011/014'te `E010` ile yasaktı (by-value → sonsuz boyut). Referansla alan
|
||||
pointer-boyutlu → **sonlu** → bağlı liste / ağaç / graf **yazılabilir.** Bunlar
|
||||
dilin hedef kullanımının kalbi: XML node'ları, JSON kalıpları, class'sız ORM.
|
||||
**Sonuç:** `E010` revize edilmeli — referansla tutulan struct alanı için döngü
|
||||
artık hata değildir.
|
||||
|
||||
### Bunun açtığı zorunlu problem (ayrı issue)
|
||||
|
||||
Döngüsel referans → naif **referans sayımı (`shared_ptr`) sızdırır.** Bu artık
|
||||
"olabilir" değil, dilin **hedeflediği** yapıların (graf/döngü) doğrudan sonucu.
|
||||
Bir geri-kazanım stratejisi (izleyici GC / döngü toplayıcı) **kesinlikle**
|
||||
gerekecek. Bu güçlü mimari borç **#56**'da izlenir ve `karar-gerekli`. v1 motoru
|
||||
`shared_ptr` ile başlayıp döngüyü **bilinçli ve belgeleyerek** sızdırabilir, ama
|
||||
ürünleşmeden önce çözülmek zorundadır.
|
||||
|
||||
### İptal/revize edilen önceki kararlar
|
||||
|
||||
- **ADR-014** — "scope-tabanlı bellek GEREKÇELİ / GC gerekmez" sonucu **iptal.**
|
||||
Bellek artık scope'a değil erişilebilirliğe bağlı; geri-kazanım stratejisi #56.
|
||||
- **ADR-018 / ADR-019** — `interface` / closure'ı ertelemenin "kaçma problemini
|
||||
yeniden açar" gerekçesi **artık geçersiz** (problem zaten açık). Bu ikisini
|
||||
*daha kolay* alınabilir kılar — ama hâlâ kapsam dışı, sadece engeli değişti.
|
||||
- **ADR-011** — `E010` döngüsel struct kuralı revize edilecek (yukarı bkz.).
|
||||
|
||||
---
|
||||
|
||||
## ADR-021: Null Güvenliği — `Type?` Nullable + Akış-Duyarlı Null Analizi
|
||||
|
||||
### Bağlam
|
||||
|
||||
ADR-020 ile bileşik tipler referans oldu. Referans, "gösterecek bir şey yok"
|
||||
durumunu (bağlı listenin sonu, başlatılmamış alan) **zorunlu** kılar. "null her
|
||||
yerde" (Java/C#/JS) milyar dolarlık hatadır: null-deref çalışma zamanında patlar.
|
||||
saQut'un kimliği "kafes — derleyici/VM seni korur" → bunu derleme zamanında
|
||||
yakalamak istiyoruz.
|
||||
|
||||
### Karar
|
||||
|
||||
✅ **Kotlin/Swift modeli: varsayılan null-OLAMAZ, nullable açıkça `?` ile.**
|
||||
|
||||
- `Node a` → asla null olamaz; başlatılması zorunlu.
|
||||
- `Node? a` → null olabilir; başlatılmazsa değeri **`null`**.
|
||||
- `null` literali yalnızca `T?` tipine atanabilir; `Node a = null` → **derleme hatası**.
|
||||
- `T?` üstünde doğrudan alan/eleman erişimi (`a.next`) → **derleme hatası**
|
||||
(önce null-kontrolü şart).
|
||||
|
||||
### Atama/operand kuralı — `T <: T?` (tek yönlü), katı
|
||||
|
||||
✅ **Alt-tip:** `T <: T?`. Yani:
|
||||
- `int? a = 5;` → ✓ (int → int?, **genişletme serbest**).
|
||||
- `int a = bir_int?;` → ✗ (int? → int, **daraltma yasak**).
|
||||
|
||||
✅ **Katı operand kuralı:** non-null bir bağlamda — atamanın sol tarafı, **her
|
||||
operatör operandı**, non-null bekleyen bir argüman — değer **statik olarak non-null**
|
||||
olmalı. `int a = b + c + d`'de `b/c/d`'den **biri bile** nullable ise → **derleme
|
||||
hatası.** Sembol tablosu/akış görünümü seviyesinde: `notnull = notnull + notnull + …`.
|
||||
Sezgi yok, deterministik. (`notnull + notnull` → `notnull`.)
|
||||
|
||||
### Akış-duyarlı null analizi (flow-sensitive narrowing)
|
||||
|
||||
`T?` bir değişken **program noktasına göre** "kesin non-null" kanıtlandıysa
|
||||
daraltılır:
|
||||
|
||||
```c
|
||||
Node? a = ...;
|
||||
// a.next; // E0xx: a null olabilir
|
||||
if (a != null) {
|
||||
a.next; // OK — bu dalda a, Node'a daraltıldı
|
||||
}
|
||||
// a.next; // yine hata (daldan çıkıldı)
|
||||
|
||||
if (a == null) return; // guard / erken çıkış
|
||||
a.next; // OK — buradan sonrası kesin non-null
|
||||
```
|
||||
|
||||
`if` bu sistemin **bel kemiğidir** — sadece büyük/küçük/eşitlik değil, nullable
|
||||
aklamanın da aracı. **İki form da desteklenir:**
|
||||
|
||||
1. **Nested (blok-kapsamlı):** `if (a != null) { /* a: T burada */ }`. Ayrıca
|
||||
`if/else`'in zıt dalı, `while (a != null) { … }`.
|
||||
2. **Sıralı (guard / erken-çıkış):** `if (a == null) return; /* a: T bundan sonra */`.
|
||||
Dal kesin çıkıyorsa (`return`/`throw`/`break`/`continue`) negasyonu **ardışık**
|
||||
koda taşınır.
|
||||
|
||||
**Mekanik:** CFG üzerinde ileri-yönlü dataflow; her nullable değişken için kafes
|
||||
`{MaybeNull, NonNull}`. Koşullarda daraltma (`!= null`, `== null` guard, `&&`
|
||||
kısa-devre sağ tarafı); kesin-çıkış dalları negasyonu ardına taşır; birleşme (join)
|
||||
muhafazakâr (bir daldan MaybeNull gelirse MaybeNull); atama RHS'e göre sıfırlar.
|
||||
|
||||
> **Karmaşıklaştırma sınırı:** narrowing yalnızca **doğrudan test edilen değişken**
|
||||
> için tanınır (`x == null`/`x != null`). **Alias takibi YOK** (`y = x; if (y != null)`
|
||||
> → x daralmaz) ve keyfi teorem-ispatı yok. Bu, derleyiciyi basit tutarken yaygın
|
||||
> durumların hepsini kapsar → developer **uzun/karmaşık kod yazmak zorunda kalmaz.**
|
||||
|
||||
> **Runtime maliyeti SIFIR** — tamamen derleme-zamanı analizi; üretilen kodda
|
||||
> fazladan kontrol yok.
|
||||
|
||||
### Kaçış kapısı YOK — `!` ve `??` YASAK
|
||||
|
||||
Null **yalnızca görünür kontrol akışıyla** (yukarıdaki `if` narrowing) aklanır.
|
||||
Gizli runtime null-aklama operatörleri **yasaktır:**
|
||||
|
||||
- ❌ **`x!`** (non-null iddiası) — "compiler'a güvenme, runtime'da kontrol et"
|
||||
= statik garantiyi delen gizli backdoor. *(ADR-021'in ilk taslağındaki `a!`
|
||||
KALDIRILDI.)*
|
||||
- ❌ **`x ?? default`** (elvis), **`x?.field`** (güvenli çağrı) — null durumunu
|
||||
sessizce gizleyen şeker.
|
||||
|
||||
> Ayrım: `as int`'in başarısızlıkta fırlatması yasak **değil** — o bir null-backdoor
|
||||
> değil, kendiliğinden başarısız olabilen bir *dönüşüm* (ADR-026).
|
||||
|
||||
### Frontend her şeyi kesin çözer (backend-bağımsızlık)
|
||||
|
||||
Nullability **tamamen frontend'de** çözülür; tüm null-güvenlik hataları IR'den
|
||||
**önce** verilir. Backend'ler (IR+VM, ileride C-transpile) null-güvenliği **yeniden
|
||||
analiz etmez** — garantiyi hazır devralır (ADR-006/019). Bu sayede: well-typed saf
|
||||
saQut kodu **statik null-güvenlidir** → non-null referans deref'i runtime null-kontrolü
|
||||
**gerektirmez** (perf + sadelik). Runtime null-deref hatası (ADR-025) bu yüzden
|
||||
geriye esas olarak **FFI sınırı** (host non-null sözünü çiğnerse) ve savunma amaçlı
|
||||
backstop olarak kalır — saf saQut kodu bunu üretmez.
|
||||
|
||||
### Mimari yeri
|
||||
|
||||
Bu, saQut'un ilk gerçek **akış-duyarlı** analizidir. **Yapısal kontrol akışı**
|
||||
üstünde (AST + structured CFG) yapılabilir; tam SSA gerektirmez → **#2 (CFG/SSA
|
||||
gerekli mi?)** için somut veri: şimdilik yapısal akış analizi yeter. **#20**
|
||||
(akıllı diagnostic) bu analizden beslenir ("burada null olabilir, çünkü …").
|
||||
|
||||
---
|
||||
|
||||
## ADR-022: Bellek Geri-Kazanımı — Basit Deterministik Mark-Sweep + GC-Hazır Nesne Modeli
|
||||
|
||||
### Bağlam
|
||||
|
||||
ADR-020 referans semantiği → döngüsel yapılar (#56). Kısıtlar: GC **basit ve
|
||||
deterministik** olmalı, "karmaşık ve rastgele" istenmiyor. Ayrıca bu, **geç
|
||||
değiştirilmesi en pahalı** karardır (nesne modeline işler) → topuğa sıkmamak
|
||||
kritik.
|
||||
|
||||
### Önce yanlış-eşleştirmeyi temizle
|
||||
|
||||
**`null`/`?` GC'yi zorlaştırmaz.** Nullable tamamen derleme-zamanı/tip meselesidir;
|
||||
runtime'da null referans sadece "boş işaretçi" → GC için *daha kolay* (izlenecek
|
||||
nesne yok). null ile GC **dik (orthogonal)**; aralarında gerilim yoktur.
|
||||
|
||||
### Seçenekler ve neden mark-sweep
|
||||
|
||||
| Strateji | Döngü | Basitlik | Topuğa-sıkma riski |
|
||||
|---|---|---|---|
|
||||
| Refcount (`shared_ptr` her yerde) | ❌ sızdırır | başta basit | **Yüksek** — node dilinde döngü kaçınılmaz; üstüne döngü toplayıcı = CPython karmaşıklığı (tam "karmaşık/rastgele") |
|
||||
| **Mark-sweep, taşımasız, stop-the-world** | ✅ | **en basit *doğru* GC** | **Düşük** — gelişmiş GC'lerin tabanı; üstüne eklenir, yeniden yazılmaz |
|
||||
| Generational / incremental / compacting | ✅ | karmaşık (write barrier, remembered set) | pause'lar belirsizleşir = istenmeyen "rastgele" |
|
||||
|
||||
✅ **Karar: taşımasız (non-moving), stop-the-world, basit mark-sweep.**
|
||||
- Döngüleri **bedavaya** toplar (izleme döngü umursamaz) → #56'yı gerçekten çözer.
|
||||
- **Deterministik:** GC belirli safepoint'lerde çalışır (ör. her N tahsiste) →
|
||||
kayıt-tekrar / time-travel bit-aynı kalır ("cage" korunur). "Rastgele" değil.
|
||||
- Taşımasız → işaretçi düzeltme / barrier yok → VM'in geri kalanı GC'ye katılmak
|
||||
zorunda değil. *Crafting Interpreters*'ın `clox`'u tam bunu yapar (~birkaç yüz satır).
|
||||
|
||||
### Topuğa-sıkmama kuralı — nesne modelini ŞİMDİ GC-hazır kur
|
||||
|
||||
Asıl risk GC'yi *yazmak* değil, nesne modelini sonradan ona uyduramamaktır. O
|
||||
yüzden **bugünden** (toplama yokken bile):
|
||||
|
||||
1. Her heap nesnesine küçük **header**: tip tag + mark biti + tüm-nesneler listesi için `next`.
|
||||
2. VM **kök (root) sayımı** yapabilsin: operand stack, frame local'leri, global'ler.
|
||||
3. Bir nesne **içerdiği referansları** sayabilsin: referans-tipli struct alanları,
|
||||
referans-tipli array elemanları.
|
||||
|
||||
Bu üçü hazırsa "mark-sweep'i aç" **lokal bir ekleme** olur, nesne-modeli yeniden
|
||||
yazımı değil.
|
||||
|
||||
### Aşamalandırma (#56'nın yönü)
|
||||
|
||||
- **v1 (şimdi):** GC-header'lı tahsis + intrusive tüm-nesneler listesi + kök sayımı.
|
||||
**Toplama yok** (program sonunda hepsini bırak / arena). Fibonacci/test ölçeğinde
|
||||
sorunsuz; kısa programlar sızıntıdan etkilenmez.
|
||||
- **v2 (#56 ciddileşince):** aynı header+kök+çocuk-sayımı üstünde mark-sweep'i aç.
|
||||
Model yeniden yazılmaz.
|
||||
- **`shared_ptr`'dan kaçın:** v1'de bile her referansa refcount gömmek, sonra
|
||||
mark-sweep için **sökmek** ayrı bir topuğa-sıkmadır. Baştan GC-header modeli kur,
|
||||
sadece henüz toplama.
|
||||
|
||||
### Performans notu — asıl "katil" nerede?
|
||||
|
||||
- **Nullability / null:** runtime maliyeti **sıfır** — katil değil.
|
||||
- **Referans modeli:** her bileşik heap'te + işaretçi dolaylılığı → düzenli ama
|
||||
yönetilebilir maliyet; ileride **escape analizi** ile kaçmayan nesneleri stack'e
|
||||
alıp *semantiği bozmadan* hızlandırılır (opt-in, sonra).
|
||||
- **Tek yüksek-değişim-maliyetli karar = GC.** Onu da (a) basit mark-sweep seçip
|
||||
(b) modeli baştan GC-hazır kurarak de-risk ettik. **Kaçınılacak gerçek katil:
|
||||
refcount'u kalıcı model yapmak.**
|
||||
|
||||
---
|
||||
|
||||
## ADR-023: Eşitlik Semantiği — Referanslarda Kimlik Eşitliği (`==`)
|
||||
|
||||
### Bağlam
|
||||
|
||||
ADR-020 ile bileşik tipler referans. `==` / `!=` referans tipler için ne yapsın?
|
||||
Yapısal (derin) eşitlik sezgisel ama üç sorunu var: (1) büyük yapıda **derin
|
||||
gezinme maliyeti**, (2) yeni açtığımız **döngüsel grafta sonsuz döngü** riski
|
||||
(ziyaret-takibi şart), (3) seçtiğimiz referans modeliyle **tutarsız**.
|
||||
|
||||
### Karar
|
||||
|
||||
✅ **Kimlik eşitliği (A):**
|
||||
|
||||
| Kategori | `==` davranışı |
|
||||
|---|---|
|
||||
| Primitive (`int`/`float`/`bool`) | **değer** karşılaştırması (`3 == 3`) |
|
||||
| Referans (`struct`, `array`) | **kimlik** — aynı nesne mi? (işaretçi aynılığı) |
|
||||
| `string` | ⏸️ **#40'a bağlı** — aşağıdaki nota bak |
|
||||
| `null` | `null == null` → true; `null == nesne` → false; `a == null` null-daraltma deyimi (ADR-021) |
|
||||
|
||||
İçerik karşılaştırması istenirse **ayrı, niyeti görünür** bir mekanizmayla gelir
|
||||
(ileride builtin `deepEquals()` / PHP'nin `==` vs `===` vs `clone` ailesi gibi) —
|
||||
asla sessizce `==`'e bağlanmaz. Gerekçe: deepEqual'ı `==`'e bağlamak büyük/döngüsel
|
||||
yapılarda performans ve sonsuz-döngü tuzağıdır; "cam kutu, sürpriz yok" kimliğiyle
|
||||
de çelişir.
|
||||
|
||||
### ⚠️ String istisnası (Java gotcha'sı)
|
||||
|
||||
Saf kimlik eşitliğini string'e de uygularsak `"abc" == "abc"` → **false** olur —
|
||||
Java'nın en çok sövülen hatası. Çoğu dil string'i istisna yapar (JS'te string
|
||||
primitive → içerik; C# overload; Python intern). Bu yüzden **string'in `==`'i
|
||||
içerik eşitliği olmalı**, ki bu string'i **immutable değer-tipi** olarak modellemeyi
|
||||
güçlü biçimde öneriyor (bkz. #40). ADR-023 struct/array'i kilitler; string'in `==`'i
|
||||
#40'ta netleşir ama **varsayılan yön: içerik eşitliği.**
|
||||
|
||||
### Açık (ileride, çok uzak — şimdi karar değil)
|
||||
|
||||
- **`obj == obj`'i hata/uyarı yapmak:** kullanıcıyı niyetini açık yazmaya zorlamak
|
||||
(kimlik mi içerik mi). Daha katı bir duruş; v0'da `==` = kimlik serbest.
|
||||
- **Kullanıcı-tanımlı eşitlik (OOP'siz):** ileride bir tip için `equals(T,T)->bool`
|
||||
konvansiyonu veya benzeri ile `==`'i kullanıcının tanımlamasına izin vermek —
|
||||
operator-overload'un OOP'siz karşılığı. Çok uzak.
|
||||
|
||||
---
|
||||
|
||||
## ADR-024: String — Immutable Değer-Tipi, İç Temsil UTF-8
|
||||
|
||||
### Bağlam
|
||||
|
||||
ADR-020 string'i "bileşik (referans)" listesine `?` ile koymuştu; ADR-023 string
|
||||
`==`'inin **içerik** olmasını istedi (Java gotcha'sından kaçınmak için). İkisi de
|
||||
string'i değişmez-değer modeline itti.
|
||||
|
||||
### Karar
|
||||
|
||||
✅ **String = immutable (değişmez) değer-tipi; iç temsil UTF-8 bayt.**
|
||||
|
||||
- **Immutable:** oluşturulduktan sonra içeriği değişmez; `s = s + "x"` **yeni**
|
||||
string üretir, eskisini değiştirmez.
|
||||
- **`==` içerik eşitliği** (ADR-023 istisnası). Paylaşılınca değişmediği için
|
||||
içerik-eşitliği güvenlidir; aliasing sürprizi yok (JS'in string'i primitive gibi
|
||||
davranmasının sebebi budur).
|
||||
- **GC dostu:** serbestçe paylaşılır / intern edilebilir.
|
||||
- **İç temsil UTF-8** (Rust/Go/Swift hattı): kompakt, web-doğal, ASCII'de ucuz.
|
||||
`s[i]` **karakter** indeksi O(1) **değildir** → bayt / scalar / grapheme erişimi
|
||||
**açıkça** ayrılır; sahte O(1) vaat edilmez (Java/JS'in "uzunluk emoji'de yalan
|
||||
söylüyor" sürprizinden kaçın). Host tarafında `std::string` ham bayt olarak oturur.
|
||||
- **Verimli birleştirme** için ileride ayrı **builder** tipi (StringBuilder / `join`)
|
||||
— çekirdeği kirletmeden, döngüde O(n²)'den kaçınmak için.
|
||||
|
||||
### Etkilenen
|
||||
|
||||
- **#40** (string işlem yüzeyi) bu kararla netleşti; **#9** (iç temsil) = UTF-8.
|
||||
- ADR-020'deki string `?` işareti → "değer-tipi" olarak çözüldü.
|
||||
|
||||
---
|
||||
|
||||
## ADR-025: Hata Yönetim Modeli — Struct-Tabanlı Yakalanabilir Hatalar (Swift-tarzı)
|
||||
|
||||
### Bağlam
|
||||
|
||||
ADR-020 (struct = referans) → null bir struct alanına erişim/yazma ihtimali doğdu:
|
||||
klasik NullPointerException. ADR-021 statik analizi *kanıtlayabildiğini* derleme
|
||||
zamanında yakalar, ama `!` iddiası ve kanıtlanamayan durumlar (struct alanı,
|
||||
cross-fonksiyon) için bir **runtime backstop** gerekir. Ayrıca array OOB, /0 gibi
|
||||
faults. Java/C#/JS bunları **yakalanabilir** hata yapar — ama OOP exception
|
||||
hiyerarşisi (`extends Exception`) bizde yok.
|
||||
|
||||
### Karar
|
||||
|
||||
✅ **Yakalanabilir, struct-tabanlı hata modeli — OOP'siz.**
|
||||
Hata *değeri* Swift gibi (düz struct, hiyerarşi/extend yok); *görünürlük* Java/C#/JS
|
||||
gibi (**unchecked** — fonksiyon işaretlenmez, klasik `try{}catch{}`). "Exception'ın
|
||||
tanıdık catch-and-jump ergonomisi + OOP'suz değer."
|
||||
|
||||
1. **Hata değeri = standart built-in struct** — extend yok, OOP yok, deterministik:
|
||||
```
|
||||
struct Error {
|
||||
int line; // hata satırı
|
||||
int col; // sütun ("char" tip adıyla çakışmaması için col)
|
||||
string message; // insan-okunur (derleyicinin W/E kataloğundan)
|
||||
string trace; // stacktrace, en içten dışa
|
||||
string code; // makine-okunur W/E kodu (E010 vb.) — JSON/toolbox filtresi
|
||||
}
|
||||
```
|
||||
2. **try/catch (unwind + jump):** hata oluşunca en yakın çevreleyen `catch`'e
|
||||
zıplanır; `catch (e)` → `e : Error`.
|
||||
3. **Runtime null-deref = yakalanabilir hata** (NPE analoğu). ADR-021 statik
|
||||
analizinin **backstop'u**: `a!` patlayınca + analizin kanıtlayamadığı durumlar.
|
||||
Array OOB ve /0 da aynı kapıdan.
|
||||
4. **`throw`** ile kullanıcı da hata kaldırabilir (`Error` doldurup).
|
||||
5. **Determinizm:** unwind deterministik; stacktrace frame'lerden üretilir;
|
||||
time-travel/replay handle eklenebilir.
|
||||
|
||||
### Görünürlük — KARAR: (ii) görünmez / unchecked (Java/C#/JS usulü)
|
||||
|
||||
✅ **Fonksiyonlar işaretlenmez.** "Bu hata yapabilir / yapamaz" anotasyonu **YOK**
|
||||
(C++'ın `noexcept`/`constexpr` benzeri kirlilik istenmiyor). Çağrıda `try f()`
|
||||
işareti de yok. **Klasik `try { ... } catch (e) { ... }` bloğu** — "anam babam usulü".
|
||||
|
||||
**Gerekçe:** developer'a **güven** + insanların derin try-catch alışkanlığını bozmamak
|
||||
(sözdizimini tanıdık tut, içgüdüye dokunma). Hatalar zaten çoğunlukla FFI, bellek
|
||||
dolması ve derleyici-içi durumlardan doğar; her çağrıyı işaretlemenin bedeli faydadan
|
||||
büyük.
|
||||
|
||||
> Not: Bu, `Type?` (explicit nullable) ile **bilinçli** felsefi ayrışmadır — null
|
||||
> *tipte* görünür, ama hata akışı *blok* düzeyinde tanıdık tutulur. Reddedilen (i):
|
||||
> Swift/Zig'in imza-işaretli + çağrıda `try f()` modeli.
|
||||
|
||||
### Stacktrace mekaniği (modelden bağımsız önkoşul)
|
||||
|
||||
- Her `CallFrame` → `IRFunction` + komut işaretçisi; **IR'a satır tablosu**
|
||||
(komut index → kaynak konum) eklenir (önce taşıyıp taşımadığı doğrulanmalı).
|
||||
- panic/throw'da frame stack gezilir → `fonksiyon + konum`, en içten dışa → `trace`.
|
||||
- Sunum: derleme-zamanı diagnostic ile **aynı kabuk** (kod + mesaj + konum +
|
||||
"nasıl düzelt" #20), hem insan hem **JSON** (toolbox: her hata yapılandırılmış nesne).
|
||||
- Farklılaştırıcı: deterministik → trace'e adım indeksi → hataya **geri sar**.
|
||||
|
||||
### İlişkili güncellemeler
|
||||
|
||||
- **ADR-014 "tuple yok" → "tuple ERTELENDİ"** (reddedilmedi; çoklu-dönüş kodu
|
||||
spagettileştirir, şimdilik uzak ama masada — `interface` gibi).
|
||||
- **`finally` yerine ileride `defer`** (GC'li, RAII'siz dilde daha temiz). Ayrı küçük karar.
|
||||
- ADR-021 ile uyum: statik analiz provable null'ı yakalar; bu hata onun backstop'u + `!`.
|
||||
|
||||
---
|
||||
|
||||
## ADR-026: Tip Dönüşümü — `as` (Skaler/String), Başarısızlık Hedef Tipinin Nullable'lığıyla
|
||||
|
||||
### Bağlam
|
||||
|
||||
ADR-010 "gizli int↔float yok" → değişken-değişken dönüşüm **açık** olmalı. float
|
||||
runtime'ı var ama cast sözdizimi yoktu → int↔float dönüşümü imkânsızdı. Ayrıca
|
||||
elimizde null (ADR-021) + hata (ADR-025) modelleri var; cast bunlarla örtüşmeli.
|
||||
|
||||
### Karar
|
||||
|
||||
✅ **Sözdizimi: `as` (infix, sola-bağlı).** `deger as int`.
|
||||
- Sola-bağlı olduğu için zincir **lineer** okunur: `a as int as string` =
|
||||
`((a as int) as string)`, parantez gerekmez (fonksiyon-stili `int(float(a))`'nın
|
||||
iç içe çirkinliği yok).
|
||||
- `int(x)` fonksiyon-stili **reddedildi** ("int adlı fonksiyon mu, cast mı"
|
||||
belirsizliği); C-tarzı `(int)x` ve `static_cast<>` reddedildi.
|
||||
|
||||
✅ **Kapsam: yalnızca skaler + string** (`int`/`float`/`bool`/`string` arası).
|
||||
- **Struct/array cast'e GİRMEZ.** Farklı struct'lar ayrı tiplerdir; "dönüşümleri"
|
||||
geliştiricinin yazdığı **açık yapıcı fonksiyonlarla** olur (`Employee yap(Person p)`).
|
||||
Gerekçe: yapısal/duck eşleme veya reinterpret = derleyiciyi karmaşıklaştırır +
|
||||
sessiz alan kaybı = hataya açık. OOP'siz "cage" kimliğiyle uyumsuz.
|
||||
|
||||
✅ **Başarısızlık davranışı = HEDEF TİPİN nullable'lığı** (ayrı `as?` operatörü YOK):
|
||||
- `x as int` → hedef non-null → başarısızsa **`Error` fırlatır** (ADR-025), sonuç `int`.
|
||||
- `x as int?` → hedef nullable → başarısızsa **`null` döner**, sonuç `int?`.
|
||||
|
||||
Nullable her zaman **tipte** (`?`) yaşar, ayrı operatör icat edilmez. Sonra `int?`'i
|
||||
`int`'e çevirmek için **narrowing** (`if`) gerekir — `!`/`??` yasak (ADR-021).
|
||||
|
||||
### Dönüşüm matrisi
|
||||
|
||||
| Dönüşüm | Hatasız mı? | Not |
|
||||
|---|---|---|
|
||||
| `int → float` | ✅ hatasız | büyük int'te kesinlik kaybı olabilir, patlamaz |
|
||||
| `int → string`, `float → string` | ✅ hatasız | biçimlendirme |
|
||||
| `string → int`/`float` | ⚠️ fallible | parse; `"abc"` → `as int` fırlatır / `as int?` null |
|
||||
| `float → int` | ⚠️ fallible | sonlu & aralık-içi: **sıfıra doğru kırpılır** (`1.71→1`, `-1.71→-1`); NaN/Inf/taşma → fırlatır / null |
|
||||
| `bool ↔ int` | (karar) | başta yasak tutmak en güvenlisi; gerekirse açılır |
|
||||
|
||||
### Örnek (ADR-021 ile birlikte)
|
||||
|
||||
```
|
||||
int a = 1.71 as int?; // ✗ DERLEME HATASI: int? → int (daraltma); cast başarılı olsa bile statik tip int?
|
||||
int a = 1.71 as int; // ✓ a = 1 (kırpma); başarısızsa Error
|
||||
int? a = 1.71 as int?; // ✓ tipler eşit
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Kararların Özet Tablosu
|
||||
|
||||
| ADR | Konu | Karar |
|
||||
|---|---|---|
|
||||
| 006 | Frontend mimarisi | Çok-aşamalı; frontend/middle-end/backend katmanları |
|
||||
| 007 | Analiz vs optimizasyon | Analiz yerinde işaretler; optimizasyon klonda dönüştürür; `clone()` merkezi, sembol tablosu remap edilir |
|
||||
| 007 | Analiz vs optimizasyon | Analiz yerinde; `ast` komutu klon üstünde dönüştürür (öncesi/sonrası karşılaştırması); `run`/`ir` yerinde optimize eder (klon yok); sembol bağları salt-okunur paylaşım (remap gerekmez) |
|
||||
| 008 | Optimizasyon konumu | Basitler AST'de, dataflow gerektirenler IR'de |
|
||||
| 009 | Pass yönetimi | Fixpoint döngüsü, toggle'lı; monotonluk/iterasyon-tavanı değişmezi; akışa-bağlı analiz tur başına tazelenir |
|
||||
| 010 | Tip sistemi | Minimal+genişletilebilir Type; gizli dönüşüm yok; Error tipi; tamsayı literali bağlama-göre tiplenir |
|
||||
|
|
@ -680,3 +1128,10 @@ modelini birlikte zorlar — ikisi de bu yüzden ertelendi.
|
|||
| 017 | Batteries/stdlib | Sınır problemi; küçük builtin + FFI/kütüphane; ertelendi |
|
||||
| 018 | `interface` | Ertelendi (reddedilmedi); struct+fonksiyon yeter |
|
||||
| 019 | Frontend↔runtime | Frontend yapı+anlam; çekirdek/cihaz/çıktı runtime'a ait |
|
||||
| 020 | Değer/referans semantiği | Primitive=değer, bileşik (struct/array/string)=referans; "pointer yok"=`&`/`*` sözdizimi yok; kaçma/lifetime problemi bilinçli açıldı → GC borcu (#56); ADR-014'ün "GC gerekmez" sonucu iptal |
|
||||
| 021 | Null güvenliği | `Type?` nullable, varsayılan non-null; akış-duyarlı null analizi (compile-time, runtime maliyeti sıfır); `!` runtime-kontrollü non-null iddiası |
|
||||
| 022 | Bellek geri-kazanımı | Basit taşımasız stop-the-world mark-sweep (deterministik); nesne modeli baştan GC-hazır (header+root+child); v1 toplamasız, v2 mark-sweep; refcount kalıcı model DEĞİL; #56'nın yönü |
|
||||
| 023 | Eşitlik semantiği | `==` = primitive değer / referans (struct,array) **kimlik**; deepEqual asla `==`'e bağlanmaz (ayrı `deepEquals()`); string `==` içerik (→ #40, Java gotcha'sından kaçın); `obj==obj` hata + kullanıcı-tanımlı eşitlik = uzak gelecek |
|
||||
| 024 | String | Immutable değer-tipi, iç temsil **UTF-8**; `==` içerik; mutasyon yeni string üretir; bayt/scalar/grapheme açıkça ayrı; verimli birleştirme için ileride builder; #40/#9'u çözer |
|
||||
| 025 | Hata yönetimi | Struct-tabanlı yakalanabilir hata (değer Swift gibi, OOP yok); standart `Error{line,col,message,trace,code}`; klasik `try{}catch{}` **unchecked** (fonksiyon işaretsiz, Java usulü); runtime null-deref/OOB yakalanabilir (esasen FFI backstop); deterministik stacktrace (IR satır tablosu); tuple→ertelendi; finally→`defer`; #57 |
|
||||
| 026 | Tip dönüşümü | `as` (infix, sola-bağlı), yalnızca skaler+string; struct/array cast YOK (elle yapıcı fonksiyon); başarısızlık hedef nullable'lığıyla (`as int` fırlatır / `as int?` null); float→int kırpma; #42 |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
# 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.
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
# 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.
|
||||
|
|
@ -18,9 +18,10 @@
|
|||
> **ç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:** ADR-001'deki "mevcut durum" listesi hâlâ doğrudur
|
||||
> (lexer/tokenizer/parser/AST + minimal IR deneyi çalışır); kod üretimi ve VM
|
||||
> **henüz yoktur.**
|
||||
> - **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`.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,421 @@
|
|||
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()
|
||||
|
|
@ -0,0 +1,406 @@
|
|||
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
|
||||
|
|
@ -10,21 +10,12 @@
|
|||
> yorum satırlarıyla takip edilebilir olmalıdır (header-only tarzı korunur,
|
||||
> bkz. ADR-003).
|
||||
>
|
||||
> ⚠️ **Yapılan vs planlanan:** Bugün çalışan = lexer, tokenizer, Pratt parser,
|
||||
> AST, AST'nin JSON serileştirmesi, CLI iskeleti, konum takibi, basit aritmetiği
|
||||
> düşüren minimal IR deneyi. Bu yol haritasındaki **her şey planlıdır** (sembol
|
||||
> tablosu, semantik analiz, tip sistemi, diagnostic, optimizasyon).
|
||||
> ✅ **Birinci kilometre taşı AŞILDI.** Faz 0–4 uygulandı; `examples/fibonacci.sqt`
|
||||
> uçtan uca çalışıyor. Bu yol haritası artık tarihsel bir referanstır.
|
||||
>
|
||||
> 🎯 **Bu haftanın işi:** **sembol tablosu + iki-geçişli toplayıcı** (Faz 2),
|
||||
> hedef **"fibonacci'yi derle ve çalıştır"** (`examples/fibonacci.sqt`). Faz 0–1
|
||||
> bunun önkoşuludur.
|
||||
>
|
||||
> 🧭 **Önce dikey dilim, sonra çerçeve.** Bir şey çalışmadan önce genel pass
|
||||
> manager / evrensel config / ağır soyutlama inşa etme. Uçtan uca tek bir dilim
|
||||
> (kaynak → IR → çalıştır; tamsayı + değişken + kontrol akışı + tek `print`)
|
||||
> önce çalışsın. Faz 4'ün framework'ü (OptimizationManager, fixpoint, config)
|
||||
> ancak Faz 0–3 fibonacci'yi geçirdikten **sonra** anlam kazanır — erken
|
||||
> soyutlama daha az değil, daha çok karmaşıklıktı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`.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -46,7 +37,7 @@ Katman eşlemesi (ADR-006):
|
|||
|
||||
---
|
||||
|
||||
## Faz 0 — Temeller (Type + Diagnostic + Hata Kataloğu)
|
||||
## ✅ 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).
|
||||
|
|
@ -91,7 +82,7 @@ Katman eşlemesi (ADR-006):
|
|||
|
||||
---
|
||||
|
||||
## Faz 1 — AST Refactor (ExpressionNode / StatementNode + analiz alanları)
|
||||
## ✅ 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.
|
||||
|
|
@ -116,7 +107,7 @@ ayır, analiz alanlarını ekle. İlgili ADR: 012, 013.
|
|||
|
||||
---
|
||||
|
||||
## Faz 2 — Symbol Table (scope'lu, iki-geçişli toplama)
|
||||
## ✅ 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.
|
||||
|
|
@ -150,7 +141,7 @@ ayır, analiz alanlarını ekle. İlgili ADR: 012, 013.
|
|||
|
||||
---
|
||||
|
||||
## Faz 3 — Semantic Analiz (Tip Kontrolü + Yapısal Doğrulama)
|
||||
## ✅ 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.
|
||||
|
|
@ -173,7 +164,7 @@ doğrula. İlgili ADR: 010, 013.
|
|||
|
||||
---
|
||||
|
||||
## Faz 4 — Optimizasyon Framework
|
||||
## ✅ 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.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,186 @@
|
|||
# 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. |
|
||||
|
||||
Açı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ı açı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.
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,5 @@
|
|||
int main() {
|
||||
print("Merhaba");
|
||||
print("saQut calisiyor");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// Ö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");
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// E003 — return tipi uyuşmazlığı
|
||||
int foo() {
|
||||
return 1.5;
|
||||
}
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
// E004 — break döngü dışında
|
||||
int main() {
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
// E003 — daraltma: float literal → int
|
||||
int main() {
|
||||
int x = 1.5;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
// 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// E010 — döngüsel struct (by-value çevrim → sonsuz boyut)
|
||||
struct A {
|
||||
B b;
|
||||
}
|
||||
|
||||
struct B {
|
||||
A a;
|
||||
}
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
// E002 — aynı scope'ta çift tanım
|
||||
int main() {
|
||||
int x = 1;
|
||||
int x = 2;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
// E001 — tanımsız isim
|
||||
int main() {
|
||||
int x = y + 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
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;
|
||||
}
|
||||
307
readme.md
307
readme.md
|
|
@ -1,185 +1,186 @@
|
|||
# saQut
|
||||
|
||||
**Programlanabilir, incelenebilir bir derleyici — bir "alet çantası" (toolbox).**
|
||||
> **A compiler built as a toolbox, not a black box —**
|
||||
> every internal phase is a first-class, inspectable output.
|
||||
|
||||
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.
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
Uygulama dili **C++**'tır (header-only eğilimli, bkz. `docs/fikirler.md` ADR-003).
|
||||
Most compilers are black boxes. saQut is a **glass box.**
|
||||
|
||||
---
|
||||
|
||||
## Şu an ne çalışıyor, ne çalışmıyor
|
||||
## What is it?
|
||||
|
||||
Belgeler **planlanan** ile **yapılan**ı net ayırır. Bugünkü gerçek durum:
|
||||
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.**
|
||||
|
||||
### ✅ Ç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`.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## Dil kimliği (kilitli)
|
||||
## The language looks like this
|
||||
|
||||
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).
|
||||
```c
|
||||
int fibonacci(int n) {
|
||||
if (n <= 1) {
|
||||
return n;
|
||||
}
|
||||
return fibonacci(n - 1) + fibonacci(n - 2);
|
||||
}
|
||||
|
||||
| Özellik | Karar |
|
||||
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));
|
||||
print(fibonacciIterative(n));
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
- 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
|
||||
|
||||
**Deliberately absent:** OOP, closures, generics, implicit int↔float coercion, `auto`.
|
||||
|
||||
---
|
||||
|
||||
## Build
|
||||
|
||||
**Requirements:** C++17, CMake ≥ 3.16, Ninja
|
||||
|
||||
```bash
|
||||
git clone https://github.com/abdussamedulutas/saqut
|
||||
cd saqut
|
||||
cmake -B build -G Ninja
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
Binary lands at `build/saqut`.
|
||||
|
||||
**Tested on:** Linux (x86-64, Manjaro). macOS and Windows untested but no platform-specific code.
|
||||
|
||||
---
|
||||
|
||||
## CLI
|
||||
|
||||
| Command | What you get |
|
||||
|---|---|
|
||||
| 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) |
|
||||
| `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 |
|
||||
|
||||
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.
|
||||
Every output is designed to be piped, diffed, or consumed by other tools.
|
||||
|
||||
---
|
||||
|
||||
## Ç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.
|
||||
|
||||
---
|
||||
|
||||
## Mimari hatlar
|
||||
## Pipeline
|
||||
|
||||
```
|
||||
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 ┘
|
||||
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
|
||||
```
|
||||
|
||||
- **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.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## CLI (mevcut + planlanan)
|
||||
## What works right now
|
||||
|
||||
```
|
||||
# --- ç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 |
|
||||
| Stage | Status |
|
||||
|---|---|
|
||||
| `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 |
|
||||
| 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` | 🚧 |
|
||||
|
||||
---
|
||||
|
||||
## İlke
|
||||
## Philosophy in two sentences
|
||||
|
||||
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.
|
||||
**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.
|
||||
|
||||
The long version is in [`docs/architecture.md`](docs/architecture.md).
|
||||
|
||||
---
|
||||
|
||||
## Design records
|
||||
|
||||
Architectural decisions live in `docs/`:
|
||||
|
||||
| File | Coverage |
|
||||
|---|---|
|
||||
| [`docs/fikirler.md`](docs/fikirler.md) | ADR-001–005: backend strategy, parser, header-only, token, IR |
|
||||
| [`docs/adr-frontend-analiz.md`](docs/adr-frontend-analiz.md) | ADR-006–019: 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) |
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,153 @@
|
|||
"""
|
||||
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)")
|
||||
|
|
@ -32,6 +32,8 @@ 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
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
|
|
@ -67,6 +69,14 @@ 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;
|
||||
|
|
@ -83,8 +93,9 @@ 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 == "compile" || arg == "parse" ||
|
||||
arg == "transpile" || arg == "interpret") {
|
||||
arg == "symbols" || arg == "check" || arg == "ir" ||
|
||||
arg == "compile" || arg == "parse" || arg == "transpile" ||
|
||||
arg == "interpret") {
|
||||
args.command = arg;
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -10,6 +13,13 @@
|
|||
#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) {
|
||||
|
|
@ -28,9 +38,25 @@ inline int cmdAst(const CliArgs& args) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
AstAnalysis analysis = analyzeAst(ast);
|
||||
// ── 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);
|
||||
|
||||
// Çıktı hedefi
|
||||
std::ostream* out = &std::cout;
|
||||
std::ofstream outFile;
|
||||
if (!args.outputFile.empty()) {
|
||||
|
|
@ -40,12 +66,16 @@ inline int cmdAst(const CliArgs& args) {
|
|||
|
||||
*out << "{\n"
|
||||
<< " \"ast\":\n"
|
||||
<< jsonIndent(2) << astToJson(ast, 2) << ",\n"
|
||||
<< jsonIndent(2) << astToJson(displayAst, 2) << ",\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;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
#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
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#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
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
// ============================================================================
|
||||
// saQut CLI — run komutu (pipeline: token → AST → IR debug)
|
||||
// ============================================================================
|
||||
// saQut CLI — run komutu
|
||||
//
|
||||
// TODO: İleride `saqut -` ile stdin'den okuyup anında çalıştıracak
|
||||
// interpreter modu bu komutun altına gelecek.
|
||||
// Tam derleme + çalıştırma pipeline'ı:
|
||||
// tokenize → parse → sembol topla → [opsiyonel: optimize] → IR üret → VM çalıştır
|
||||
//
|
||||
// --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
|
||||
|
|
@ -14,53 +16,78 @@
|
|||
#include "cli/args.hpp"
|
||||
#include "tokenizer/tokenizer.hpp"
|
||||
#include "parser/parser.hpp"
|
||||
#include "ir/ir.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"
|
||||
|
||||
inline int cmdRun(const CliArgs& args) {
|
||||
std::string source = readSource(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, inputFilePath(args));
|
||||
|
||||
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";
|
||||
auto tokens = tokenizer.scan(source, filePath);
|
||||
|
||||
// ── Aşama 2: Parse ───────────────────────────────────────────────────
|
||||
Parser parser;
|
||||
ASTNode* ast = parser.parse(tokens);
|
||||
|
||||
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;
|
||||
}
|
||||
std::cout << " (" << op.arg1.value.index() << ")\n";
|
||||
}
|
||||
|
||||
delete ast;
|
||||
if (!ast) {
|
||||
std::cerr << "Hata: AST üretilemedi\n";
|
||||
for (auto* t : tokens) delete t;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ── 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;
|
||||
}
|
||||
|
||||
delete ast;
|
||||
for (auto* t : tokens) delete t;
|
||||
return 0;
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
#endif // SAQUT_CLI_RUN
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// ============================================================================
|
||||
// saQut CLI — symbols komutu (sembol tablosu)
|
||||
// saQut CLI — symbols komutu (sembol tablosu — JSON çıktı, Faz 2)
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SAQUT_CLI_SYMBOLS
|
||||
|
|
@ -9,50 +9,62 @@
|
|||
#include "cli/args.hpp"
|
||||
#include "tokenizer/tokenizer.hpp"
|
||||
#include "parser/parser.hpp"
|
||||
#include "json.hpp"
|
||||
#include "symbol/symbol_table.hpp"
|
||||
#include "symbol/symbol_collector.hpp"
|
||||
#include "diagnostic/diagnostic_engine.hpp"
|
||||
#include "vendor/nlohmann/json.hpp"
|
||||
|
||||
inline int cmdSymbols(const CliArgs& args) {
|
||||
std::string source = readSource(args);
|
||||
std::string filePath = inputFilePath(args);
|
||||
std::string source = readSource(args);
|
||||
if (source.empty()) return 1;
|
||||
|
||||
Tokenizer tokenizer;
|
||||
auto tokens = tokenizer.scan(source, inputFilePath(args));
|
||||
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 table;
|
||||
DiagnosticEngine diag;
|
||||
|
||||
if (ast) {
|
||||
SymbolCollector(table, diag).collect(ast);
|
||||
} else {
|
||||
diag.report("E000", SourceLocation{}, "AST üretilemedi");
|
||||
}
|
||||
|
||||
auto symbols = collectSymbols(ast);
|
||||
// ── JSON çıktı ──────────────────────────────────────────────────────────
|
||||
nlohmann::json out;
|
||||
out["file"] = filePath;
|
||||
|
||||
std::cout << "Sembol Tablosu (" << symbols.size() << " sembol):\n";
|
||||
std::cout << "────────────────────────────────────────────\n";
|
||||
nlohmann::json symArray = nlohmann::json::array();
|
||||
for (Symbol* s : table.allSymbols()) {
|
||||
if (s->isBuiltin) continue;
|
||||
|
||||
if (symbols.empty()) {
|
||||
std::cout << " (sembol bulunamadı)\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}
|
||||
});
|
||||
}
|
||||
out["symbols"] = symArray;
|
||||
out["diagnostics"] = diag.toJsonObj();
|
||||
|
||||
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";
|
||||
std::cout << (args.compact ? out.dump() : out.dump(2)) << "\n";
|
||||
|
||||
delete ast;
|
||||
for (auto* t : tokens) delete t;
|
||||
return 0;
|
||||
return diag.hasErrors() ? 1 : 0;
|
||||
}
|
||||
|
||||
#endif // SAQUT_CLI_SYMBOLS
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
#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
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
#define SAQUT_CORE_LOCATION
|
||||
|
||||
#include <string>
|
||||
#include "vendor/nlohmann/json.hpp"
|
||||
|
||||
// ============================================================================
|
||||
// SourceLocation — Kaynak Koddaki Bir Nokta
|
||||
|
|
@ -66,15 +67,17 @@ struct SourceLocation {
|
|||
}
|
||||
|
||||
// JSON formatı: {"file":"...","line":5,"column":10,"offset":134}
|
||||
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) +
|
||||
"}";
|
||||
nlohmann::json toJsonObj() const {
|
||||
if (!isValid()) return nullptr;
|
||||
return {
|
||||
{"file", filePath},
|
||||
{"line", line},
|
||||
{"column", column},
|
||||
{"offset", offset}
|
||||
};
|
||||
}
|
||||
|
||||
std::string toJson() const { return toJsonObj().dump(); }
|
||||
};
|
||||
|
||||
#endif // SAQUT_CORE_LOCATION
|
||||
|
|
|
|||
|
|
@ -0,0 +1,285 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
#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";
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -0,0 +1,975 @@
|
|||
#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();
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#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";
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -79,7 +79,7 @@ std::string Lexer::getPositionRange() {
|
|||
// --------------------------------------------------------------------------
|
||||
// include: Belirtilen kelime mevcut konumda başlıyor mu?
|
||||
// --------------------------------------------------------------------------
|
||||
bool Lexer::include(std::string word, bool accept) {
|
||||
bool Lexer::include(std::string_view word, bool accept) {
|
||||
beginPosition();
|
||||
for (size_t i = 0; i < word.size(); i++) {
|
||||
if (isEnd()) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include "core/location.hpp"
|
||||
#include "core/sourcefile.hpp"
|
||||
|
|
@ -67,7 +68,7 @@ public:
|
|||
std::string getPositionRange(); // Pozisyon aralığındaki metni döndür
|
||||
|
||||
// --- Desen Eşleme ---
|
||||
bool include(std::string word, bool accept = true);
|
||||
bool include(std::string_view word, bool accept = true);
|
||||
|
||||
// --- Konum Okuma/Yazma ---
|
||||
int getOffset(); // Mevcut offset'i döndür
|
||||
|
|
|
|||
10
src/main.cpp
10
src/main.cpp
|
|
@ -27,6 +27,8 @@
|
|||
#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
|
||||
|
|
@ -48,6 +50,14 @@ 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",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,286 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -0,0 +1,371 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
// ============================================================================
|
||||
// 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
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#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
|
||||
|
|
@ -187,7 +187,10 @@ public:
|
|||
if (m_hasFields) m_ss << ",\n";
|
||||
m_ss << m_indentInner << "\"" << jsonEscape(key) << "\": [";
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include "core/location.hpp"
|
||||
#include "core/type.hpp"
|
||||
#include "parser/token.hpp"
|
||||
#include "tools.hpp"
|
||||
|
||||
|
|
@ -86,6 +87,8 @@ 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ğ.
|
||||
|
|
@ -106,6 +109,8 @@ 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, ...]
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
|
|
@ -235,10 +240,12 @@ public:
|
|||
// KARMAŞIKLIK: O(1) — referans döndürür
|
||||
std::vector<ASTNode*>& getChildren() { return children; }
|
||||
|
||||
// ~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;
|
||||
// ~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;
|
||||
}
|
||||
|
||||
protected:
|
||||
// children — Alt düğümlerin vektörü.
|
||||
|
|
@ -247,6 +254,47 @@ 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
|
||||
// ============================================================================
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ 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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@
|
|||
|
||||
#include "parser/ast_node.hpp"
|
||||
|
||||
class BinaryExpressionNode : public ASTNode {
|
||||
class BinaryExpressionNode : public ExpressionNode {
|
||||
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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
// 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);
|
||||
|
|
@ -12,6 +13,9 @@ 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));
|
||||
});
|
||||
|
|
@ -30,6 +34,7 @@ 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();
|
||||
|
|
|
|||
|
|
@ -3,21 +3,26 @@
|
|||
|
||||
#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 ASTNode {
|
||||
class VariableDeclNode : public StatementNode {
|
||||
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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ 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();
|
||||
}
|
||||
|
|
@ -30,6 +31,7 @@ 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();
|
||||
}
|
||||
|
|
@ -46,6 +48,24 @@ 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();
|
||||
}
|
||||
|
|
@ -62,6 +82,7 @@ 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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,39 +3,52 @@
|
|||
|
||||
#include "parser/ast_node.hpp"
|
||||
|
||||
class PostfixNode : public ASTNode {
|
||||
class PostfixNode : public ExpressionNode {
|
||||
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 ASTNode {
|
||||
class CallExpressionNode : public ExpressionNode {
|
||||
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 ASTNode {
|
||||
class MemberAccessNode : public ExpressionNode {
|
||||
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 ASTNode {
|
||||
class IndexExpressionNode : public ExpressionNode {
|
||||
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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "parser/nodes/identifier.hpp"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "parser/ast_json.hpp"
|
||||
|
||||
IdentifierNode::IdentifierNode() { kind = ASTKind::Identifier; }
|
||||
|
|
@ -11,13 +10,10 @@ void IdentifierNode::log(int indent) {
|
|||
}
|
||||
|
||||
std::string IdentifierNode::toJson(int depth) {
|
||||
std::string in = jsonIndent(depth);
|
||||
std::string name = parserToken.token ? parserToken.token->token : "?";
|
||||
std::ostringstream ss;
|
||||
ss << "{\n"
|
||||
<< in << " \"kind\": \"Identifier\",\n"
|
||||
<< in << " \"name\": \"" << jsonEscape(name) << "\",\n"
|
||||
<< in << " \"location\": " << loc.toJson() << "\n"
|
||||
<< in << "}";
|
||||
return ss.str();
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,16 @@
|
|||
|
||||
#include "parser/ast_node.hpp"
|
||||
|
||||
class IdentifierNode : public ASTNode {
|
||||
struct Symbol; // TODO(faz-2): sembol tablosu (Symbol) tanımlandığında bağlanacak
|
||||
|
||||
class IdentifierNode : public ExpressionNode {
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -1,34 +1,33 @@
|
|||
#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 {" << (parserToken.token ? parserToken.token->token : "?") << "} "
|
||||
<< "Literal {" << val << "} "
|
||||
<< 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 in = jsonIndent(depth);
|
||||
std::string val = parserToken.token ? parserToken.token->token : "?";
|
||||
std::ostringstream ss;
|
||||
ss << "{\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();
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "parser/ast_node.hpp"
|
||||
|
||||
class LiteralNode : public ASTNode {
|
||||
class LiteralNode : public ExpressionNode {
|
||||
public:
|
||||
Token* lexerToken = nullptr;
|
||||
ParserToken parserToken;
|
||||
|
|
@ -12,6 +12,11 @@ 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;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ 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();
|
||||
}
|
||||
|
|
@ -31,6 +32,7 @@ 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();
|
||||
}
|
||||
|
|
@ -47,6 +49,7 @@ 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();
|
||||
}
|
||||
|
|
@ -67,6 +70,7 @@ 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();
|
||||
}
|
||||
|
|
@ -83,6 +87,7 @@ 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();
|
||||
}
|
||||
|
|
@ -97,6 +102,7 @@ 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();
|
||||
}
|
||||
|
|
@ -109,6 +115,7 @@ 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();
|
||||
}
|
||||
|
|
@ -121,6 +128,7 @@ 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();
|
||||
}
|
||||
|
|
@ -135,6 +143,40 @@ 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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,78 +3,106 @@
|
|||
|
||||
#include "parser/ast_node.hpp"
|
||||
|
||||
class BlockNode : public ASTNode {
|
||||
class BlockNode : public StatementNode {
|
||||
public:
|
||||
BlockNode();
|
||||
void log(int indent = 0) override;
|
||||
std::string toJson(int depth = 0) override;
|
||||
};
|
||||
|
||||
class IfStatementNode : public ASTNode {
|
||||
class IfStatementNode : public StatementNode {
|
||||
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 ASTNode {
|
||||
class WhileStatementNode : public StatementNode {
|
||||
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 ASTNode {
|
||||
class ForStatementNode : public StatementNode {
|
||||
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 ASTNode {
|
||||
class DoWhileStatementNode : public StatementNode {
|
||||
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 ASTNode {
|
||||
class ReturnStatementNode : public StatementNode {
|
||||
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 ASTNode {
|
||||
class BreakStatementNode : public StatementNode {
|
||||
public:
|
||||
BreakStatementNode();
|
||||
void log(int indent = 0) override;
|
||||
std::string toJson(int depth = 0) override;
|
||||
};
|
||||
|
||||
class ContinueStatementNode : public ASTNode {
|
||||
class ContinueStatementNode : public StatementNode {
|
||||
public:
|
||||
ContinueStatementNode();
|
||||
void log(int indent = 0) override;
|
||||
std::string toJson(int depth = 0) override;
|
||||
};
|
||||
|
||||
class ExpressionStatementNode : public ASTNode {
|
||||
class ExpressionStatementNode : public StatementNode {
|
||||
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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -63,11 +63,13 @@ ASTNode* Parser::parseProgram() {
|
|||
ProgramNode* program = new ProgramNode();
|
||||
|
||||
while (currentToken().type != TokenType::SVR_VOID) {
|
||||
int prevPos = current;
|
||||
ASTNode* decl = parseDeclaration();
|
||||
if (decl)
|
||||
program->addChild(decl);
|
||||
else
|
||||
break;
|
||||
// İlerleme olmadıysa token atla — syntax hatasında sonsuz döngüyü önler
|
||||
if (current == prevPos)
|
||||
nextToken();
|
||||
}
|
||||
|
||||
return program;
|
||||
|
|
@ -83,14 +85,36 @@ 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();
|
||||
}
|
||||
|
||||
|
|
@ -138,6 +162,23 @@ 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,
|
||||
|
|
@ -287,14 +328,46 @@ 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)
|
||||
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;
|
||||
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();
|
||||
}
|
||||
|
|
@ -334,6 +407,18 @@ 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;
|
||||
|
|
@ -342,6 +427,7 @@ 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 &&
|
||||
|
|
@ -350,6 +436,7 @@ ASTNode* Parser::parseVariableDecl() {
|
|||
nextToken();
|
||||
if (currentToken().type == TokenType::RBRACKET)
|
||||
nextToken();
|
||||
if (vd->varType.back() != ']') vd->varType += "[]";
|
||||
}
|
||||
|
||||
if (currentToken().type == TokenType::EQUAL) {
|
||||
|
|
@ -422,6 +509,12 @@ 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,
|
||||
|
|
@ -433,6 +526,15 @@ 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();
|
||||
}
|
||||
|
||||
|
|
@ -597,3 +699,43 @@ 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ private:
|
|||
ASTNode* parseBreakStatement();
|
||||
ASTNode* parseContinueStatement();
|
||||
ASTNode* parseExpressionStatement();
|
||||
ASTNode* parseTryStatement();
|
||||
ASTNode* parseThrowStatement();
|
||||
|
||||
// --- İfadeler (Pratt parser) ---
|
||||
ASTNode* parseExpression();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
#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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#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
|
||||
|
|
@ -0,0 +1,572 @@
|
|||
#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;
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
#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
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#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
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef SAQUT_SYMBOL_SYMBOL
|
||||
#define SAQUT_SYMBOL_SYMBOL
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "core/type.hpp"
|
||||
#include "core/location.hpp"
|
||||
|
||||
enum class SymbolKind { Variable, Function, Parameter, Struct, Field };
|
||||
|
||||
inline const char* symbolKindName(SymbolKind k) {
|
||||
switch (k) {
|
||||
case SymbolKind::Variable: return "variable";
|
||||
case SymbolKind::Function: return "function";
|
||||
case SymbolKind::Parameter: return "parameter";
|
||||
case SymbolKind::Struct: return "struct";
|
||||
case SymbolKind::Field: return "field";
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
class Scope;
|
||||
|
||||
struct Symbol {
|
||||
std::string name;
|
||||
SymbolKind kind = SymbolKind::Variable;
|
||||
Type type;
|
||||
SourceLocation definitionLoc;
|
||||
std::vector<SourceLocation> references;
|
||||
Scope* scope = nullptr;
|
||||
bool isBuiltin = false;
|
||||
};
|
||||
|
||||
#endif // SAQUT_SYMBOL_SYMBOL
|
||||
|
|
@ -0,0 +1,379 @@
|
|||
#include "symbol/symbol_collector.hpp"
|
||||
#include <functional>
|
||||
#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"
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// collect — dört aşamalı toplama
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
void SymbolCollector::collect(ASTNode* program) {
|
||||
if (!program) return;
|
||||
seedBuiltins();
|
||||
pass1Globals(program);
|
||||
checkStructCycles();
|
||||
pass2Bodies(program);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// seedBuiltins — global scope'a yerleşik fonksiyonları ekle
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
void SymbolCollector::seedBuiltins() {
|
||||
// TODO(#89 builtin kataloğu): geçici; ileride gerçek katalog gelecek.
|
||||
Symbol* s = table_.define("print", SymbolKind::Function,
|
||||
Type::function(Type::Void(), {}),
|
||||
SourceLocation{});
|
||||
if (s) s->isBuiltin = true;
|
||||
|
||||
// ADR-025: Error builtin struct — try/catch için
|
||||
// Alan sırası VM makeErrorValue() ile eşleşmeli: [line, col, message, trace, code]
|
||||
table_.structLayouts["Error"] = {
|
||||
{"line", Type::Int()},
|
||||
{"col", Type::Int()},
|
||||
{"message", Type::String()},
|
||||
{"trace", Type::String()},
|
||||
{"code", Type::String()}
|
||||
};
|
||||
table_.define("Error", SymbolKind::Struct, Type::structType("Error"), {});
|
||||
structFields_["Error"]; // cycle checker'a tanıt
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// typeFromName — tip adından Type üret; bilinmiyorsa E007
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Type SymbolCollector::typeFromName(const std::string& n, const SourceLocation& loc) {
|
||||
Type t = Type::fromName(n);
|
||||
if (!t.isError()) return t;
|
||||
if (structFields_.count(n)) return Type::structType(n);
|
||||
// TODO(faz2/faz3): bilinmeyen tip tam E007 tanısı
|
||||
diag_.report("E007", loc, "Bilinmeyen tip: '" + n + "'");
|
||||
return Type::error();
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// pass1Globals — üst-seviye isimleri hoist eder (gövdelere girmez)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
void SymbolCollector::pass1Globals(ASTNode* program) {
|
||||
for (ASTNode* child : program->getChildren()) {
|
||||
switch (child->kind) {
|
||||
|
||||
case ASTKind::FunctionDecl: {
|
||||
auto* fn = (FunctionDeclNode*)child;
|
||||
// parametre tiplerini topla
|
||||
std::vector<Type> paramTypes;
|
||||
for (auto* p : fn->params)
|
||||
paramTypes.push_back(typeFromName(p->varType, p->loc));
|
||||
Type retType = typeFromName(fn->returnType, fn->loc);
|
||||
Symbol* s = table_.define(fn->name, SymbolKind::Function,
|
||||
Type::function(retType, paramTypes),
|
||||
fn->loc);
|
||||
if (!s)
|
||||
diag_.report("E002", fn->loc,
|
||||
"'" + fn->name + "' zaten bu kapsamda tanımlı");
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::StructDecl: {
|
||||
auto* st = (StructDeclNode*)child;
|
||||
Symbol* s = table_.define(st->name, SymbolKind::Struct,
|
||||
Type::structType(st->name), st->loc);
|
||||
if (!s) {
|
||||
diag_.report("E002", st->loc,
|
||||
"'" + st->name + "' zaten bu kapsamda tanımlı");
|
||||
break;
|
||||
}
|
||||
// structFields_'e her zaman bir giriş aç (typeFromName için gerekli)
|
||||
structFields_[st->name]; // boş vektör oluşturur; by-value döngü artık referans semantiğiyle meşru (ADR-020)
|
||||
|
||||
// structLayouts: tüm alanlar (isim + tip) sırayla — IR üreteci ve tip denetleyici için
|
||||
for (ASTNode* fieldNode : st->getChildren()) {
|
||||
if (fieldNode->kind == ASTKind::VariableDecl) {
|
||||
auto* vd = (VariableDeclNode*)fieldNode;
|
||||
Type ft = typeFromName(vd->varType, vd->loc);
|
||||
table_.structLayouts[st->name].push_back({vd->name, ft});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::VariableDecl: {
|
||||
auto* vd = (VariableDeclNode*)child;
|
||||
Symbol* s = table_.define(vd->name, SymbolKind::Variable,
|
||||
typeFromName(vd->varType, vd->loc),
|
||||
vd->loc);
|
||||
if (!s)
|
||||
diag_.report("E002", vd->loc,
|
||||
"'" + vd->name + "' zaten bu kapsamda tanımlı");
|
||||
// Sibling VariableDecl'ler (int a, b;)
|
||||
for (ASTNode* sib : vd->getChildren()) {
|
||||
if (sib->kind == ASTKind::VariableDecl) {
|
||||
auto* sv = (VariableDeclNode*)sib;
|
||||
Symbol* ss = table_.define(sv->name, SymbolKind::Variable,
|
||||
typeFromName(sv->varType, sv->loc),
|
||||
sv->loc);
|
||||
if (!ss)
|
||||
diag_.report("E002", sv->loc,
|
||||
"'" + sv->name + "' zaten bu kapsamda tanımlı");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// checkStructCycles — E010 döngüsel struct (by-value çevrim → sonsuz boyut)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
void SymbolCollector::checkStructCycles() {
|
||||
// ADR-020: Struct alanları referans semantiği taşır (Object* pointer).
|
||||
// By-value gömme yok → sonsuz-boyut döngüsü imkânsız.
|
||||
// E010 artık üretilmez; bu metot koşullu olarak devre dışı.
|
||||
// TODO(gelecek): Primitive tipler için by-value gömme eklenirse E010 geri açılır.
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// pass2Bodies — fonksiyon gövdelerini gez; isim çözümle + referans topla
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
void SymbolCollector::pass2Bodies(ASTNode* program) {
|
||||
for (ASTNode* child : program->getChildren()) {
|
||||
switch (child->kind) {
|
||||
|
||||
case ASTKind::FunctionDecl: {
|
||||
auto* fn = (FunctionDeclNode*)child;
|
||||
table_.enterScope();
|
||||
// parametreleri tanımla
|
||||
for (auto* p : fn->params) {
|
||||
Symbol* s = table_.define(p->name, SymbolKind::Parameter,
|
||||
typeFromName(p->varType, p->loc), p->loc);
|
||||
if (!s)
|
||||
diag_.report("E002", p->loc,
|
||||
"Parametre '" + p->name + "' zaten tanımlı");
|
||||
}
|
||||
// gövdeyi gez (children[0] = BlockNode)
|
||||
auto& ch = fn->getChildren();
|
||||
if (!ch.empty()) walkStmt(ch[0]);
|
||||
table_.exitScope();
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::VariableDecl: {
|
||||
// global değişken başlatıcısı (declare-before-use)
|
||||
auto* vd = (VariableDeclNode*)child;
|
||||
if (vd->initExpr) walkExpr(vd->initExpr);
|
||||
// TODO(faz2): global init sırası kontrolü (fibonacci'de global var yok)
|
||||
for (ASTNode* sib : vd->getChildren()) {
|
||||
if (sib->kind == ASTKind::VariableDecl) {
|
||||
auto* sv = (VariableDeclNode*)sib;
|
||||
if (sv->initExpr) walkExpr(sv->initExpr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::StructDecl:
|
||||
break; // pass2'de gövde gezme gerekmez
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// walkStmt — ifade bloğunu gez
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
void SymbolCollector::walkStmt(ASTNode* node) {
|
||||
if (!node) return;
|
||||
|
||||
switch (node->kind) {
|
||||
|
||||
case ASTKind::Block: {
|
||||
table_.enterScope();
|
||||
for (ASTNode* child : node->getChildren()) walkStmt(child);
|
||||
table_.exitScope();
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::VariableDecl: {
|
||||
auto* vd = (VariableDeclNode*)node;
|
||||
// Önce başlatıcıyı gez (kendini görmesin)
|
||||
if (vd->initExpr) walkExpr(vd->initExpr);
|
||||
// Sonra tanımla
|
||||
Symbol* s = table_.define(vd->name, SymbolKind::Variable,
|
||||
typeFromName(vd->varType, vd->loc), vd->loc);
|
||||
if (!s)
|
||||
diag_.report("E002", vd->loc,
|
||||
"'" + vd->name + "' zaten bu kapsamda tanımlı");
|
||||
// Sibling VariableDecl'ler (int a, b;) — TODO: fibonacci'de yok
|
||||
for (ASTNode* sib : vd->getChildren()) {
|
||||
if (sib->kind == ASTKind::VariableDecl) {
|
||||
auto* sv = (VariableDeclNode*)sib;
|
||||
if (sv->initExpr) walkExpr(sv->initExpr);
|
||||
Symbol* ss = table_.define(sv->name, SymbolKind::Variable,
|
||||
typeFromName(sv->varType, sv->loc), sv->loc);
|
||||
if (!ss)
|
||||
diag_.report("E002", sv->loc,
|
||||
"'" + sv->name + "' zaten bu kapsamda tanımlı");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::IfStatement: {
|
||||
auto* ifn = (IfStatementNode*)node;
|
||||
if (ifn->condition) walkExpr(ifn->condition);
|
||||
if (ifn->thenBranch) walkStmt(ifn->thenBranch);
|
||||
if (ifn->elseBranch) walkStmt(ifn->elseBranch);
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::WhileStatement: {
|
||||
auto* ws = (WhileStatementNode*)node;
|
||||
if (ws->condition) walkExpr(ws->condition);
|
||||
if (ws->body) walkStmt(ws->body);
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::ForStatement: {
|
||||
auto* fs = (ForStatementNode*)node;
|
||||
table_.enterScope(); // init değişkeni döngüye ait
|
||||
if (fs->init) {
|
||||
if (fs->init->kind == ASTKind::VariableDecl) walkStmt(fs->init);
|
||||
else walkExpr(fs->init);
|
||||
}
|
||||
if (fs->condition) walkExpr(fs->condition);
|
||||
if (fs->update) walkExpr(fs->update);
|
||||
if (fs->body) walkStmt(fs->body);
|
||||
table_.exitScope();
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::DoWhileStatement: {
|
||||
auto* dw = (DoWhileStatementNode*)node;
|
||||
if (dw->body) walkStmt(dw->body);
|
||||
if (dw->condition) walkExpr(dw->condition);
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::ReturnStatement: {
|
||||
auto* rs = (ReturnStatementNode*)node;
|
||||
if (rs->value) walkExpr(rs->value);
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::ExpressionStatement: {
|
||||
auto* es = (ExpressionStatementNode*)node;
|
||||
if (es->expression) walkExpr(es->expression);
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::BreakStatement:
|
||||
case ASTKind::ContinueStatement:
|
||||
break; // yaprak
|
||||
|
||||
// ADR-025: try { body } catch (Error e) { handler }
|
||||
case ASTKind::TryStatement: {
|
||||
auto* ts = (TryStatementNode*)node;
|
||||
if (ts->body) walkStmt(ts->body);
|
||||
// catch değişkeni catch bloğu kapsamında görünür
|
||||
if (ts->handler) {
|
||||
table_.enterScope();
|
||||
if (!ts->catchVar.empty())
|
||||
table_.define(ts->catchVar, SymbolKind::Variable,
|
||||
Type::structType("Error"), {});
|
||||
walkStmt(ts->handler);
|
||||
table_.exitScope();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// ADR-025: throw <ifade>;
|
||||
case ASTKind::ThrowStatement: {
|
||||
auto* th = (ThrowStatementNode*)node;
|
||||
if (th->value) walkExpr(th->value);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// walkExpr — ifade ağacında isimleri çöz
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
void SymbolCollector::walkExpr(ASTNode* node) {
|
||||
if (!node) return;
|
||||
|
||||
switch (node->kind) {
|
||||
|
||||
case ASTKind::Identifier: {
|
||||
auto* id = (IdentifierNode*)node;
|
||||
if (!id->parserToken.token) break;
|
||||
std::string name = id->parserToken.token->token;
|
||||
Symbol* s = table_.resolve(name);
|
||||
if (s) {
|
||||
id->resolvedSymbol = s;
|
||||
table_.addReference(s, id->loc);
|
||||
} else {
|
||||
diag_.report("E001", id->loc,
|
||||
"'" + name + "' tanımlı değil");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::BinaryExpression: {
|
||||
auto* bin = (BinaryExpressionNode*)node;
|
||||
if (bin->Left) walkExpr(bin->Left);
|
||||
if (bin->Right) walkExpr(bin->Right);
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::Call: {
|
||||
auto* call = (CallExpressionNode*)node;
|
||||
if (call->callee) walkExpr(call->callee);
|
||||
for (ASTNode* arg : call->arguments) walkExpr(arg);
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::Postfix: {
|
||||
auto* pf = (PostfixNode*)node;
|
||||
if (pf->operand) walkExpr(pf->operand);
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::MemberAccess: {
|
||||
auto* ma = (MemberAccessNode*)node;
|
||||
if (ma->object) walkExpr(ma->object); // member çözümü Faz 3 → TODO
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::IndexExpression: {
|
||||
auto* ie = (IndexExpressionNode*)node;
|
||||
if (ie->object) walkExpr(ie->object);
|
||||
if (ie->index) walkExpr(ie->index);
|
||||
break;
|
||||
}
|
||||
|
||||
case ASTKind::Literal:
|
||||
break; // yaprak
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef SAQUT_SYMBOL_COLLECTOR
|
||||
#define SAQUT_SYMBOL_COLLECTOR
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "symbol/symbol_table.hpp"
|
||||
#include "diagnostic/diagnostic_engine.hpp"
|
||||
#include "core/type.hpp"
|
||||
#include "core/location.hpp"
|
||||
#include "parser/ast_node.hpp"
|
||||
|
||||
class SymbolCollector {
|
||||
public:
|
||||
SymbolCollector(SymbolTable& t, DiagnosticEngine& d) : table_(t), diag_(d) {}
|
||||
|
||||
// seedBuiltins → pass1 → structCycles(E010) → pass2
|
||||
void collect(ASTNode* program);
|
||||
|
||||
private:
|
||||
void seedBuiltins();
|
||||
void pass1Globals(ASTNode* program);
|
||||
void checkStructCycles();
|
||||
void pass2Bodies(ASTNode* program);
|
||||
void walkStmt(ASTNode* node);
|
||||
void walkExpr(ASTNode* node);
|
||||
|
||||
Type typeFromName(const std::string& n, const SourceLocation& loc);
|
||||
|
||||
SymbolTable& table_;
|
||||
DiagnosticEngine& diag_;
|
||||
|
||||
// struct adı → içerdiği struct-tip alan adları (cycle check için)
|
||||
std::unordered_map<std::string, std::vector<std::string>> structFields_;
|
||||
};
|
||||
|
||||
#endif // SAQUT_SYMBOL_COLLECTOR
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
#ifndef SAQUT_SYMBOL_TABLE
|
||||
#define SAQUT_SYMBOL_TABLE
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include "symbol/scope.hpp"
|
||||
|
||||
class SymbolTable {
|
||||
public:
|
||||
SymbolTable() {
|
||||
global_ = newScope(nullptr);
|
||||
current_ = global_;
|
||||
}
|
||||
|
||||
Scope* global() { return global_; }
|
||||
Scope* current() { return current_; }
|
||||
|
||||
Scope* enterScope() {
|
||||
current_ = newScope(current_);
|
||||
return current_;
|
||||
}
|
||||
|
||||
void exitScope() {
|
||||
if (current_->parent) current_ = current_->parent;
|
||||
}
|
||||
|
||||
// current scope'ta tanımla; duplicate → nullptr döner
|
||||
Symbol* define(const std::string& name, SymbolKind k, Type t, SourceLocation loc) {
|
||||
auto s = std::make_unique<Symbol>();
|
||||
s->name = name;
|
||||
s->kind = k;
|
||||
s->type = std::move(t);
|
||||
s->definitionLoc = loc;
|
||||
Symbol* raw = s.get();
|
||||
if (!current_->defineLocal(raw)) return nullptr; // duplicate
|
||||
pool_.push_back(std::move(s));
|
||||
return raw;
|
||||
}
|
||||
|
||||
Symbol* resolve(const std::string& n) { return current_->resolve(n); }
|
||||
|
||||
void addReference(Symbol* s, SourceLocation loc) {
|
||||
if (s) s->references.push_back(loc);
|
||||
}
|
||||
|
||||
std::vector<Symbol*> allSymbols() const {
|
||||
std::vector<Symbol*> result;
|
||||
result.reserve(pool_.size());
|
||||
for (const auto& s : pool_) result.push_back(s.get());
|
||||
return result;
|
||||
}
|
||||
|
||||
// Struct alan düzeni: struct adı → sıralı [(alan adı, tip)] listesi
|
||||
// Sembol toplayıcı doldurur; tip denetleyici ve IR üreteci okur.
|
||||
std::unordered_map<std::string, std::vector<std::pair<std::string, Type>>> structLayouts;
|
||||
|
||||
int getFieldIndex(const std::string& structName, const std::string& fieldName) const {
|
||||
auto it = structLayouts.find(structName);
|
||||
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;
|
||||
}
|
||||
|
||||
Type getFieldType(const std::string& structName, const std::string& fieldName) const {
|
||||
auto it = structLayouts.find(structName);
|
||||
if (it == structLayouts.end()) return Type::error();
|
||||
for (auto& p : it->second)
|
||||
if (p.first == fieldName) return p.second;
|
||||
return Type::error();
|
||||
}
|
||||
|
||||
private:
|
||||
Scope* newScope(Scope* p) {
|
||||
scopes_.push_back(std::make_unique<Scope>(p));
|
||||
return scopes_.back().get();
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Scope>> scopes_;
|
||||
std::vector<std::unique_ptr<Symbol>> pool_;
|
||||
Scope* global_ = nullptr;
|
||||
Scope* current_ = nullptr;
|
||||
};
|
||||
|
||||
#endif // SAQUT_SYMBOL_TABLE
|
||||
|
|
@ -1,5 +1,58 @@
|
|||
#include "tokenizer/tokenizer.hpp"
|
||||
#include <unordered_map>
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Keyword hash map — O(1) lookup yerine O(n) for döngüsü
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
static const std::unordered_map<std::string_view, std::string_view> KW_MAP = {
|
||||
{"if","if"},{"else","else"},{"for","for"},{"while","while"},{"do","do"},
|
||||
{"switch","switch"},{"case","case"},{"default","default"},
|
||||
{"break","break"},{"continue","continue"},{"return","return"},
|
||||
{"try","try"},{"catch","catch"},{"finally","finally"},
|
||||
{"throw","throw"},{"throws","throws"},{"assert","assert"},
|
||||
{"void","void"},{"int","int"},{"float","float"},{"double","double"},
|
||||
{"char","char"},{"string","string"},{"bool","bool"},
|
||||
{"true","true"},{"false","false"},{"null","null"},
|
||||
{"class","class"},{"struct","struct"},{"interface","interface"},
|
||||
{"enum","enum"},{"extends","extends"},{"implements","implements"},
|
||||
{"new","new"},{"public","public"},{"private","private"},
|
||||
{"protected","protected"},{"static","static"},{"final","final"},
|
||||
{"abstract","abstract"},{"import","import"},{"package","package"},
|
||||
{"const","const"},{"extern","extern"},{"typedef","typedef"},
|
||||
{"sizeof","sizeof"},{"auto","auto"},{"constexpr","constexpr"},
|
||||
{"noexcept","noexcept"},{"native","native"},
|
||||
{"synchronized","synchronized"},{"volatile","volatile"},
|
||||
{"transient","transient"}
|
||||
};
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Yardımcı makrolar — OperatorToken ve DelimiterToken üretimi
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
#define MAKE_OP(str, len) \
|
||||
do { \
|
||||
OperatorToken* _t = new OperatorToken();\
|
||||
_t->start = hmx.getOffset(); \
|
||||
_t->loc = hmx.getLocation(); \
|
||||
hmx.toChar(len); \
|
||||
_t->end = hmx.getOffset(); \
|
||||
_t->token = (str); \
|
||||
return _t; \
|
||||
} while(0)
|
||||
|
||||
#define MAKE_DEL(str, len) \
|
||||
do { \
|
||||
DelimiterToken* _t = new DelimiterToken();\
|
||||
_t->start = hmx.getOffset(); \
|
||||
_t->loc = hmx.getLocation(); \
|
||||
hmx.toChar(len); \
|
||||
_t->end = hmx.getOffset(); \
|
||||
_t->token = (str); \
|
||||
return _t; \
|
||||
} while(0)
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// scan
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
std::vector<Token*> Tokenizer::scan(std::string input, std::string filePath) {
|
||||
std::vector<Token*> tokens;
|
||||
hmx.setSourceText(filePath, input);
|
||||
|
|
@ -12,10 +65,14 @@ std::vector<Token*> Tokenizer::scan(std::string input, std::string filePath) {
|
|||
return tokens;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// scope — ana dispatch; her token için TEK geçiş
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
Token* Tokenizer::scope() {
|
||||
hmx.skipWhiteSpace();
|
||||
|
||||
if (hmx.include("//", true)) { skipOneLineComment(); return scope(); }
|
||||
// Yorum satırları — include() burada hâlâ gerekli (2 karakter kontrol)
|
||||
if (hmx.include("//", true)) { skipOneLineComment(); return scope(); }
|
||||
if (hmx.include("/*", true)) { skipMultiLineComment(); return scope(); }
|
||||
|
||||
if (hmx.isEnd()) {
|
||||
|
|
@ -24,10 +81,8 @@ Token* Tokenizer::scope() {
|
|||
return t;
|
||||
}
|
||||
|
||||
if (hmx.getchar() == '"')
|
||||
return readString();
|
||||
|
||||
if (hmx.isNumeric()) {
|
||||
if (hmx.getchar() == '"') return readString();
|
||||
if (hmx.isNumeric()) {
|
||||
INumber lem = hmx.readNumeric();
|
||||
NumberToken* nt = new NumberToken();
|
||||
nt->loc = lem.startLoc;
|
||||
|
|
@ -40,50 +95,128 @@ Token* Tokenizer::scope() {
|
|||
return nt;
|
||||
}
|
||||
|
||||
for (const auto& kw : keywords) {
|
||||
if (hmx.include(std::string(kw), false)) {
|
||||
char next = hmx.getchar(static_cast<int>(kw.size()));
|
||||
if ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z') ||
|
||||
(next >= '0' && next <= '9') || next == '_' || next == '$') {
|
||||
continue;
|
||||
char c0 = hmx.getchar();
|
||||
char c1 = hmx.getchar(1); // sadece 1 ek okuma, include() değil
|
||||
|
||||
// ── Operatörler & Delimiter'lar — switch ile O(1) dispatch ───────────
|
||||
switch (c0) {
|
||||
// + ++ +=
|
||||
case '+':
|
||||
if (c1 == '+') MAKE_OP("++", 2);
|
||||
if (c1 == '=') MAKE_OP("+=", 2);
|
||||
MAKE_OP("+", 1);
|
||||
|
||||
// - -- -= ->
|
||||
case '-':
|
||||
if (c1 == '-') MAKE_OP("--", 2);
|
||||
if (c1 == '=') MAKE_OP("-=", 2);
|
||||
if (c1 == '>') MAKE_DEL("->", 2);
|
||||
MAKE_OP("-", 1);
|
||||
|
||||
// * *= **
|
||||
case '*':
|
||||
if (c1 == '=') MAKE_OP("*=", 2);
|
||||
if (c1 == '*') MAKE_OP("**", 2);
|
||||
MAKE_OP("*", 1);
|
||||
|
||||
// / /=
|
||||
case '/':
|
||||
if (c1 == '=') MAKE_OP("/=", 2);
|
||||
MAKE_OP("/", 1);
|
||||
|
||||
// % %=
|
||||
case '%':
|
||||
if (c1 == '=') MAKE_OP("%=", 2);
|
||||
MAKE_OP("%", 1);
|
||||
|
||||
// < <= << <<=
|
||||
case '<':
|
||||
if (c1 == '<') {
|
||||
if (hmx.getchar(2) == '=') MAKE_OP("<<=", 3);
|
||||
MAKE_OP("<<", 2);
|
||||
}
|
||||
KeywordToken* kt = new KeywordToken();
|
||||
kt->start = hmx.getOffset();
|
||||
kt->loc = hmx.getLocation();
|
||||
hmx.toChar(static_cast<int>(kw.size()));
|
||||
kt->end = hmx.getOffset();
|
||||
kt->token = kw;
|
||||
return kt;
|
||||
}
|
||||
if (c1 == '=') MAKE_OP("<=", 2);
|
||||
MAKE_OP("<", 1);
|
||||
|
||||
// > >= >> >>=
|
||||
case '>':
|
||||
if (c1 == '>') {
|
||||
if (hmx.getchar(2) == '=') MAKE_OP(">>=", 3);
|
||||
MAKE_OP(">>", 2);
|
||||
}
|
||||
if (c1 == '=') MAKE_OP(">=", 2);
|
||||
MAKE_OP(">", 1);
|
||||
|
||||
// = ==
|
||||
case '=':
|
||||
if (c1 == '=') MAKE_OP("==", 2);
|
||||
MAKE_OP("=", 1);
|
||||
|
||||
// ! !=
|
||||
case '!':
|
||||
if (c1 == '=') MAKE_OP("!=", 2);
|
||||
MAKE_OP("!", 1);
|
||||
|
||||
// & && &=
|
||||
case '&':
|
||||
if (c1 == '&') MAKE_OP("&&", 2);
|
||||
if (c1 == '=') MAKE_OP("&=", 2);
|
||||
MAKE_OP("&", 1);
|
||||
|
||||
// | || |=
|
||||
case '|':
|
||||
if (c1 == '|') MAKE_OP("||", 2);
|
||||
if (c1 == '=') MAKE_OP("|=", 2);
|
||||
MAKE_OP("|", 1);
|
||||
|
||||
// ^ ^=
|
||||
case '^':
|
||||
if (c1 == '=') MAKE_OP("^=", 2);
|
||||
MAKE_OP("^", 1);
|
||||
|
||||
// ~ (tek karakter)
|
||||
case '~': MAKE_OP("~", 1);
|
||||
|
||||
// : ::
|
||||
case ':':
|
||||
if (c1 == ':') MAKE_DEL("::", 2);
|
||||
MAKE_DEL(":", 1);
|
||||
|
||||
// Tek karakterli delimiter'lar
|
||||
case '[': MAKE_DEL("[", 1);
|
||||
case ']': MAKE_DEL("]", 1);
|
||||
case '(': MAKE_DEL("(", 1);
|
||||
case ')': MAKE_DEL(")", 1);
|
||||
case '{': MAKE_DEL("{", 1);
|
||||
case '}': MAKE_DEL("}", 1);
|
||||
case ';': MAKE_DEL(";", 1);
|
||||
case ',': MAKE_DEL(",", 1);
|
||||
case '.': MAKE_DEL(".", 1);
|
||||
case '?': MAKE_OP("?", 1);
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
for (const auto& del : delimiters) {
|
||||
if (hmx.include(std::string(del), false)) {
|
||||
DelimiterToken* dt = new DelimiterToken();
|
||||
dt->start = hmx.getOffset();
|
||||
dt->loc = hmx.getLocation();
|
||||
hmx.toChar(static_cast<int>(del.size()));
|
||||
dt->end = hmx.getOffset();
|
||||
dt->token = del;
|
||||
return dt;
|
||||
}
|
||||
// ── Identifier veya Keyword — önce oku, sonra hash map'te ara ────────
|
||||
IdentifierToken* id = readIdentifier();
|
||||
|
||||
auto it = KW_MAP.find(id->token);
|
||||
if (it != KW_MAP.end()) {
|
||||
KeywordToken* kt = new KeywordToken();
|
||||
kt->start = id->start;
|
||||
kt->end = id->end;
|
||||
kt->loc = id->loc;
|
||||
kt->token = id->token;
|
||||
delete id;
|
||||
return kt;
|
||||
}
|
||||
|
||||
for (const auto& op : operators) {
|
||||
if (hmx.include(std::string(op), false)) {
|
||||
OperatorToken* ot = new OperatorToken();
|
||||
ot->start = hmx.getOffset();
|
||||
ot->loc = hmx.getLocation();
|
||||
hmx.toChar(static_cast<int>(op.size()));
|
||||
ot->end = hmx.getOffset();
|
||||
ot->token = op;
|
||||
return ot;
|
||||
}
|
||||
}
|
||||
|
||||
return readIdentifier();
|
||||
return id;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// readIdentifier — değişmedi
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
IdentifierToken* Tokenizer::readIdentifier() {
|
||||
hmx.beginPosition();
|
||||
IdentifierToken* it = new IdentifierToken();
|
||||
|
|
@ -115,6 +248,9 @@ IdentifierToken* Tokenizer::readIdentifier() {
|
|||
return it;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// readString — değişmedi
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
StringToken* Tokenizer::readString() {
|
||||
hmx.beginPosition();
|
||||
StringToken* st = new StringToken();
|
||||
|
|
@ -127,11 +263,8 @@ StringToken* Tokenizer::readString() {
|
|||
st->token.push_back(c);
|
||||
switch (c) {
|
||||
case '"':
|
||||
if (!started) {
|
||||
started = true;
|
||||
} else {
|
||||
ended = true;
|
||||
}
|
||||
if (!started) { started = true; }
|
||||
else { ended = true; }
|
||||
break;
|
||||
case '\\':
|
||||
hmx.nextChar();
|
||||
|
|
@ -154,6 +287,9 @@ StringToken* Tokenizer::readString() {
|
|||
return st;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// skipOneLineComment / skipMultiLineComment — değişmedi
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
void Tokenizer::skipOneLineComment() {
|
||||
while (!hmx.isEnd()) {
|
||||
if (hmx.getchar() == '\n') {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,46 @@
|
|||
// ============================================================================
|
||||
// saQut VM — CallFrame (Tek Fonksiyon Çağrısının Çalışma Alanı)
|
||||
//
|
||||
// fibonacci(5) çağrıldığında bir CallFrame açılır.
|
||||
// fibonacci(4) çağrıldığında AYRI bir CallFrame daha açılır.
|
||||
// Her frame kendi slot dizisine sahiptir — üst frame'e asla dokunmaz.
|
||||
//
|
||||
// FRAME YAŞAM DÖNGÜSÜ:
|
||||
// 1. CALL instruction'ı çalışır → yeni CallFrame oluşturulur, callStack'e eklenir
|
||||
// 2. Interpreter bu frame'in instruction'larını çalıştırır
|
||||
// 3. RETURN instruction'ı çalışır → frame callStack'ten çıkarılır,
|
||||
// dönüş değeri caller'ın `returnDestSlot`'una yazılır
|
||||
//
|
||||
// REFERANS GÜVENLİĞİ:
|
||||
// Interpreter döngüsü her iterasyonda callStack.back() ile frame'i TAZELER.
|
||||
// CALL ve RETURN'den sonra `continue` ile döngü başına dönülür.
|
||||
// Bu sayede vector büyüyüp referansı geçersiz kılsa bile sorun olmaz.
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SAQUT_VM_CALL_FRAME
|
||||
#define SAQUT_VM_CALL_FRAME
|
||||
|
||||
#include <vector>
|
||||
#include "ir/ir_function.hpp"
|
||||
#include "vm/value.hpp"
|
||||
|
||||
struct CallFrame {
|
||||
// Hangi fonksiyonun instruction'larını çalıştırıyoruz?
|
||||
// Pointer — IRProgram sahibi, frame sahibi değil.
|
||||
const IRFunction* function = nullptr;
|
||||
|
||||
// Sıradaki çalıştırılacak instruction'ın indeksi.
|
||||
// Döngü her adımda önce bu indeksteki instruction'ı alır,
|
||||
// SONRA ip'yi artırır. CALL/RETURN ip'ye dokunmaz.
|
||||
int instructionPointer = 0;
|
||||
|
||||
// Bu frame'in değer depoları: parametreler + lokaller + geçiciler.
|
||||
// Boyut = function->slotCount (frame oluşturulurken ayarlanır).
|
||||
std::vector<Value> slots;
|
||||
|
||||
// RETURN olunca dönüş değeri CALLER'ın hangi slotuna yazılacak?
|
||||
// -1 = main fonksiyonu (caller yok, değer kullanılmaz).
|
||||
int returnDestSlot = -1;
|
||||
};
|
||||
|
||||
#endif // SAQUT_VM_CALL_FRAME
|
||||
|
|
@ -0,0 +1,394 @@
|
|||
#include "vm/interpreter.hpp"
|
||||
#include "vm/object.hpp"
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
// ── makeErrorValue ─────────────────────────────────────────────────────────────
|
||||
// ADR-025: Error struct oluşturur — alan sırası: [line, col, message, trace, code]
|
||||
Value Interpreter::makeErrorValue(const std::string& message,
|
||||
const std::string& code,
|
||||
int line, int col) {
|
||||
StructObject* obj = heap_.allocStruct(5);
|
||||
obj->fields[0] = Value::fromInt(line);
|
||||
obj->fields[1] = Value::fromInt(col);
|
||||
obj->fields[2] = Value::fromString(message);
|
||||
obj->fields[3] = Value::fromString(""); // trace — ileride IR satır tablosuyla doldurulacak
|
||||
obj->fields[4] = Value::fromString(code);
|
||||
return Value::fromRef(obj);
|
||||
}
|
||||
|
||||
int Interpreter::run() {
|
||||
// Global slot'ları sıfırla
|
||||
globalSlots_.assign(program_.globalCount, Value::fromInt(0));
|
||||
|
||||
IRFunction* mainFunction = program_.findFunction("main");
|
||||
if (!mainFunction)
|
||||
throw std::runtime_error("Çalışma hatası: 'main' fonksiyonu bulunamadı");
|
||||
|
||||
CallFrame mainFrame;
|
||||
mainFrame.function = mainFunction;
|
||||
mainFrame.instructionPointer = 0;
|
||||
mainFrame.slots.resize(mainFunction->slotCount, Value::fromInt(0));
|
||||
mainFrame.returnDestSlot = -1;
|
||||
callStack_.push_back(std::move(mainFrame));
|
||||
|
||||
while (!callStack_.empty()) {
|
||||
CallFrame& frame = callStack_.back();
|
||||
|
||||
if (frame.instructionPointer >= (int)frame.function->instructions.size()) {
|
||||
int destSlot = frame.returnDestSlot;
|
||||
callStack_.pop_back();
|
||||
if (!callStack_.empty() && destSlot != -1)
|
||||
callStack_.back().slots[destSlot] = Value::fromInt(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
const Instruction& instr = frame.function->instructions[frame.instructionPointer];
|
||||
frame.instructionPointer++;
|
||||
|
||||
switch (instr.opcode) {
|
||||
|
||||
case Opcode::LOAD_CONST:
|
||||
frame.slots[instr.dest] = Value::fromInt(instr.intValue);
|
||||
break;
|
||||
|
||||
case Opcode::LOAD_STRING:
|
||||
frame.slots[instr.dest] = Value::fromString(instr.stringValue);
|
||||
break;
|
||||
|
||||
case Opcode::LOAD_NULL:
|
||||
frame.slots[instr.dest] = Value::null();
|
||||
break;
|
||||
|
||||
case Opcode::LOAD_SLOT:
|
||||
frame.slots[instr.dest] = frame.slots[instr.src];
|
||||
break;
|
||||
|
||||
// ── Aritmetik ─────────────────────────────────────────────────────
|
||||
// TypeChecker derleme zamanında tipleri doğruladı — burada sadece hesap yapılır.
|
||||
// İstisna: sıfıra bölme gerçek bir çalışma zamanı koşuludur, kontrol edilir.
|
||||
case Opcode::ADD:
|
||||
frame.slots[instr.dest] = Value::fromInt(
|
||||
frame.slots[instr.left].intValue + frame.slots[instr.right].intValue);
|
||||
break;
|
||||
case Opcode::SUB:
|
||||
frame.slots[instr.dest] = Value::fromInt(
|
||||
frame.slots[instr.left].intValue - frame.slots[instr.right].intValue);
|
||||
break;
|
||||
case Opcode::MUL:
|
||||
frame.slots[instr.dest] = Value::fromInt(
|
||||
frame.slots[instr.left].intValue * frame.slots[instr.right].intValue);
|
||||
break;
|
||||
case Opcode::DIV: {
|
||||
int d = frame.slots[instr.right].intValue;
|
||||
if (d == 0) { pendingThrow_ = makeErrorValue("Sıfıra bölme", "E_DIVZERO"); break; }
|
||||
frame.slots[instr.dest] = Value::fromInt(frame.slots[instr.left].intValue / d);
|
||||
break;
|
||||
}
|
||||
case Opcode::MOD: {
|
||||
int d = frame.slots[instr.right].intValue;
|
||||
if (d == 0) { pendingThrow_ = makeErrorValue("Sıfıra bölme (mod)", "E_DIVZERO"); break; }
|
||||
frame.slots[instr.dest] = Value::fromInt(frame.slots[instr.left].intValue % d);
|
||||
break;
|
||||
}
|
||||
|
||||
// ── Bitsel ────────────────────────────────────────────────────────
|
||||
case Opcode::BAND:
|
||||
frame.slots[instr.dest] = Value::fromInt(
|
||||
frame.slots[instr.left].intValue & frame.slots[instr.right].intValue);
|
||||
break;
|
||||
case Opcode::BOR:
|
||||
frame.slots[instr.dest] = Value::fromInt(
|
||||
frame.slots[instr.left].intValue | frame.slots[instr.right].intValue);
|
||||
break;
|
||||
case Opcode::SHL:
|
||||
frame.slots[instr.dest] = Value::fromInt(
|
||||
frame.slots[instr.left].intValue << frame.slots[instr.right].intValue);
|
||||
break;
|
||||
case Opcode::SHR:
|
||||
frame.slots[instr.dest] = Value::fromInt(
|
||||
frame.slots[instr.left].intValue >> frame.slots[instr.right].intValue);
|
||||
break;
|
||||
case Opcode::BNOT:
|
||||
frame.slots[instr.dest] = Value::fromInt(~frame.slots[instr.src].intValue);
|
||||
break;
|
||||
|
||||
// ── Global değişken erişimi ────────────────────────────────────────
|
||||
case Opcode::LOAD_GLOBAL:
|
||||
frame.slots[instr.dest] = globalSlots_[instr.intValue];
|
||||
break;
|
||||
case Opcode::STORE_GLOBAL:
|
||||
globalSlots_[instr.intValue] = frame.slots[instr.src];
|
||||
break;
|
||||
|
||||
// ── Karşılaştırma ─────────────────────────────────────────────────
|
||||
case Opcode::LESS:
|
||||
frame.slots[instr.dest] = Value::fromInt(
|
||||
frame.slots[instr.left].intValue < frame.slots[instr.right].intValue ? 1 : 0);
|
||||
break;
|
||||
case Opcode::LESS_EQUAL:
|
||||
frame.slots[instr.dest] = Value::fromInt(
|
||||
frame.slots[instr.left].intValue <= frame.slots[instr.right].intValue ? 1 : 0);
|
||||
break;
|
||||
case Opcode::GREATER:
|
||||
frame.slots[instr.dest] = Value::fromInt(
|
||||
frame.slots[instr.left].intValue > frame.slots[instr.right].intValue ? 1 : 0);
|
||||
break;
|
||||
case Opcode::GREATER_EQUAL:
|
||||
frame.slots[instr.dest] = Value::fromInt(
|
||||
frame.slots[instr.left].intValue >= frame.slots[instr.right].intValue ? 1 : 0);
|
||||
break;
|
||||
case Opcode::EQUAL_EQUAL: {
|
||||
auto& lv = frame.slots[instr.left]; auto& rv = frame.slots[instr.right];
|
||||
int r;
|
||||
if (lv.kind == ValueKind::Ref || rv.kind == ValueKind::Ref)
|
||||
r = (lv.ref == rv.ref ? 1 : 0); // ADR-023: array/struct kimlik karşılaştırması
|
||||
else if (lv.kind == ValueKind::String)
|
||||
r = (lv.stringValue == rv.stringValue ? 1 : 0);
|
||||
else
|
||||
r = (lv.intValue == rv.intValue ? 1 : 0);
|
||||
frame.slots[instr.dest] = Value::fromInt(r);
|
||||
break;
|
||||
}
|
||||
case Opcode::NOT_EQUAL: {
|
||||
auto& lv = frame.slots[instr.left]; auto& rv = frame.slots[instr.right];
|
||||
int r;
|
||||
if (lv.kind == ValueKind::Ref || rv.kind == ValueKind::Ref)
|
||||
r = (lv.ref != rv.ref ? 1 : 0);
|
||||
else if (lv.kind == ValueKind::String)
|
||||
r = (lv.stringValue != rv.stringValue ? 1 : 0);
|
||||
else
|
||||
r = (lv.intValue != rv.intValue ? 1 : 0);
|
||||
frame.slots[instr.dest] = Value::fromInt(r);
|
||||
break;
|
||||
}
|
||||
|
||||
// ── Kontrol akışı ─────────────────────────────────────────────────
|
||||
case Opcode::JMP:
|
||||
frame.instructionPointer = instr.jumpTarget;
|
||||
break;
|
||||
case Opcode::JIF_FALSE:
|
||||
if (!frame.slots[instr.cond].isTruthy())
|
||||
frame.instructionPointer = instr.jumpTarget;
|
||||
break;
|
||||
case Opcode::JIF_TRUE:
|
||||
if (frame.slots[instr.cond].isTruthy())
|
||||
frame.instructionPointer = instr.jumpTarget;
|
||||
break;
|
||||
|
||||
// ── Fonksiyon çağrısı ─────────────────────────────────────────────
|
||||
case Opcode::CALL: {
|
||||
IRFunction* callee = program_.findFunction(instr.functionName);
|
||||
if (!callee)
|
||||
throw std::runtime_error(
|
||||
"Çalışma hatası: '" + instr.functionName + "' fonksiyonu bulunamadı");
|
||||
|
||||
CallFrame newFrame;
|
||||
newFrame.function = callee;
|
||||
newFrame.instructionPointer = 0;
|
||||
newFrame.slots.resize(callee->slotCount, Value::fromInt(0));
|
||||
newFrame.returnDestSlot = instr.dest;
|
||||
|
||||
for (int i = 0; i < (int)instr.argSlots.size(); i++)
|
||||
newFrame.slots[i] = frame.slots[instr.argSlots[i]];
|
||||
|
||||
callStack_.push_back(std::move(newFrame));
|
||||
continue;
|
||||
}
|
||||
|
||||
// ── Dönüş ─────────────────────────────────────────────────────────
|
||||
case Opcode::RETURN: {
|
||||
Value returnValue = frame.slots[instr.src];
|
||||
int returnDestSlot = frame.returnDestSlot;
|
||||
callStack_.pop_back();
|
||||
|
||||
if (!callStack_.empty() && returnDestSlot != -1)
|
||||
callStack_.back().slots[returnDestSlot] = returnValue;
|
||||
|
||||
if (callStack_.empty())
|
||||
return returnValue.intValue;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// ── Float aritmetik (#44) ─────────────────────────────────────────
|
||||
case Opcode::LOAD_FLOAT:
|
||||
frame.slots[instr.dest] = Value::fromFloat(instr.floatValue);
|
||||
break;
|
||||
case Opcode::FADD:
|
||||
frame.slots[instr.dest] = Value::fromFloat(
|
||||
frame.slots[instr.left].floatValue + frame.slots[instr.right].floatValue);
|
||||
break;
|
||||
case Opcode::FSUB:
|
||||
frame.slots[instr.dest] = Value::fromFloat(
|
||||
frame.slots[instr.left].floatValue - frame.slots[instr.right].floatValue);
|
||||
break;
|
||||
case Opcode::FMUL:
|
||||
frame.slots[instr.dest] = Value::fromFloat(
|
||||
frame.slots[instr.left].floatValue * frame.slots[instr.right].floatValue);
|
||||
break;
|
||||
case Opcode::FDIV: {
|
||||
double r = frame.slots[instr.right].floatValue;
|
||||
if (r == 0.0) { pendingThrow_ = makeErrorValue("Float sıfıra bölme", "E_DIVZERO"); break; }
|
||||
frame.slots[instr.dest] = Value::fromFloat(frame.slots[instr.left].floatValue / r);
|
||||
break;
|
||||
}
|
||||
case Opcode::FNEG:
|
||||
frame.slots[instr.dest] = Value::fromFloat(-frame.slots[instr.src].floatValue);
|
||||
break;
|
||||
case Opcode::INT_TO_FLOAT:
|
||||
frame.slots[instr.dest] = Value::fromFloat((double)frame.slots[instr.src].intValue);
|
||||
break;
|
||||
case Opcode::FLOAT_TO_INT:
|
||||
frame.slots[instr.dest] = Value::fromInt((int)frame.slots[instr.src].floatValue);
|
||||
break;
|
||||
|
||||
// ── Struct (ADR-020: referans semantiği) ──────────────────────────
|
||||
case Opcode::STRUCT_NEW: {
|
||||
StructObject* obj = heap_.allocStruct(instr.intValue);
|
||||
frame.slots[instr.dest] = Value::fromRef(obj);
|
||||
break;
|
||||
}
|
||||
case Opcode::FIELD_GET: {
|
||||
Value& objVal = frame.slots[instr.src];
|
||||
if (objVal.kind != ValueKind::Ref || !objVal.ref)
|
||||
throw std::runtime_error("Çalışma hatası: struct değil");
|
||||
auto* obj = (StructObject*)objVal.ref;
|
||||
int idx = instr.intValue;
|
||||
if (idx < 0 || idx >= (int)obj->fields.size())
|
||||
throw std::runtime_error("Çalışma hatası: geçersiz struct alan indeksi " + std::to_string(idx));
|
||||
frame.slots[instr.dest] = obj->fields[idx];
|
||||
break;
|
||||
}
|
||||
case Opcode::FIELD_SET: {
|
||||
Value& objVal = frame.slots[instr.dest];
|
||||
if (objVal.kind != ValueKind::Ref || !objVal.ref)
|
||||
throw std::runtime_error("Çalışma hatası: struct değil");
|
||||
auto* obj = (StructObject*)objVal.ref;
|
||||
int idx = instr.intValue;
|
||||
if (idx < 0 || idx >= (int)obj->fields.size())
|
||||
throw std::runtime_error("Çalışma hatası: geçersiz struct alan indeksi " + std::to_string(idx));
|
||||
obj->fields[idx] = frame.slots[instr.right];
|
||||
break;
|
||||
}
|
||||
|
||||
// ── Array (ADR-020: referans semantiği) ───────────────────────────
|
||||
case Opcode::ARRAY_NEW: {
|
||||
ArrayObject* arr = heap_.allocArray(instr.intValue);
|
||||
arr->elements.resize(instr.intValue, Value::fromInt(0));
|
||||
frame.slots[instr.dest] = Value::fromRef(arr);
|
||||
break;
|
||||
}
|
||||
case Opcode::ARRAY_GET: {
|
||||
Value& arrVal = frame.slots[instr.left];
|
||||
if (arrVal.kind != ValueKind::Ref || !arrVal.ref) {
|
||||
pendingThrow_ = makeErrorValue("Dizi beklendi, farklı tip alındı", "E_TYPE"); break;
|
||||
}
|
||||
auto* arr = (ArrayObject*)arrVal.ref;
|
||||
int idx = frame.slots[instr.right].intValue;
|
||||
if (idx < 0 || idx >= (int)arr->elements.size()) {
|
||||
pendingThrow_ = makeErrorValue(
|
||||
"Dizi sınır dışı (indeks=" + std::to_string(idx) +
|
||||
", uzunluk=" + std::to_string(arr->elements.size()) + ")", "E_OOB");
|
||||
break;
|
||||
}
|
||||
frame.slots[instr.dest] = arr->elements[idx];
|
||||
break;
|
||||
}
|
||||
case Opcode::ARRAY_SET: {
|
||||
Value& arrVal = frame.slots[instr.dest];
|
||||
if (arrVal.kind != ValueKind::Ref || !arrVal.ref) {
|
||||
pendingThrow_ = makeErrorValue("Dizi beklendi, farklı tip alındı", "E_TYPE"); break;
|
||||
}
|
||||
auto* arr = (ArrayObject*)arrVal.ref;
|
||||
int idx = frame.slots[instr.left].intValue;
|
||||
if (idx < 0 || idx >= (int)arr->elements.size()) {
|
||||
pendingThrow_ = makeErrorValue(
|
||||
"Dizi sınır dışı (indeks=" + std::to_string(idx) +
|
||||
", uzunluk=" + std::to_string(arr->elements.size()) + ")", "E_OOB");
|
||||
break;
|
||||
}
|
||||
arr->elements[idx] = frame.slots[instr.right];
|
||||
break;
|
||||
}
|
||||
case Opcode::ARRAY_LEN: {
|
||||
Value& arrVal = frame.slots[instr.src];
|
||||
if (arrVal.kind != ValueKind::Ref || !arrVal.ref)
|
||||
throw std::runtime_error("Çalışma hatası: dizi değil");
|
||||
auto* arr = (ArrayObject*)arrVal.ref;
|
||||
frame.slots[instr.dest] = Value::fromInt((int)arr->elements.size());
|
||||
break;
|
||||
}
|
||||
|
||||
// ── String (ADR-024: immutable değer-tipi, içerik ==) ────────────
|
||||
case Opcode::STRING_CONCAT:
|
||||
frame.slots[instr.dest] = Value::fromString(
|
||||
frame.slots[instr.left].stringValue +
|
||||
frame.slots[instr.right].stringValue);
|
||||
break;
|
||||
|
||||
// ── Hata yönetimi (ADR-025) ──────────────────────────────────────
|
||||
case Opcode::ENTER_TRY:
|
||||
tryStack_.push_back({callStack_.size(), instr.jumpTarget, instr.dest});
|
||||
break;
|
||||
|
||||
case Opcode::LEAVE_TRY:
|
||||
if (!tryStack_.empty()) tryStack_.pop_back();
|
||||
break;
|
||||
|
||||
case Opcode::THROW:
|
||||
pendingThrow_ = frame.slots[instr.src];
|
||||
break;
|
||||
|
||||
// ── FFI ───────────────────────────────────────────────────────────
|
||||
case Opcode::CALLHOST:
|
||||
executeHostFunction(instr.functionName, frame.slots, instr.argSlots);
|
||||
break;
|
||||
}
|
||||
|
||||
// ── pendingThrow_ işle: try varsa catch'e unwind, yoksa fırlat ───
|
||||
if (pendingThrow_.has_value()) {
|
||||
Value errVal = std::move(*pendingThrow_);
|
||||
pendingThrow_.reset();
|
||||
|
||||
if (!tryStack_.empty()) {
|
||||
TryFrame tf = tryStack_.back();
|
||||
tryStack_.pop_back();
|
||||
// catch bloğunun bulunduğu frame'e unwind
|
||||
while (callStack_.size() > tf.callStackDepth)
|
||||
callStack_.pop_back();
|
||||
// Error'ı catch değişkenine bağla ve catch etiketine atla
|
||||
callStack_.back().slots[tf.errorSlot] = errVal;
|
||||
callStack_.back().instructionPointer = tf.catchTarget;
|
||||
} else {
|
||||
// Yakalanmamış hata — mesajı çıkar ve C++ exception olarak yükselt
|
||||
std::string msg = "Yakalanmamış hata";
|
||||
if (errVal.kind == ValueKind::Ref && errVal.ref) {
|
||||
auto* s = static_cast<StructObject*>(errVal.ref);
|
||||
if ((int)s->fields.size() > 2 &&
|
||||
s->fields[2].kind == ValueKind::String)
|
||||
msg = s->fields[2].stringValue;
|
||||
} else if (errVal.kind == ValueKind::String) {
|
||||
msg = errVal.stringValue;
|
||||
}
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Interpreter::executeHostFunction(const std::string& name,
|
||||
const std::vector<Value>& slots,
|
||||
const std::vector<int>& argSlots) {
|
||||
if (name == "print") {
|
||||
if (!argSlots.empty()) {
|
||||
const Value& val = slots[argSlots[0]];
|
||||
std::cout << val.toString() << "\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error("Çalışma hatası: bilinmeyen host fonksiyonu '" + name + "'");
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// ============================================================================
|
||||
// saQut VM — Interpreter (Bytecode Yorumlayıcı)
|
||||
//
|
||||
// IRProgram içindeki talimatları çalıştırır.
|
||||
// "main" fonksiyonundan başlar, RETURN ile biten frame'leri kapatır.
|
||||
//
|
||||
// DÖNGÜ GÜVENLİĞİ (referans invalidation):
|
||||
// Her iterasyonun başında callStack.back() tazeden alınır.
|
||||
// CALL ve RETURN'den sonra `continue` ile döngü başına dönülür;
|
||||
// böylece vector büyümesinden kaynaklanan dangling pointer sorunu olmaz.
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SAQUT_VM_INTERPRETER
|
||||
#define SAQUT_VM_INTERPRETER
|
||||
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include "ir/ir_program.hpp"
|
||||
#include "vm/call_frame.hpp"
|
||||
#include "vm/object.hpp"
|
||||
|
||||
// ADR-025: try bloğu girişinde yığına eklenen kayıt
|
||||
struct TryFrame {
|
||||
size_t callStackDepth; // ENTER_TRY anındaki callStack_.size() — unwind için
|
||||
int catchTarget; // catch bloğunun IR instruction indeksi
|
||||
int errorSlot; // catch değişkeninin slot numarası (catch frame'inde)
|
||||
};
|
||||
|
||||
class Interpreter {
|
||||
public:
|
||||
explicit Interpreter(IRProgram& program) : program_(program) {}
|
||||
|
||||
// "main" fonksiyonunu bul ve çalıştır.
|
||||
// Tamamlandığında main'in dönüş değerini (int) döndürür.
|
||||
int run();
|
||||
|
||||
private:
|
||||
IRProgram& program_;
|
||||
std::vector<CallFrame> callStack_;
|
||||
std::vector<Value> globalSlots_;
|
||||
Heap heap_;
|
||||
std::vector<TryFrame> tryStack_; // ADR-025: aktif try çerçeveleri
|
||||
std::optional<Value> pendingThrow_; // bekleyen istisna değeri
|
||||
|
||||
// Error StructObject oluştur (ADR-025): [line, col, message, trace, code]
|
||||
Value makeErrorValue(const std::string& message,
|
||||
const std::string& code = "",
|
||||
int line = 0, int col = 0);
|
||||
|
||||
// Host (C++) fonksiyon çağrısı — şu an sadece "print" destekli
|
||||
void executeHostFunction(const std::string& name,
|
||||
const std::vector<Value>& slots,
|
||||
const std::vector<int>& argSlots);
|
||||
};
|
||||
|
||||
#endif // SAQUT_VM_INTERPRETER
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue