An interpreter does not translate source code to native machine code. While your computer is only capable of executing machine code, the machine code that it executes does not necessarily have to be a translation of a higher-level language. Confusing? Let's look at a simple toy example...
Consider the programming language PrintForPony that has two functions, print
and sleep
. The print
function takes a string of characters as its only argument and prints it to stdout, while sleep
takes a positive integer as its only argument and puts the current thread to sleep for that amount of time. A pseudo-BNF for PFP:
program ::= statement_list
statement_list ::= statement | statement NEWLINE statement_list
statement ::= print STRING | sleep POSITIVE_INTEGER
Here's a super simple Java-implementation of an intepreter for PFP. The program takes a source file as its only argument and interprets it:
import java.io.BufferedReader;
import java.io.FileReader;
public class PFPInterpreter {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(args[0]));
String line = null;
while ((line = br.readLine()) != null) {
if (line.startsWith("print ")) {
System.out.println(line.substring("print ".length()));
} else if (line.startsWith("sleep ")) {
Thread.sleep(Long.parseLong(line.substring("sleep ".length())));
} else {
throw new IllegalArgumentException("Unknown function: " + line);
}
}
}
}
A sample source file:
print Hello, World!
sleep 1000
print Goodbye, World!
And sample output:
$ java PFPInterpreter test.pfp
Hello, World!
Goodbye, World!
At no point in time is PFP translated into native machine code. The native machine code that is executed is the JVM, which has nothing to do with this toy language. We could also write a compiler for PFP that would translate the code into an executable file (I'm not going to, because this answer is already getting too long), but the point of the matter is that an interpreter does not compile to native machine code - it reads an input file and does something based on the contents.
To answer the questions:
1) An interpreter is the runtime that runs your code for you. I'm not sure exactly where you've read that interpreters don't work at runtime, but I'm also not sure what it's supposed to mean.
2) As demonstrated above, no, an interpreter does not translate to native machine code. A JIT-compiler does. Your processor only executes native machine code, but that native machine code could be a program that reads an arbitrary file and does something based on the contents. In that sense, an interpreter is really just a typical program that accepts input in the form of text files.
3) JIT-compilation is pretty complicated, and I am not an expert at all. However, with Java's HotSpot, for instance, code blocks must be executed a certain amount of times (1,500 for client, 15,000 for server, IIRC) before the JIT-compiler is invoked on them. This is likely because the actual compilation is not free, and it's very likely that the compiled native machine code is cached for later executions (which would explain the requirement of many executions). This makes JIT-compilation is an investment (in time and space) that may not be faster (perhaps even slower) on the first execution, but subsequent executions will be faster because compilation is no longer necessary, and the native machine code is more efficient.
4) See above.
I hope that helps!