Dasturlash tilidan mashina kodigacha
Siz yozgan bitta satr kod kompilyator yoki interpretator orqali nol va birlarga, so'ng tranzistorlardagi signallarga aylanadi.
Protsessor faqat mashina kodini — nol va birlardan iborat buyruqlarni tushunadi. Odamlar uchun esa bunday kod yozish juda qiyin. Shuning uchun dasturlash tillari yaratilgan. Ular darajalarga bo'linadi. Mashina kodi — protsessorning ona tili. Assembler — mashina kodining odam o'qiy oladigan ko'rinishi (ADD, MOV). Past darajali tillar (C, Rust) — apparatga yaqin, xotirani qo'lda boshqarish mumkin. Yuqori darajali tillar (Python, JavaScript, Java) — apparat tafsilotlarini to'liq yashiradi.
12.1. Kompilyator
Kompilyator butun manba kodni oldindan mashina kodiga tarjima qiladi va bajariladigan fayl (Windows'da .exe) hosil qiladi. Bu jarayon bir necha bosqichdan iborat: (1) leksik tahlil — kod so'zlarga (tokenlarga) ajratiladi; (2) sintaktik tahlil — tokenlardan daraxtsimon tuzilma (AST) quriladi va grammatik xatolar tekshiriladi; (3) semantik tahlil — turlar va o'zgaruvchilar tekshiriladi; (4) optimallashtirish — kod tezroq ishlashi uchun qayta tuziladi (masalan, 2 * 8 oldindan 16 ga almashtiriladi); (5) kod generatsiyasi — aniq ISA uchun mashina buyruqlari hosil qilinadi. C, C++, Rust, Go kompilyatsiya qilinadigan tillar.
12.2. Interpretator va JIT
Interpretator kodni oldindan tarjima qilmaydi — u uni satrma-satr o'qib, darhol bajaradi. Bu qulay (kodni o'zgartirib, darhol ishga tushirish mumkin), lekin sekinroq. Python (CPython) avval kodni oraliq baytkodga aylantiradi, so'ng virtual mashina uni interpretatsiya qiladi.
JavaScript'ni ishlatadigan V8 dvigateli (Chrome va Node.js ichida) yanada aqlli usul — JIT (Just-In-Time) kompilyatsiyadan foydalanadi. Kod avval tezda interpretatsiya qilinadi. Qaysi funksiyalar ko'p chaqirilayotgani kuzatiladi va bunday "issiq" funksiyalar ish vaqtida optimallashtirilgan mashina kodiga kompilyatsiya qilinadi. Shuning uchun zamonaviy JavaScript juda tez ishlaydi. Agar funksiyaga har safar turli turdagi ma'lumot berilsa (goh son, goh satr), optimallashtirish bekor qilinadi — TypeScript'dagi aniq turlar bilvosita shu masalada ham yordam beradi.
12.3. Xotirani boshqarish: stek va uyum
Dastur ishlaganda uning xotirasi bir nechta sohaga bo'linadi. Kod sohasi — mashina buyruqlari. Stek (stack) — funksiya chaqiriqlari va lokal o'zgaruvchilar uchun; funksiya chaqirilganda stekka yangi "ramka" qo'shiladi, tugaganda olib tashlanadi. Cheksiz rekursiya stekni to'ldirib yuboradi — bu mashhur stack overflow xatosi. Uyum (heap) — dinamik yaratiladigan obyektlar uchun (JavaScript'dagi har bir {} yoki []). C tilida heap'dagi xotirani dasturchi o'zi bo'shatishi kerak, JavaScript va Python'da esa buni axlat yig'uvchi (garbage collector) avtomatik bajaradi: u hech qayerdan havola qilinmagan obyektlarni topib, xotirasini bo'shatadi.