Bosh sahifa Wiki Interpreter

Interpreter

Interpretersource code yoki oraliq instructionlarni runtime vaqtida o‘qib, ularning ma’nosini bajaradigan dastur.

Compiler ko‘pincha butun dastur yoki modulni oldindan target codega aylantiradi. Interpreter esa instructionlarni bajarilish jarayonida tahlil qiladi yoki oldindan yaratilgan bytecode’ni virtual machine orqali ijro etadi.

Python, JavaScript, Ruby, shell va ko‘plab scripting muhitlarida interpretatsiya muhim rol o‘ynaydi.

To‘g‘ridan-to‘g‘ri interpretatsiya

Eng sodda modelda interpreter:

  1. source matnni o‘qiydi;
  2. statementni parse qiladi;
  3. semantic amalni bajaradi;
  4. keyingi statementga o‘tadi.

Bu model o‘quv interpreterlarida uchraydi.

Katta tillarda har statementni qayta parse qilish samarasiz, shuning uchun AST yoki bytecode yaratiladi.

AST interpreter

Source code lexer va parserdan o‘tib ASTga aylanadi.

Interpreter tree node’larni yuradi:

Add
├── Number 2
└── Multiply
    ├── Number 3
    └── Number 4

Avval child node’lar bajarilib, natija 14 bo‘ladi.

AST interpreter yaratish sodda, lekin node va pointerlar sabab performance pastroq bo‘lishi mumkin.

Bytecode interpreter

Source code compact virtual instructionlarga compile qilinadi.

Misol:

LOAD_CONST 2
LOAD_CONST 3
ADD
PRINT

Virtual machine instruction pointer va operand stack orqali bytecode’ni bajaradi.

Bytecode source parsing xarajatini kamaytiradi va cross-platform bo‘lishi mumkin.

Virtual machine

Interpreter ko‘pincha virtual machine tarkibida ishlaydi.

VM quyidagilarni boshqarishi mumkin:

JVM va .NET runtime interpreter, JIT va boshqa execution mexanizmlarini birlashtirishi mumkin.

Dispatch loop

Bytecode interpreter markazida dispatch loop mavjud.

WHILE running
    opcode ← FETCH
    DECODE opcode
    EXECUTE opcode
END WHILE

Dispatch usullari:

  • switch dispatch;
  • threaded code;
  • direct threading;
  • computed goto;
  • superinstruction.

Branch prediction va cache performance’ga ta’sir qiladi.

Operand stack

Stack-based VM instruction operandlarni stackdan oladi.

PUSH 10
PUSH 20
ADD

ADD ikki qiymatni olib, 30ni qaytaradi.

Afzalligi — bytecode ixcham. Kamchiligi — ko‘p push/pop.

Register-based VM

Virtual registerlar bilan ishlaydi.

ADD R3, R1, R2

Instruction kattaroq bo‘lishi mumkin, ammo kamroq instruction talab qilishi mumkin.

Lua VM va boshqa runtime’larda shunday model uchraydi.

Dynamic type

Interpreted tillarda type ko‘pincha runtime’da aniqlanadi.

+ operatori:

  • integer qo‘shish;
  • floating-point;
  • string concatenation;
  • user-defined method

bo‘lishi mumkin.

Interpreter operand type’larini tekshirib, tegishli amalni tanlaydi.

Environment va scope

Interpreter variable nomlarini environment yoki scope chain orqali topadi.

Har function call:

bilan ishlashi mumkin.

Name lookup performance uchun hash table, inline cache yoki slot ishlatiladi.

REPL

Read-Eval-Print Loop user kiritgan expressionni o‘qiydi, bajaradi va natijani chiqaradi.

>>> 2 + 3
5

REPL:

  • o‘rganish;
  • debugging;
  • data tahlili;
  • tez tajriba;
  • application console

uchun qulay.

Script

Interpreter source file’ni to‘g‘ridan-to‘g‘ri ishga tushirishi mumkin.

Unix shebang:

#!/usr/bin/env python3

OS scriptni ko‘rsatilgan interpreterga beradi.

Environmentdagi interpreter versiyasi natijaga ta’sir qilishi mumkin.

Import

Interpreter module source yoki bytecode’ni topadi, yuklaydi va bir marta execute qiladi.

Import cache qayta bajarishni kamaytiradi.

Circular import module qisman initialize bo‘lgan holatga olib kelishi mumkin.

Exception

Runtime xato exception obyektiga aylanadi.

Interpreter stack frame’lar bo‘ylab handler qidiradi.

Handler topilmasa:

yuz beradi.

Garbage collection

Interpreter runtime dynamic objectlar xotirasini boshqaradi.

Usullar:

  • reference counting;
  • tracing GC;
  • generational GC;
  • cycle detector.

GC pause va memory usage runtime performance’iga ta’sir qiladi.

Native extension

Interpreted til performance yoki system access uchun native library chaqirishi mumkin.

Misollar:

Native extension runtime memory safety himoyasini chetlab o‘tishi mumkin.

JIT

Interpreter tez-tez bajariladigan code pathni aniqlab, native codega compile qilishi mumkin.

JIT:

ishlatadi.

Taxmin noto‘g‘ri bo‘lsa interpreter yoki kam optimallashtirilgan codega qaytadi.

Startup va throughput

Interpreter odatda tez startup qilishi mumkin, chunki katta AOT compilation talab qilinmaydi.

Uzoq hisoblashda native compiled code tezroq bo‘lishi mumkin.

JIT startup xarajati evaziga keyinchalik throughputni oshiradi.

Portability

Bytecode yoki source bir xil interpreter mavjud platformalarda ishlashi mumkin.

Biroq:

portabilityni cheklaydi.

Sandboxing

Interpreter untrusted scriptni cheklangan muhitda bajarishi mumkin.

Faqat language-level cheklov yetarli bo‘lmasligi mumkin. Runtime zaifligi yoki native API sandboxdan chiqishga sabab bo‘ladi.

OS process isolation, seccomp, container yoki VM qo‘shimcha himoya beradi.

Interpreter va compiler

Ko‘p runtime’larda chegara aniq emas.

Python source bytecodega compile qilinib VMda interpretatsiya qilinadi.

Java source bytecodega compile qilinadi, JVM esa interpretatsiya va JITdan foydalanadi.

JavaScript engine source’ni parse qilib, bir nechta IR va JIT bosqichidan o‘tkazadi.

Diagnostika

Interpreter muammosida:

tekshiriladi.

Bir xil script turli interpreter versiyasida syntax yoki semantic farq sabab boshqacha ishlashi mumkin.

Bog‘liq tushunchalar

Bytecode, Virtual machine, AST, REPL, Dynamic typing, Garbage collection, JIT, Compiler, Runtime, Native extension