Как обрабатывать область при генерации байт-кода с помощью рукописного компилятора
Я написал небольшой компилятор для простой машины стека. Он может собирать и обрабатывать область действия / функции только через несколько хаков виртуальных машин. То есть он определяет область действия и определения переменных области в самом байт-коде.
Могу ли я получить некоторые советы о том, как я должен обращаться с областью.
Проблемы, с которыми я сталкиваюсь, в основном, как мне сообщить, когда и когда не следует перезаписывать переменную снаружи переменной внутри, и тому подобное. Байт-код изменчив, и я бы предпочел изменить его.
Другие проблемы включают в себя, как сохранить переменные снаружи после возврата. Так что переменная все еще имеет свое значение. Я могу поместить его в стек, но у меня может быть много переменных.
Я думаю, что есть некоторая работа компилятора, чтобы проверить эти вещи, но я не могу думать о том, что нужно сделать, чтобы сделать это.
1 ответ
Одним из способов было бы переименовать переменные во время компиляции, чтобы гарантировать отсутствие маскирования. Так:
{
declare foo;
foo = assignment;
{
declare foo;
foo = another_assignment;
another_use = foo;
}
use = foo;
}
Эквивалентно:
{
declare foo_0;
foo_0 = assignment;
{
declare foo_1;
foo_1 = another_assignment;
another_use = foo_1;
}
use = foo_0;
}
Во время компиляции вы поддерживаете один "стек переименования" для каждой переменной. А также:
Всякий раз, когда вы видите объявление, вы генерируете новое имя и помещаете его в стек переименования соответствующей переменной.
Когда вы видите назначение / использование, вы заменяете имя тем, что находится на вершине стека.
Когда вы покидаете область видимости, вы вытаскиваете ее из стека.