Любой язык может потенциально быть скомпилированным. .net содержит генератор собственного кода (NGEN), который переводит байт-код в собственный код и потенциально может использоваться для создания собственных двоичных файлов. И действительно, любой язык, который компилируется в байт-код, может иметь такую же возможность.
Это становится сложно, когда вы переходите на языки сценариев (Python, PHP, Perl и т. Д.). В таких случаях обычно проще связать скрипт с интерпретатором в один исполняемый файл. Но ничто не мешает кому-то писать PHP или Perl-компилятор, за исключением того, что функции eval обоих языков в значительной степени требуют возможности разбирать и выполнять текст - это означает, что в итоге вы получите интерпретатор, по крайней мере связанный с программой в любом случае.
Большой вопрос: «На каком уровне он перестает быть компилируемым?». На это я отвечу «когда вы запускаете код, который должен иметь возможность интерпретировать сам себя». IE: я бы не стал пытаться скомпилировать любой язык с оператором / функцией eval, если бы мне не разрешили удалить оператор / функцию.