BugLang — o'z dasturlash tilimni qanday yaratdim (Go → Rust)
Nega o'z tilini yaratish kerak?
Har kuni ishlatadigan tillarimiz — Go, Python — qanday ishlashini chuqur tushunishning eng yaxshi yo'li bitta: o'zing til yozib ko'rish. Shu maqsadda BugLang'ni boshladim — avval Go'da interpretator, hozir Rust'da bytecode VM.
Birinchi bosqich: Go'da interpretator
Klassik uch qism:
1. Lexer
Manba kodni tokenlarga bo'ladi — qo'lda yozilgan, regexsiz:
func (l *Lexer) NextToken() Token {
switch l.ch {
case '=':
if l.peekChar() == '=' { return l.makeTwoCharToken(EQ) }
return newToken(ASSIGN, l.ch)
case '+':
return newToken(PLUS, l.ch)
// ...
}
}
2. Pratt parser
Ifodalarni operator ustuvorligi bilan o'qiydigan eng elegant usul. Har bir token turiga ikkita funksiya biriktiriladi: prefix (-x, !ok) va infix (a + b, f(x)).
3. Tree-walk interpretator
AST bo'ylab rekursiv yurib, har tugunni baholaydi. Yozish oson, lekin sekin — har amalda pointer chasing va type switch.
Ikkinchi bosqich: Rust'da bytecode VM
Tree-walk sekin bo'lgani uchun hozir bytecode VM ustida ishlayapman:
- AST → ixcham bytecode kompilyatsiya qilinadi
- VM bitta tight loop'da opcode'larni bajaradi
- Maqsad: interpretatordan 5–8× tezroq
Bundan tashqari saqlash integratsiyasi uchun C++'da eksperimental DB driverlar yozdim.
Xulosa
Til yaratish — murakkab tizimlarni kichik, tushunarli qismlarga bo'lishning mashqi. Lexer yozib bo'lgach parser qo'rqinchli emas; parser tushunilgach VM ham mantiqiy davom.
Kod ochiq: github.com/JscorpTech