Учебное пособие / ресурс для реализации ВМ - PullRequest
42 голосов
/ 09 января 2010

Я хочу, чтобы в целях самообразования была реализована простая виртуальная машина для динамического языка, предпочитаемая на C. Что-то вроде Lua VM, или Parrot, или Python VM, но проще. Существуют ли какие-либо хорошие ресурсы / учебные пособия по достижению этого, кроме просмотра кода и документации по проектированию существующих виртуальных машин?

Редактировать: зачем закрывать голосование? Я не понимаю - это не программирование. Пожалуйста, прокомментируйте, если есть конкретная проблема с моим вопросом.

Ответы [ 6 ]

30 голосов
/ 12 января 2010

Полагаю, вам нужна виртуальная машина, а не просто интерпретатор. Я думаю, что они две точки на континууме. Интерпретатор работает над чем-то близким к оригинальному представлению программы. ВМ работает на более примитивных (и автономных) инструкциях. Это означает, что вам нужен этап компиляции для перевода одного на другой. Я не знаю, хотите ли вы сначала поработать над этим или у вас еще есть вводный синтаксис.

Для динамического языка вам нужно где-то, где хранятся данные (как пары ключ / значение) и некоторые операции, которые воздействуют на него. ВМ поддерживает магазин. Программа, запущенная на нем, представляет собой последовательность инструкций (включая поток управления). Вам необходимо определить набор инструкций. Я бы предложил начать с простого набора, например:

  • основные арифметические операции, включая арифметические сравнения, доступ к магазину
  • базовый поток управления
  • встроенная печать

Возможно, вы захотите использовать подход к вычислениям на основе стека, как это делают многие виртуальные машины. В вышесказанном пока не так много динамики. Чтобы достичь этого, нам нужны две вещи: способность вычислять имена переменных во время выполнения (это просто означает строковые операции) и некоторая обработка кода как данных. Это может быть так же просто, как разрешить ссылки на функции.

В идеале ввод в ВМ должен быть в байт-коде. Если у вас еще нет компилятора, он может быть сгенерирован из базового ассемблера (который может быть частью виртуальной машины).

Сама виртуальная машина состоит из цикла:

1. Look at the bytecode instruction pointed to by the instruction pointer.
2. Execute the instruction:
   * If it's an arithmetic instruction, update the store accordingly.
   * If it's control flow, perform the test (if there is one) and set the instruction pointer.
   * If it's print, print a value from the store.
3. Advance the instruction pointer to the next instruction.
4. Repeat from 1.

Работа с именами вычисляемых переменных может быть сложной: инструкция должна указывать, в каких переменных находятся вычисляемые имена. Это можно сделать, разрешив инструкциям ссылаться на пул строковых констант, предоставленных во входных данных.

Пример программы (в сборке и байт-код):

offset  bytecode (hex)   source
 0      01 05 0E         //      LOAD 5, .x
 3      01 03 10         // .l1: LOAD 3, .y
 6      02 0E 10 0E      //      ADD .x, .y, .x
10      03 0E            //      PRINT .x
12      04 03            //      GOTO .l1
14      78 00            //      .x: "x"
16      79 00            //      .y: "y"

Предполагаемые коды инструкций:

"LOAD x, k" (01 x k) Load single byte x as an integer into variable named by string constant at offset k.
"ADD k1, k2, k3" (02 v1 v2 v3) Add two variables named by string constants k1 and k2 and put the sum in variable named by string constant k3.
"PRINT k" (03 k) Print variable named by string constant k.
"GOTO a" (04 a) Go to offset given by byte a.

Вам нужны варианты, когда переменные именуются другими переменными и т. Д. (И уровни косвенности сложно обдумать). Ассемблер просматривает аргументы типа «ADD .x, .y, .x» и генерирует правильный байт-код для добавления из строковых констант (а не вычисляемых переменных).

9 голосов
/ 09 января 2010

Ну, речь идет не о реализации виртуальной машины в C, но, поскольку это была последняя вкладка, которую я открыл перед тем, как увидел этот вопрос, я чувствую, что мне нужно указать статью о реализации компилятора байт-кода QBASIC и виртуальной машина в JavaScript с использованием тега <canvas> для отображения. Он включает весь исходный код, чтобы получить достаточное количество QBASIC, реализованного для запуска игры «nibbles», и является первым в серии статей о компиляторе и интерпретаторе байт-кода; этот описывает виртуальную машину, и он обещает будущие статьи с описанием компилятора.

Кстати, я не голосовал за закрытие вашего вопроса, но вы получили закрытое голосование как дубликат вопроса прошлого года о том, как узнать о внедрении виртуальной машины. Я думаю, что этот вопрос (об учебнике или о чем-то относительно простом) достаточно отличается от того, что он должен оставаться открытым, но вы можете обратиться к этому вопросу за советом.

4 голосов
/ 18 мая 2010

Еще один ресурс, на который стоит обратить внимание, - это реализация языка Lua . Это виртуальная машина на основе регистров, которая имеет хорошую репутацию для производительности. Исходный код написан на ANSI C89 и, как правило, очень удобочитаем.

Как и в большинстве высокопроизводительных скриптовых языков, конечный пользователь видит читаемый высокоуровневый динамический язык (с такими функциями, как замыкания, хвостовые вызовы, неизменяемые строки, числа и хеш-таблицы в качестве основных типов данных, функции в качестве значений первого класса, и больше). Исходный текст компилируется в байт-код виртуальной машины для выполнения реализацией виртуальной машины, схема которой в значительной степени соответствует описанию ответа Эдмунда .

Большие усилия были направлены на то, чтобы реализация самой виртуальной машины была переносимой и эффективной. Если требуется еще большая производительность, компилятор как раз вовремя из байтового кода виртуальной машины в собственные инструкции существует для 32-битной x86 и находится в бета-версии для 64-битной.

2 голосов
/ 30 декабря 2012

Для запуска (даже если не C , но C ++ ) вы можете взглянуть на muParser .

Это математическое выражениесинтаксический анализатор, который использует простую виртуальную машину для выполнения операций.Я думаю, что даже вам нужно время, чтобы все понять;в любом случае, этот код более прост, чем полная виртуальная машина, способная запустить настоящую полную программу.(Кстати, я проектирую подобную lib в C # - это ее ранние стадии, но следующие версии позволят компилировать в .NET / VM IL или, возможно, новую простую виртуальную машину, такую ​​как muParser ).

Другая интересная вещь - NekoVM (он выполняет файлы .n с байт-кодом).Это проект с открытым исходным кодом , написанный на C , и считается, что его основной язык (.neko) генерируется компилятором исходного кода .В духе последней темы смотрите Haxe от того же автора (тоже с открытым исходным кодом).

1 голос
/ 22 октября 2014

Как и вы, я также изучал виртуальные машины и компиляторы, и одна хорошая книга, которую я могу порекомендовать, - Дизайн компилятора: виртуальные машины . Он описывает виртуальные машины для императивных, функциональных, логических и объектно-ориентированных языков, предоставляя набор инструкций для каждой виртуальной машины вместе с руководством по компиляции языка более высокого уровня для этой виртуальной машины. Я реализовал виртуальную машину только для обязательного языка, и это уже было очень полезным упражнением.

Если вы только начинаете, я могу порекомендовать другой ресурс: PL101 . Это интерактивный набор уроков по JavaScript, который проведет вас через процесс реализации синтаксических анализаторов и интерпретаторов для различных языков.

0 голосов
/ 27 августа 2018

Я опаздываю на вечеринку, но я бы рекомендовал Game Scripting Mastery, которая берет вашу руку, чтобы написать рабочий скриптовый язык и его виртуальную машину с нуля. И с очень небольшим предварительным условием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...