Польская инверсная запись была выбрана нами в качестве языка внутреннего представления программы, в частности, потому, что записанная таким образом программа может быть легко проинтерпретирована.
Идея алгоритма очень проста: просматриваем ПОЛИЗ слева направо; если встречаем операнд, то записываем его в стек; если встретили знак операции, то извлекаем из стека нужное количество операндов и выполняем операцию, результат (если он есть) заносим в стек и т.д.
Итак, программа на ПОЛИЗе записана в массиве P; пусть она состоит из N элементов-лексем. Каждая лексема - это структура
struct lex {int class; int value;},
возможные значения поля class:
- лексемы-метки (номера элементов в ПОЛИЗе)
- логические константы true либо false (других лексем - служебных слов в ПОЛИЗе нет)
- операции (других лексем-ограничителей в ПОЛИЗе нет)
- целые константы
- лексемы-идентификаторы (во время интерпретации будет использоваться значение)
- лексемы-идентификаторы (во время интерпретации будет использоваться адрес).
Считаем, что к моменту интерпретации распределена память под константы и переменные, адреса занесены в поле address таблиц TID и TNUM, значения констант размещены в памяти.
В программе-интерпретаторе будем использовать некоторые переменные и функции, введенные нами ранее.
void interpreter(void) {
int *ip;
int i, j, arg;
for (i = 0; i<=N; i++)
{curr_lex = P[i];
switch (curr_lex.class) {
case 0: ipush (curr_lex.value); break;
/* метку ПОЛИЗ - в стек */
case 1: if (eq ("true")) ipush (1);
else ipush (0); break;
/* логическое значение - в стек */
case 2: if(eq ("+")){ipush (ipop() + ipop()); break};
/*выполнили операцию сложения, результат - в стек*/
if (eq ("-"))
{arg = ipop(); ipush (ipop() - arg); break;}
/*аналогично для других двухместных арифметических и логических операций */
if (eq ("not")) {ipush (!ipop()); break;};
if (eq ("!")) {j = ipop(); i = j-1; break;};
/* интерпретация будет продолжена с j-го элемента ПОЛИЗа */
if (eq ("!F")) {j = ipop(); arg = ipop();
if (!arg) {i = j-1}; break;};
/*если значение arg ложно, то интерпретация будет продолжена с j -го элемента ПОЛИЗа, иначе порядок не изменится */