Для генерации промежуточного кода расширяющего синтаксический анализ так, чтобы учесть свойство ЭВМ, для которого создается код. Чтобы не углубляться в конкретное свойство реальной ЭВМ, будем полагать, что промежуточный код - это код специальной (виртуальной) машины, подогнанный под язык SPL и названный SPL - процессором. Программой для виртуальной машины (SPL - программой) является промежуточный код, созданный в процессе синтаксического анализа. Выполняется эта программа интерпретатором (функция из файла interp.c), которая фактически моделирует работу SPL - процессора. SPL - процессор имеет память для SPL - программы, которая моделируется глобальными данными массива ТСO и переменными atrnm, cpnm, cgv; память данных, которая моделируется  стеком st, где помещается значения всех данных в процессе интерпретации. Используются указатели: t - вершина стека st, sp - начало области локальных данных функции (записи активирования), p - текущей команды в TCO. Поскольку каждая функция в SPL имеет локальные переменные и допускается рекурсия, то для распределения памяти при выполнении функций необходимо  динамическое (автоматическое) управление памятью: при вызове- выделение памяти в стеке st, а при возврате -ее освобождение. При вызове каждой функции, включая main, в стеке выделяется запись активизирования этого вызова, куда заносятся: значения фактических параметров p1,p2...pn; количество параметров; адрес возврата в TCD (адрес вызова команды) АПОВ; адрес предыдущей записи активации в стеке ( откуда произошел вызов функции) ААК; локальные и временные данные ЛТД, которые используются при вычислении этого вызова функции (рисунок 101).

 

 

z101

 

Рисунок 101

 

 

Например, стек st для последовательных вызовов функции main ® p0 ®p1 имеет область глобальных данных ГЛД, которая вмещает cgv элементов, и три записи активизации для функции main, p0, p1. Адреса возврата из main приравнивается - 1; sp показывает верхнюю запись активизации в стеке, а t - последний занятый элемент (рисунок 101).

В любой момент выполнения SPL - программы доступными являются глобальные данные, записанные в основании стека st со смещением k для адресации st [k] и локальные данные в верхней части, которые указываются через sp. Для параметров, расположенных ниже sp, смещение k < 0; для локальных данных, записанных выше sp, k > 0; адресация st [sp + k]. Смещения всех данных вычисляются при обработке описаний для n параметров - (n+2), ...- 4, - 3; для локальных данных 1, 2, ...; для глобальных переменных 0, 1, 2 ... Так, при обработке описания

a (x, y, z),

begin int v,w, ... end.

Будут вычислены смещения: x-> - 5, y -> - 4, z -> - 3, v -> 1, w -> 2.

Файл spltp,h имеет описание кодов команд и структуры SPL - процессора:

/* коды и структура команды полной записи /*

enum { OPR, LiT, COE, LDI, STE, STI, CAL, INI, JMP, JMC};

typedef struct

{ int code, opd;} cmd;

SPL - программа создается в процессе синтаксического анализа в массиве TCD : TCD [i] = { f, a }, где: f = TCD [i]. cod, a = TCD [i].opd.

Действия задаются кодами операций:

OPR - выполнение операции а над вершиной стека.

LIT - занесение в стек константы а;

LDE, LDI -запись в стек значения глобальной (локальной) переменной со смещением а;

STE,STI-запоминание значения вершины стека в глобальной (локальной) переменной со смещением а;

CAL - вызов функции с точкой входа а;

INI - увеличение t на а (выделение памяти);

JMP - осуществление безусловного перехода на команду а;

JMC - выполнение условного перехода на команду а, если верхний элемент стека меньше или равен нулю (этот элемент изымается из стека). У команды с кодом OPR допустимы операции: ввести в стек число из  stdin ( a = 1); вывести верхнее значение из стека в stdout (a = 2); выполнить над двумя верхними элементами операцию +, -. *, /, %, (а = 3 - 7); заменить знак верхнего элемента стека (а = 8); вернуться из функции (результат размещается в верхнем элементе стека) (а = 9); остановить исполнение SPL - программы (а = 10). При возврате из main печатается результат и p = -1, при завершении остановкой (достигли end в функции) p = -2.