Вот пример интерпретатора:
while (<>) {
my ($cmd, @args) = split;
if ($cmd eq '...') { ... }
elsif ($cmd eq '...') { ... }
elsif ($cmd eq '...') { ... }
else { ... }
}
Это указывает на то, что интерпретируемая программа не запускается в отдельном процессе от интерпретатора.
Это также указывает на то, что не обязательно перевод на машинный язык.
Обратите внимание, что Perl - это скомпилированный язык, а не интерпретируемый.
$ perl -MO=Concise,-exec -e'print("Hello, world!\n");'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <0> pushmark s
4 <$> const[PV "Hello, world!\n"] s
5 <@> print vK
6 <@> leave[1 ref] vKP/REFC
-e syntax OK
Тем не менее, скомпилированная форма не является нативной инструкцией. Это можно сделать разными способами, но Perl эффективно их интерпретирует. Ниже приведен переводчик:
int
Perl_runops_standard(pTHX)
{
OP *op = PL_op;
PERL_DTRACE_PROBE_OP(op);
while ((PL_op = op = op->op_ppaddr(aTHX))) {
PERL_DTRACE_PROBE_OP(op);
}
PERL_ASYNC_CHECK();
TAINT_NOT;
return 0;
}
(скопировано с здесь .)
Операции на самом деле являются структурами данных, расположенными в связанном списке (с другими указателями для переходов), а не потоком инструкций кодирования байтов. Вышеупомянутый цикл проходит по списку, выполняя функцию, связанную с каждым операцией. Эта функция возвращает адрес следующей операции для выполнения, таким образом формируя программу.
Некоторые языки, вероятно, используют аналогичный подход. Другие языки определенно используют другой подход.