Files
dexpr/docs/compiler.md
2026-04-05 23:05:31 +03:00

152 lines
4.0 KiB
Markdown
Raw Permalink 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.
# Compiler Modülü
**Konum:** `src/compiler.rs`
AST'yi bytecode'a dönüştürür. Tek geçişli (single-pass) derleme yapar. Tüm değişkenler global scope'tadır.
---
## Konfigürasyon
- `MAX_REGISTERS = 8` — Hesaplama için kullanılabilir register sayısı
---
## Hata Türleri (CompileError)
| Hata | Açıklama |
|------|----------|
| `UndefinedFunction(SmolStr)` | Tanımlanmamış fonksiyon (built-in dışı çağrı) |
| `RegisterLimitExceeded` | Register limiti aşıldı |
| `InvalidExpression(String)` | Geçersiz ifade |
| `InvalidStatement(String)` | Geçersiz deyim |
| `BytecodeError(String)` | Bytecode üretim hatası |
---
## Compiler Yapısı
```rust
struct Compiler {
writer: BytecodeWriter,
used_registers: Vec<bool>,
// Jump address resolution
pending_jumps: Vec<(usize, usize)>,
labels: HashMap<usize, usize>,
next_label: usize,
// Debug info generation
debug_info: DebugInfo,
current_span: Span,
}
```
---
## Derleme Akışı
### Ana Derleme: `compile(statements) -> Vec<u8>`
Tek geçişli derleme süreci:
```
1. Deyimleri sırayla derle
2. End opcode'u yaz
3. Atlama adreslerini çözümle (resolve_jumps)
```
### Kaynak Koddan Derleme: `compile_from_source(source) -> (Vec<u8>, DebugInfo)`
Parse ile birlikte pozisyon bilgisi de toplar ve `DebugInfo` üretir.
---
## Deyim Derleme
### Assignment (Atama)
1. İfadeyi register'a derle
2. `StoreGlobal` emit et (tüm değişkenler global)
### If Statement (Koşullu Deyim)
```
1. Koşulu register'a derle
2. Else ve end için label oluştur
3. JumpIfFalse → else label
4. Then dalını derle
5. Jump → end label
6. Else label'ını set et, else dalını derle
7. End label'ını set et
```
---
## İfade Derleme
### Value (Sabit Değer)
- Register ayır → `LoadConst` emit et
### Variable (Değişken)
- Register ayır → `LoadGlobal` emit et
### BinaryOp (İkili Operasyon)
1. Sol operandı register'a derle
2. Sağ operandı register'a derle
3. Sonuç register'ı ayır
4. Uygun opcode'u emit et (Add, Sub, Mul, vs.)
5. Operand register'ları serbest bırak
> **Not:** String birleştirme derleme zamanında ayırt edilmez. `Op::Add` her zaman `OpCodeByte::Add` emit eder; string birleştirme ve otomatik tip dönüşümü VM tarafından çalışma zamanında (runtime) ele alınır.
### UnaryOp (Tekli Operasyon)
1. Operandı register'a derle
2. Sonuç register'ı ayır
3. `Neg` veya `Not` emit et
### FunctionCall (Fonksiyon Çağrısı)
- `log` built-in fonksiyonu: Argümanları derle → `Log` emit et → Null register döndür
- Diğer fonksiyonlar: `CallExternal` opcode emit edilir (VM tarafından runtime'da çözümlenir)
### ExprStmt (İfade Deyimi)
- İfadeyi derle → `SetResult` emit et → Register'ı serbest bırak
- `SetResult`, VM'in `execute()` dönüş değerini belirler (son ExprStmt kazanır)
### MethodCall (Metod Çağrısı)
- Nesneyi register'a derle
- Argümanları derle
- `MethodCall` emit et (sonuç, nesne, metod adı, argüman sayısı, argüman register'ları)
### PropertyAccess (Özellik Erişimi)
- Nesneyi register'a derle
- `GetProperty` emit et (hedef register, nesne register, özellik adı string)
### PropertyAssignment (Özellik Ataması)
- İç içe özellik zinciri (`a.b.c = expr`) için:
1. Kök değişkeni `LoadGlobal` ile yükle
2. Ara özellikler için `GetProperty` zinciri emit et
3. Son özellik için `SetProperty` emit et
4. Değiştirilmiş kök nesneyi `StoreGlobal` ile geri yaz
---
## Register Yönetimi
- `allocate_register() -> u8` — İlk boş register'ı bul, yoksa hata
- `free_register(reg)` — Register'ı kullanılabilir olarak işaretle
- Toplam 8 register limiti var
---
## Label ve Jump Yönetimi
| Metod | Açıklama |
|-------|----------|
| `create_label() -> usize` | Benzersiz label ID üret |
| `set_label(id)` | Label'ın bytecode pozisyonunu kaydet |
| `emit_jump_address(label) -> usize` | Placeholder yaz, çözümleme için kaydet |
| `emit_jump(label)` | Koşulsuz atlama emit et |
| `resolve_jumps()` | Tüm placeholder'ları gerçek adreslerle doldur |