9.9 KiB
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 0–3
- 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/toStringbirim testleri.DiagnosticEnginetopla →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.sqthâlâ geçerli JSON (regresyon yok,python3 -m json.toolile).- 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 eskicollectSymbolsRecursivebu 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/E007diagnostic'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
DiagnosticEnginehepsini 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+2katlanmış, ö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.