;
Control table interpreter: Logic is specified as data formatted as a table. ; Bytecode interpreter: Some interpreters process
bytecode which is an intermediate format of logic compiled from a high-level language. For example,
Emacs Lisp is compiled to bytecode which is interpreted by an interpreter. One might say that this compiled code is machine code for a virtual machine implemented by the interpreter. Such an interpreter is sometimes called a
compreter. ; Threaded code interpreter: A
threaded code interpreter is similar to bytecode interpreter but instead of bytes, uses pointers. Each instruction is a word that points to a function or an instruction sequence, possibly followed by a parameter. The threaded code interpreter either loops fetching instructions and calling the functions they point to, or fetches the first instruction and jumps to it, and every instruction sequence ends with a fetch and jump to the next instruction. One example of threaded code is the
Forth code used in
Open Firmware systems. The source language is compiled into "F code" (a bytecode), which is then interpreted by a
virtual machine. ; Abstract syntax tree interpreter: An abstract syntax tree interpreter transforms source code into an
abstract syntax tree (AST), then interprets it directly, or uses it to generate native code via JIT compilation. In this approach, each sentence needs to be parsed just once. As an advantage over bytecode, AST keeps the global program structure and relations between statements (which is lost in a bytecode representation), and when compressed provides a more compact representation. Thus, using AST has been proposed as a better intermediate format than bytecode. However, for interpreters, AST results in more overhead than a bytecode interpreter, because of nodes related to syntax performing no useful work, of a less sequential representation (requiring traversal of more pointers) and of overhead visiting the tree. ; Template interpreter: Rather than implement the execution of code by virtue of a large switch statement containing every possible bytecode, while operating on a software stack or a tree walk, a template interpreter maintains a large array of bytecode (or any efficient intermediate representation) mapped directly to corresponding native machine instructions that can be executed on the host hardware as key value pairs (or in more efficient designs, direct addresses to the native instructions), known as a "Template". When the particular code segment is executed the interpreter simply loads or jumps to the opcode mapping in the template and directly runs it on the hardware. Due to its design, the template interpreter very strongly resembles a JIT compiler rather than a traditional interpreter, however it is technically not a JIT due to the fact that it merely translates code from the language into native calls one opcode at a time rather than creating optimized sequences of CPU executable instructions from the entire code segment. Due to the interpreter's simple design of simply passing calls directly to the hardware rather than implementing them directly, it is much faster than every other type, even bytecode interpreters, and to an extent less prone to bugs, but as a tradeoff is more difficult to maintain due to the interpreter having to support translation to multiple different architectures instead of a platform independent virtual machine/stack. To date, the only template interpreter implementations of widely known languages to exist are the interpreter within Java's official reference implementation, the Sun HotSpot Java Virtual Machine, It separates the high-level machine instructions from the underlying
electronics so that the high-level instructions can be designed and altered more freely. It also facilitates providing complex multi-step instructions, while reducing the complexity of computer circuits. == See also ==