I understand that an interpreter could do one of the following things (and probably more):

  1. Execute programming-language source code directly.

  2. First translate the source code to some intermediate code (which is less human-readable and more efficient or easier for the interpreter to execute), and then execute this code.

My questions are:

  1. Is this assumption true? Am I understanding correctly the general function of an interpreter? Or is something I wrote wrong?

  2. If my assumptions are true, which one of these two possible functions are more common? Please show examples.

  • 1
    Sharing your research helps everyone. Tell us what you've tried and why it didn’t meet your needs. This demonstrates that you’ve taken the time to try to help yourself, it saves us from reiterating obvious answers, and most of all it helps you get a more specific and relevant answer. Also see How to Ask. – ratchet freak Mar 7 '14 at 10:12
  • 7
    I'd recommend you to stop worrying about the vague, inconsistent and totally irrelevant terminology, it's nothing but a waste of time. – SK-logic Mar 7 '14 at 10:24
  • @SK-logic Especially the distinction between interpreting and executing. – Patrick Mar 7 '14 at 11:40

An interpreter is generally understood to execute a program without compiling the program in a separate step. However, most modern interpreters do not interpret the source code directly – this isn't really possible anyway for anything more complex than BASIC. Instead, they first parse the code, then produce an intermediate representation, and finally execute this representation.

Common intermediate representations are:

  • bytecode, which is a high-level cousin of machine code. They are executed on a virtual machine that uses this bytecode. The bytecode is not generally human-readable, although a human-readable serialization may exist (e.g. Jasmin assembler for JVM bytecode).

    A language implementation may choose bytecode because it's essentially similar to most existing architectures, albeit more restricted, and thus safer. It is also really simple to store bytecode in a file, or interchange it otherwise. Most VMs execute bytecode (starting with the original P-Code, over CPython to the JVM).

  • other opcodes, e.g. in-memory data structures like ASTs. These sometimes do not have any permanent serialization.

    A language implementation may choose to represent the code as a data structure because this is a lot more flexible (just as Lisp is more flexible than C), and because it removes the need to decode bytecodes inside the VM – making it simpler to implement. This route is most useful for simple projects, but is also used in some serious interpreters like perl.

In practice, the boundary between compilers and interpreters has been blurred beyond recognition, and most interpreters could also be considered compilers because they compile to some intermediate representation (even if it isn't stored anywhere). The two useful distinguishing characteristics are:

  • when the source is compiled – ahead of time, or before each execution
  • what the compilation target is – machine code, some intermediate representation executed by a VM

Some implementations like the primary Java implementations defy overly simple categorization: Here, code is compiled ahead of time to a bytecode which is interpreted on a VM which may also perform JIT compilation to machine code.

  • Thanks for your answer. One question: You said that '[In Java], code is compiled ahead of time to a bytecode which is interpreted on a VM..' Why are you saying that the bytecode is interpreted by the VM? The VM, as far as I understand, executes the bytecode. Than why are you using the term 'interpreted*? Is there a difference between interpreting bytecode, to executing it? – Aviv Cohn Mar 7 '14 at 11:52
  • 1
    @Prog “executing” is a general term, “interpreting” is more specific and tells us how the bytecode is executed. The alternative to interpreting is compiling the bytecode before executing it, e.g. to machine code. An interpreter is characterized by a loop which might look like while (op = getNextOp(state)) state = jumpTable[op](state); and this is what java does most of the time. – amon Mar 7 '14 at 13:03
  • I'm sorry for being technical but I just want to really understand: The 'interpretation' that the JVM does with the Java Bytecode, is of the first type I described in my question: Simply read a line of code, run it, read the next, etc. As opposed to the second type I described, which is first translating to some intermediate code and then running - Since the bytecode is already intermediate code. Is this accurate? – Aviv Cohn Mar 7 '14 at 13:27
  • @Prog Yes, java bytecode is an intermediate code, compiled down from Java. But it still isn't machine code. The JVM still has to read the bytecodes and interpret them to decide what to do. So instead of interpreting the source code directly, Java compiles it down to a more compact form, then interprets that. Actually, the modern JVMs are clever enough to decide whether to just interpret the bytecode, or compile it down further into machine code. They make this decision on the fly, depending on which is likely to be the most efficient. – Simon B Mar 7 '14 at 13:51
  • 1
    @MaciejPiechotka Btw, here is the main interpreter loop of the JVM, starting with line 886. It then switches on the opcode, which is less flexible but more performant than Perl's strategy. – amon Mar 7 '14 at 14:58

Is this assumption true? Am I understanding correctly the general function of an interpreter? Or is something I wrote wrong?

It is true, in theory. But a practical interpreter will do at least some work to translate the source code into an intermediate code of some kind.

If my assumptions are true, which one of these two possible functions are more common? Please show examples.

The latter. In fact, I'm not aware of any real-life examples that directly execute the source code ... though some primitive BASIC interpreters might have worked that way.

Of course, the intermediate code could take a variety of forms. It code take the form of instructions for an (imaginary) machine; e.g. Java bytecodes, Pascal PCODE, Microsoft CLR, and so on. Or it could take the form of an abstract syntax tree ... with decorations.

  • Could the intermediate code be of plain text form - and still be considered intermediate code produced by an interpreter? For example, if the interpreter reads the source code line print("something");, and translates it to the intermediate code: p-something: Will it still be considered intermediate code of an interpreter? – Aviv Cohn Mar 7 '14 at 12:04
  • @Prog - It entirely depends on who is doing the "considering". Or to put it another why, show me the definition of "intermediate code" that you are using, and I can give you an answer. – Stephen C Mar 7 '14 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.