mirror of
https://github.com/duhanbalci/dexpr.git
synced 2026-07-01 16:19:16 +00:00
4.0 KiB
4.0 KiB
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ı
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)
- İfadeyi register'a derle
StoreGlobalemit 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 →
LoadConstemit et
Variable (Değişken)
- Register ayır →
LoadGlobalemit et
BinaryOp (İkili Operasyon)
- Sol operandı register'a derle
- Sağ operandı register'a derle
- Sonuç register'ı ayır
- Uygun opcode'u emit et (Add, Sub, Mul, vs.)
- Operand register'ları serbest bırak
Not: String birleştirme derleme zamanında ayırt edilmez.
Op::Addher zamanOpCodeByte::Addemit 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)
- Operandı register'a derle
- Sonuç register'ı ayır
NegveyaNotemit et
FunctionCall (Fonksiyon Çağrısı)
logbuilt-in fonksiyonu: Argümanları derle →Logemit et → Null register döndür- Diğer fonksiyonlar:
CallExternalopcode emit edilir (VM tarafından runtime'da çözümlenir)
ExprStmt (İfade Deyimi)
- İfadeyi derle →
SetResultemit et → Register'ı serbest bırak SetResult, VM'inexecute()dönüş değerini belirler (son ExprStmt kazanır)
MethodCall (Metod Çağrısı)
- Nesneyi register'a derle
- Argümanları derle
MethodCallemit et (sonuç, nesne, metod adı, argüman sayısı, argüman register'ları)
PropertyAccess (Özellik Erişimi)
- Nesneyi register'a derle
GetPropertyemit et (hedef register, nesne register, özellik adı string)
PropertyAssignment (Özellik Ataması)
- İç içe özellik zinciri (
a.b.c = expr) için:- Kök değişkeni
LoadGlobalile yükle - Ara özellikler için
GetPropertyzinciri emit et - Son özellik için
SetPropertyemit et - Değiştirilmiş kök nesneyi
StoreGlobalile geri yaz
- Kök değişkeni
Register Yönetimi
allocate_register() -> u8— İlk boş register'ı bul, yoksa hatafree_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 |