saqut-compiler/docs/roadmap-frontend.md

180 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# saQut Frontend Yol Haritası — Symbol Table + Semantic Analiz + Optimizasyon
> Bu belge, frontend'i tamamlamaya yönelik dosya-dosya uygulama planıdır.
> Kararların gerekçeleri: `docs/adr-frontend-analiz.md` (ADR-006…014).
> Tartışma akışı: `docs/transkript-frontend-tasarim.md`.
>
> **İlke:** Sıralama katıdır — her faz bir öncekine dayanır. Her faz sonunda
> mevcut örneklerle (`examples/Final.sqt`, `examples/source.sqt`) ve CLI
> komutlarıyla doğrulama yapılır; regresyon olmamalıdır. Kod temiz, anlaşılır ve
> yorum satırlarıyla takip edilebilir olmalıdır (header-only tarzı korunur,
> bkz. ADR-003).
---
## Genel Bakış
```
Faz 0 Temeller Type sınıfı + Diagnostic modülü + Hata kataloğu
Faz 1 AST Refactor ExpressionNode/StatementNode + analiz alanları
Faz 2 Symbol Table Symbol + Scope + SymbolTable + iki-geçişli toplama
Faz 3 Semantic Analiz Tip kontrolü + yapısal doğrulama (diagnostic'e basar)
Faz 4 Optimizasyon Pass manager (fixpoint) + constant folding + dead code
```
Katman eşlemesi (ADR-006):
- **Frontend:** Faz 03
- **Middle-end:** Faz 4
- **Backend:** bu yol haritasının dışında (C transpile → QBE → JIT, ADR-001)
---
## Faz 0 — Temeller (Type + Diagnostic + Hata Kataloğu)
**Bağımlılık:** yok. **Hedef:** her şeyin üstüne kurulacağı temel veri yapıları.
İlgili ADR: 010 (Type), 013 (Diagnostic).
### Dosyalar
| Dosya | İçerik |
|---|---|
| `src/core/type.hpp` | `Type` sınıfı. `enum class TypeKind { Primitive, Array, Struct, Function, Error }`. Primitif alt-tipleri: `int, float, double, char, string, bool, void`. Alanlar: array için `elementType`, function için `returnType`+`paramTypes`, struct için `structName`. Metotlar: `equals(const Type&)`, `toString()`, `toJson()`, factory'ler (`Type::primitive(...)`, `Type::array(...)`, `Type::error()`). |
| `src/diagnostic/diagnostic.hpp` | `enum class DiagLevel { Error, Warning, Note, Hint }`. `struct Diagnostic { DiagLevel level; std::string code; SourceLocation loc; std::string message; std::string hint; }`. **Hata kataloğu** (sabitler/enum): bkz. aşağı. |
| `src/diagnostic/diagnostic_engine.hpp` | `DiagnosticEngine`: `report(Diagnostic)`, `hasErrors()`, `errorCount()`, `printAll(std::ostream&)`, `toJson()`. Diagnostic'leri biriktirir; durdurma kararını pipeline verir (tüm hatalar toplanır, sonra raporlanır — ADR-013). |
### Hata Kataloğu (baştan belirlenir)
| Kod | Anlam | Hangi fazda üretilir |
|---|---|---|
| `E001` | Tanımsız değişken/isim | Faz 2/3 |
| `E002` | Aynı scope'ta çift tanım | Faz 2 |
| `E003` | Tip uyuşmazlığı | 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 |
| `W001` | Kullanılmayan değişken | Faz 4 |
| `W002` | Sıfıra bölme (sabit folding) | Faz 4 |
| `W003` | Erişilemez (ölü) kod | Faz 4 |
*(Liste uygulamada genişleyebilir; yeni hatalar buraya eklenir.)*
### Doğrulama
- `Type::equals` / `toString` birim testleri.
- `DiagnosticEngine` topla → `printAll` çıktısı doğru sıralı.
---
## Faz 1 — AST Refactor (ExpressionNode / StatementNode + analiz alanları)
**Bağımlılık:** Faz 0 (Type). **Hedef:** node hiyerarşisini ifade/deyim olarak
ayır, analiz alanlarını ekle. İlgili ADR: 012, 013.
### Dosyalar
| Dosya | Değişiklik |
|---|---|
| `src/parser/ast_node.hpp` | İki ara taban ekle: `class ExpressionNode : public ASTNode { Type resolvedType; bool isConstant=false; /* foldedValue */ }` ve `class StatementNode : public ASTNode { bool isReachable=true; }`. |
| `src/parser/nodes/literal.hpp` · `binary_expr.hpp` · `identifier.hpp` · `expressions.hpp` (Call/Member/Index/Postfix) | Bu node'ları `ExpressionNode`'dan türet. |
| `src/parser/nodes/statements.hpp` (Block/If/While/For/DoWhile/Return/Break/Continue/ExpressionStatement) · `declarations.hpp`? | Statement'ları `StatementNode`'dan türet. (VariableDecl/FunctionDecl/StructDecl tartışmalı — declaration; şimdilik `StatementNode` veya doğrudan `ASTNode` altında değerlendirilir.) |
| `src/parser/nodes/identifier.hpp` | `IdentifierNode`'a `Symbol* resolvedSymbol = nullptr;` (Faz 2'de bağlanır). |
| `src/parser/nodes/*.cpp` | `toJson()`/`log()`'a yeni alanları (tip, isReachable) ekle — boş cpp'ler doluyor. |
### Doğrulama
- `saqut ast examples/Final.sqt` hâlâ geçerli JSON (regresyon yok, `python3 -m json.tool` ile).
- Derleme uyarısız (`-Wall -Wextra`).
---
## Faz 2 — Symbol Table (scope'lu, iki-geçişli toplama)
**Bağımlılık:** Faz 0, 1. **Hedef:** isim çözümleme + scope + referans toplama.
İlgili ADR: 011, 013.
### Dosyalar
| Dosya | İçerik |
|---|---|
| `src/symbol/symbol.hpp` | `enum class SymbolKind { Variable, Function, Parameter, Struct, Field }`. `struct Symbol { std::string name; SymbolKind kind; Type type; SourceLocation definitionLoc; std::vector<SourceLocation> references; Scope* scope; }`. |
| `src/symbol/scope.hpp` | `class Scope { Scope* parent; std::unordered_map<std::string, Symbol*> symbols; ... }`. `defineLocal()`, `lookupLocal()`. Her katman bir namespace. |
| `src/symbol/symbol_table.hpp` | Scope yığını yönetimi: `enterScope()`, `exitScope()`, `define(Symbol)` (aynı scope'ta duplicate → false + `E002`), `resolve(name)` (içten dışa), `addReference(name, loc)`, `getAllSymbols()`, `toJson()`. |
| `src/symbol/symbol_collector.hpp/.cpp` | **İki geçiş** (ADR-011): **Geçiş 1** → tüm üst-seviye tanımlarını (fonksiyon imzaları, struct isim+alan tipleri, global değişkenler) global scope'a hoist et. **Geçiş 2** → fonksiyon gövdelerine in; lokal'leri declare-before-use ile topla; her `IdentifierNode`'u `resolve()` edip `resolvedSymbol`'a bağla + `addReference`. |
### Notlar
- Scope oluşturan node'lar: Program, FunctionDecl (parametreler), Block, for/while.
- `src/json.hpp`'deki eski `collectSymbolsRecursive` bu sistemle değiştirilir.
- Tanımsız isim → `E001`; bilinmeyen tip → `E007`.
### Doğrulama
- `saqut symbols examples/Final.sqt` → zengin tablo (her sembolün tipi, tanım yeri,
referansları). Forward reference çalışır (sonra tanımlı fonksiyon çağrılabilir).
- Hatalı örnekler → `E001`/`E002`/`E007` diagnostic'leri.
---
## Faz 3 — Semantic Analiz (Tip Kontrolü + Yapısal Doğrulama)
**Bağımlılık:** Faz 2. **Hedef:** tipleri ata/kontrol et, yapısal kuralları
doğrula. İlgili ADR: 010, 013.
### Dosyalar
| Dosya | İçerik |
|---|---|
| `src/sema/type_checker.hpp/.cpp` | İfadeleri alttan üste gez, her `ExpressionNode`'a `resolvedType` ata. Gizli dönüşüm yok (ADR-010) → uyuşmazlıkta `E003`. Kontrol noktaları: atama (`=`), binary op operand tipleri, fonksiyon çağrısı argümanları (`E008`), array index, return değeri (`E006`), variable init tip uyumu. Hata olunca node'a `Type::error()` → ardışık sahte hata yok. |
| `src/sema/structural_validator.hpp/.cpp` | Parent pointer ile ağaç-tırmanma kontrolleri: `break`/`continue` döngü/switch içinde mi (`E004`), `return` fonksiyon içinde mi (`E005`), array boyutu sabit mi (`E009`). |
### Notlar
- Bu iki modül + Faz 2'nin collector'ı birlikte "semantic analiz" fazını oluşturur.
- Tüm hatalar toplanır, ilk hatada durulmaz; faz sonunda `DiagnosticEngine`
hepsini raporlar, pipeline durur (ADR-013).
### Doğrulama
- Doğru `.sqt` → temiz geçer, her expression node'unun tipi JSON'da görünür.
- Hatalı `.sqt` örnekleri → tüm semantik hatalar tek seferde listelenir.
---
## Faz 4 — Optimizasyon Framework
**Bağımlılık:** Faz 3. **Hedef:** opsiyonel, iteratif, toggle'lı kaynak-seviyesi
optimizasyon. **Orijinali bozmaz — klon üstünde** (ADR-007). İlgili ADR: 007, 008, 009.
### Dosyalar
| Dosya | İçerik |
|---|---|
| `src/core/config.hpp` | `CompilerConfig`: pass toggle'ları (`optConstantFolding`, `optDeadCodeElim`, …), `outputFormat`, `mode`, `optimized` bayrağı. |
| `src/opt/optimization_pass.hpp` | Soyut `OptimizationPass`: `virtual bool run(ASTNode* root, SymbolTable* table) = 0;` (değişiklik yaptıysa true). `name()`. |
| `src/opt/optimization_manager.hpp` | Pass listesi; `CompilerConfig`'e göre seçim; **fixpoint döngüsü** (hiçbir pass değişiklik yapmayana kadar). Çalışmadan önce AST'yi **klonlar** (`ASTNode::clone()` gerekebilir). |
| `src/opt/constant_folding.hpp/.cpp` | `BinaryExpression` operandları sabitse hesapla, sonucu sabit `Literal` ile değiştir (klonda). Tipe saygılı (`5/2`→int `2`, ADR-010). Sıfıra bölme → `W002`, katlama yapma. |
| `src/opt/dead_code_elim.hpp/.cpp` | `isReachable` (Faz 3) işaretine göre: `return`/`break`/`continue` sonrası statement'lar, `if(false)`, sıfır-referanslı değişken (`W001`/`W003`). |
### CLI Entegrasyonu
| Dosya | Değişiklik |
|---|---|
| `src/cli/args.hpp` | `--optimized` ve `--opt-all`/`--opt-none`/`--skip-*` bayrakları`CompilerConfig`. |
| `src/cli/commands/ast.hpp` · `symbols.hpp` | `--optimized` verilince klon+optimize edilmiş hali göster; verilmezse orijinal. |
### Doğrulama
- `saqut ast file --optimized``1+2` katlanmış, ölü kod elenmiş.
- `saqut ast file` (bayraksız) → orijinal, **değişmemiş** (öncesi/sonrası ayrımı).
- Fixpoint: zincirleme optimizasyon (folding → yeni dead code → DCE) yakalanır.
---
## Tamamlanınca
Bu yol haritası bittiğinde frontend tamamlanmış olur:
- Parser → analizli, tipli, sembol-çözümlü AST + zengin symbol table.
- Tam hata raporlama (toplu, kataloglu).
- Opsiyonel, incelenebilir optimizasyon.
Sonraki adım (ayrı yol haritası): **IR güçlendirme** (kontrol akışı/fonksiyon/
bellek opcode'ları, ADR-005/Issue 5.1) → **C transpile backend** → QBE → JIT
(ADR-001 sırası). Dinamik array'in runtime bellek modeli (ADR-014) backend
fazında kararlaştırılır.