Реализация стековой виртуальной машины для подмножества C - PullRequest
7 голосов
/ 21 июля 2010

Привет всем! В настоящее время я внедряю простой язык программирования для обучения, но мне нужны некоторые советы. В настоящее время я разрабатываю свой переводчик, и у меня возникла проблема.

Мой язык является подмножеством C, и у меня возникла проблема с реализацией интерпретатора стека. На языке скомпилируется следующее:

somefunc ()
{
    1 + 2;
}

main ()
{
    somefunc ();
}

Теперь все в порядке, но когда вычисляется «1 + 2», результат помещается в стек, а затем функция возвращается, но в стеке все еще есть число, и его не должно быть. Как я могу обойти эту проблему?

Я думал о сохранении «состояния» стека перед вызовом функции и восстановлении «состояния» после вызова функции. Например, сохранение количества элементов в стеке, затем выполнение кода функции, возврат, а затем извлечение из стека до тех пор, пока у нас не будет того же числа элементов, что и раньше (или, возможно, +1, если функция что-то вернула).

Есть идеи? Спасибо за любые советы!

Ответы [ 3 ]

8 голосов
/ 21 июля 2010

Отличный вопрос! Одно из моих хобби - написание компиляторов для игрушечных языков, так что спасибо за ваш превосходный вкус программирования.

выражение-выражение - это выражение, в котором код в выражении является просто выражением. Это означает что-либо в форме <expression> ;, которая включает в себя такие вещи, как назначения и вызовы функций, но не if s, while s или return s. Любое выражение выражения будет иметь оставшееся значение в конце стека, которое вы должны отбросить.

1 + 2 является выражением-выражением, но так же:

  • x = 5;
    Присвоение выражение оставляет значение 5 в стеке, поскольку результатом присваивания является значение левого операнда. После завершения оператора вы получаете неиспользованное значение 5.

  • printf("hello world!\n");
    printf () возвращает количество выводимых символов. У вас останется это значение в стеке, поэтому извлеките его, когда инструкция завершится.

Фактически каждый оператор выражения будет оставлять значение в стеке, если тип выражения не равен void. В этом случае вы либо используете специальные операторы void и ничего потом не выталкиваете, либо помещаете в стек притворное «пустое» значение, чтобы вы всегда могли вытолкнуть значение.

2 голосов
/ 21 июля 2010

Вам понадобится более умный парсер.Когда вы видите выражение, значение которого не используется, вам нужно выдать POP.

0 голосов
/ 28 июня 2017

Это важная возможность по оптимизации обучения.у вас есть функция, которая выполняет числовое, но целочисленное математическое вычисление, результат int math даже не используется ни в каком виде, ни в какой-либо форме.

Если ваш компилятор оптимизирует эту функцию, это сократит количество создаваемого байт-кодаказнен ни за что!

...