There are two general approaches to programming language implementation: •
Interpretation: The program is read as input by an interpreter, which performs the actions written in the program. •
Compilation: The program is read by a compiler, which translates it into some other language, such as
bytecode or
machine code. The translated code may either be directly
executed by hardware or serve as input to another interpreter or another compiler. Typically interpreters support a
read–eval–print loop that makes developing new programs much quicker; compilers force developers to use a much slower edit-compile-run-debug loop. A typical program, when compiled with an ahead-of-time compiler, will (after the program has been compiled) run faster than the same program processed and run with a JIT compiler; which in turn may run faster than that same program partially compiled into a
p-code intermediate language such as a
bytecode and interpreted by an
application virtual machine; which in turn runs much faster than a pure interpreter. In theory, a programming language can first be specified and then later an interpreter or compiler for it can be implemented (waterfall model). In practice, often things learned while trying to implement a language can effect later versions of the language specification, leading to combined programming language design and implementation. Both interpreters and compilers usually implement some sort of
symbol table.
Interpreters An interpreter is a program that reads another program, typically as text, Interpreters typically read code line by line, and parse it to convert and execute the code as operations and actions. An interpreter is composed of two parts: a
parser and an
evaluator. After a program is read as input by an interpreter, it is processed by the parser. The parser breaks the program into
language components to form a
parse tree. The evaluator then uses the parse tree to execute the program.
Virtual machine A virtual machine is a special type of interpreter that interprets bytecode. To improve their efficiencies, many programming languages such as
Java, and
C# are compiled to bytecode before being interpreted.
Just-in-time compiler Some virtual machines include a just-in-time (JIT) compiler to improve the efficiency of bytecode execution. While the bytecode is being executed by the virtual machine, if the JIT compiler determines that a portion of the bytecode will be used repeatedly, it compiles that particular portion to machine code. The JIT compiler then stores the machine code in
memory so that it can be used by the virtual machine. JIT compilers try to strike a balance between longer compilation time and faster execution time. If a compiler of a given
high level language produces another high level language, it is called a
transpiler. Transpilers can be used to extend existing languages or to simplify compiler development by exploiting
portable and well-optimized implementations of other languages (such as
C).
Multiple implementations Programming languages can have multiple implementations. Different implementations can be written in different languages and can use different methods to compile or interpret code. For example, implementations of
Python include: •
CPython, the
reference implementation of Python •
IronPython, an implementation targeting the
.NET Framework (written in
C#) •
Jython, an implementation targeting the
Java virtual machine •
PyPy, an implementation designed for speed (written in RPython) == Process ==