Interpreter
1. Definition
An interpreter is a translator that reads a high-level source program statement by statement, converts each statement into machine-level operations and executes it immediately, before moving on to the next statement. It produces no object file — the program is never translated as a whole; translation and execution are interleaved.
source.py
│ read line 1 ─► translate ─► execute ──► output/effect
│ read line 2 ─► translate ─► execute ──► output/effect
│ read line 3 ─► translate ─► execute ──► output/effect
▼ ... continues until the last statement or an error
(no object code produced at any stage)
2. How It Works Internally
- Read the next statement (or a block, e.g. a function body).
- Lexical and syntax analysis — tokenise and build a small parse tree for that statement.
- Semantic checking at run time — variable lookups, type checks performed against the run-time symbol table.
- Evaluate / execute — perform the operations, update variables, produce output or call the OS.
- Repeat until EOF; if an error occurs, report it with the line number and stop.
Because names and types are resolved while the program runs, an interpreted language is typically dynamically typed (Python, JavaScript, Ruby).
3. Types of Interpreters
| Type | How it behaves | Examples |
|---|---|---|
| Pure / classic interpreter | Translates and executes every statement, every run — no caching | Classic BASIC, early shell interpreters |
| Bytecode interpreter + VM | Source is first compiled to compact bytecode, then the VM interprets the bytecode | Java (javac → .class → JVM), Python (.pyc), C#, PHP |
| JIT-assisted interpreter | Starts interpreting, then compiles hot code to machine code at run time | JVM HotSpot, V8 (JavaScript), PyPy |
| Command/scripting interpreter | Interprets shell/DSL commands one line at a time | Bash, PowerShell, SQL engines |
| REPL | Read-Eval-Print Loop for interactive experimentation | Python IDLE, Node console |
4. Trace of Interpretation
x = 2 → read, translate, execute : symbol table { x = 2 }
y = x * 3 → read, translate, execute : symbol table { x = 2, y = 6 }
print(y) → read, translate, execute : outputs 6
print(z) → run-time error: name 'z' is not defined (line 4)
Note that the error appears only when that line is reached — statements after it never run.
5. Advantages and Limitations
| Advantages | Limitations |
|---|---|
| No separate compilation step — write and run immediately | Slower execution: translation overhead on every run |
| Errors reported with the exact line, at the point of failure → easy interactive debugging | Errors that a compiler would find statically appear only when that code path runs |
| Memory efficient — no object code stored | Source code must be available (harder to protect) |
| Platform independence at the source/bytecode level (JVM, Python) | Needs the interpreter installed on every machine |
| Excellent for scripting, prototyping, teaching, REPL testing | Not suitable for CPU-bound or hard real-time work without JIT |
| Dynamic typing and interactive development (REPL, notebooks) | Dynamic typing can hide bugs until run time |
6. Interpreter vs Compiler — Summary Table
| Basis | Compiler | Interpreter |
|---|---|---|
| Unit of translation | Entire program | One statement (or block) at a time |
| Intermediate/object code | Produced (.obj / .exe) | Not produced |
| Time of execution | After full translation | During translation |
| Speed of resulting program | Faster | Slower |
| Error detection | After the whole program is scanned; lists all errors | Stops at the first run-time error encountered |
| Memory requirement | Higher (object code + symbol tables) | Lower |
| Portability of output | Machine specific executable | Source/bytecode is portable |
| Debugging convenience | Less convenient | Very convenient (line-by-line) |
| Examples | C, C++, Go, Rust | Python, Ruby, JavaScript (initial), BASIC |
Hybrid approach: Java and .NET compile source to an intermediate bytecode, which is then interpreted by a virtual machine and selectively JIT-compiled — combining portability with near-compiled speed.
7. Exam Points
- Define an interpreter and explain its working with a flow diagram — 5 marks.
- Difference between compiler and interpreter (tabular) — 5 marks, almost certain.
- Which is better for debugging and why? Which executes faster and why? — 3-5 marks.
- Explain the bytecode + JVM / JIT scheme used by Java — 5 marks.
- List two advantages and two limitations of an interpreter — 3 marks.
- Why does an interpreter report errors only when the faulty statement executes? — 3 marks.