Как обрабатывать область при генерации байт-кода с помощью рукописного компилятора

Я написал небольшой компилятор для простой машины стека. Он может собирать и обрабатывать область действия / функции только через несколько хаков виртуальных машин. То есть он определяет область действия и определения переменных области в самом байт-коде.

Могу ли я получить некоторые советы о том, как я должен обращаться с областью.

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

Другие проблемы включают в себя, как сохранить переменные снаружи после возврата. Так что переменная все еще имеет свое значение. Я могу поместить его в стек, но у меня может быть много переменных.

Я думаю, что есть некоторая работа компилятора, чтобы проверить эти вещи, но я не могу думать о том, что нужно сделать, чтобы сделать это.

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;
}

Во время компиляции вы поддерживаете один "стек переименования" для каждой переменной. А также:

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

  2. Когда вы видите назначение / использование, вы заменяете имя тем, что находится на вершине стека.

  3. Когда вы покидаете область видимости, вы вытаскиваете ее из стека.

Другие вопросы по тегам