Вобще хотелось бы узнать есть ли такие интерпретаторы которые исполняют прямо по абстрактному синтаксическому дереву (которое получается после парсинга), то есть без преобразования в байт код? Или старый PHP единственный в своём роде?
Таких очень мало, это не особо оптимальный подход для интерпретаторов. Можешь среди разных LISP'ов и Scheme поискать, ну или https://github.com/HaxeFoundation/hscript посмотри, если нужен один пример, он умеет сериализовывать аст в бинарщину, но это не байткод в классическом понимании вещей.
Несколько более оптимальный подход - интерпретатор, основанный на замыканиях, ну или closure-based подход. Хорошо описан в SICP и в "Интерпретации Лиспа и Scheme". А ссылки на репы нет смысла давать, если нет понимания, как оно работает в теории. Не поймут.
Это фактически компиляция, только не в машинный код или байт-код, а в замыкания в языке программирования, на котором пишется такой интерпретатор. В наивном интерпретаторе обход AST будет выполнен каждый раз заново. Например, есть цикл, где 100500 раз вызывается функция c арифметическим выражением. Интерпретатор тогда будет 100500 раз обходить AST этой функции и продираться через это выражение. Вместо этого можно сделать один обход, создавая при этом замыкания, в которых и будут заключены все вычисления, ожидающие только входных данных. Потом останется лишь вызвать замыкание (с параметром - состоянием лексичесого окружения, например) и получить значение интерпретируемого подвырежения. AST здесь больше не нужно. Плюс в том, что в замыканиях (в их локальных переменных) можно естественным образом что-нибудь закешировать, например, местоположение переменных, что лексическом окружении хранятся (чтобы по строковым именам к ним не обращаться каждый раз), и этим ускорить к ним доступ.
Пытаюсь переварить про замыкания... как-то не очень понятно... То есть AST по частям преобразуют в замыкания ... А замыкания как я полагаю это массивы указателей(или ссылки) на подпрограммы которые получают указатели на аргументы . Или что такое замыкания в этом случае? Ведь это не замыкания в языках программирования? Было бы интересно на каком либо примере увидеть эти замыкания хотя бы готовые.
Как обычно, рекурсивно обходят и преобразуют. На выходе получается замыкание, представляющее всё вычисление. То, о чем вы полагаете, скорее называется шитым кодом. Да, я говорю именно про замыкания в языках программирования. То есть процедура плюс переменные, захваченные в контексте определения этой процедуры (ну или в лексической области видимости). Так в том же питоне есть замыкания. Например, на javascript такой пример: Код (Text): function incrementor() { var i = 0; return function() { i++; return i; } } var inc = incrementor(); inc(); inc(); console.log(inc()); - выведет "3". Здесь переменная i определена в функции incrementor, а изменяется во внутренней анонимной функции, причем значение переменной сохраняется между её вызовами. Интерпретатор на замыканиях может выглядеть так. Псеводкод на javascript'е: Код (Text): function analyze(ast) { switch (ast.nodeType) { case NUMBER: return analyzeNumber(ast); case VARIABLE: return analyzeVariable(ast); case IF: return analyzeIf(ast); ... } } function analyzeNumber(ast) { var number = stringToNumber(ast.text); return function(env) { return number; }; } function analyzeVariable(ast) { var location = findLocation(ast); return function(env) { return getVariableValue(env, location); }; } function analyzeIf(ast) { var executePred = analyze(ast.predicate); var executeThen = analyze(ast.then); var executeElse = analyze(ast.else); return function(env) { var result = executePred(env); if (result == true) { return executeThen(env); } else { return executeElse(env); } }; } var environment = ...; for (;;) { var expression = readline('> '); var ast = parse(expression); var execute = analyze(ast); var result = execute(environment); print(result); } То есть функция analyze проходит по AST и возвращает замыкание, которое, в свою очередь, возвращает результат вычисления, когда его вызывают. А enviromnent - это состояние интерпретатора, т. е. память, переменные и так далее. Как видите, в анонимных функциях AST больше не используется, а всё, что нужно для работы, сохранено в локальных переменных. Ну а в цикле всё и происходит - прочитали, распарсили, выполнили, вывели результат. Вообще, задавая вопросы на форумах, вы никогда не разберетесь, так будет только хаос в голове. Ищите всё самостоятельно в литературе, а ссылки выше я дал.
есть ещё паттерн проэктирования https://ru.wikipedia.org/wiki/Интерпретатор_(шаблон_проектирования) помоему это про эту тему
Заметка о языке :Firth сделанного в рамках Lua. https://blog.ionoclast.com/2015/05/firth-pre-alpha-1-a-forth-like-language-for-dsl-creation/ :Firth pre-alpha 1– a Forth-like language for DSL creation. P.S. Можно использовать отдельно библиотеку LibJit https://ru.wikipedia.org/wiki/LibJIT для повышения производительности Форт программ при стековом байт коде VM (может и для МК может сработать при наличии ресурсов в необходимой мере) Библиотека нормально собралась и отработала тесты под Linux 32 (правда не последняя её версия) В примере библиотеки "скриптовый" Паскаль Dpas с выполнением кода во время загрузки его с исходника. На Github есть некоторое количество отдельных языков в привязкe к этой библиотеке. С помощью библиотеки строится внутреннее представление программы в памяти, а далее при наличии поддержки бэка целевой архитектуры он выполняется, но может быть выполнен из этого представления без наличия бек-энда и с хорошей производительностью при этом. https://ru.bmstu.wiki/LibJIT ... Основы программного моделирования ЭВМ.pdf Интерпретаторы байт-кодов своими руками (из 3-ёх статей) --- Сообщение объединено, 23 авг 2022 --- Пара познавательных видосиков русскоязычных преподавателей по Форт 1. Системы реального времени (СРВ, RTS). Лекция. Язык Forth (Shared March 10, 2022) (Автор только ошибся - в Фортe и стандарте есть локальные переменныe) 2. Операционные системы - Система Forth 17.12.21
Незнаю, может это как-то внесет ясность, исходники питона https://www.python.org/downloads/source/ Еще есть дирректория include в установленном питоне с заголовочными файлами на си. Тоже интересно, только в контексте embedded python. Не совсем понятны некоторые вещи.