\subsection{Генерация С++\,--текста}

Основной тип объекта, над которым выполняются действия, --- Рефал-вы\-ра\-же\-ние,
для его описания в данной реализации определен класс Expr, рассмотренный ранее.
Таким образом, для генерации выходного кода важ\-но, что в ASAIL\,--программе используются три типа данных: 
целые (реа\-ли\-зо\-ван\-ный в С++ как int), Рефал-выражения (соответственно, класс Expr) и ло\-ги\-чес\-кие 
(как результат промежуточных вычислений в условных операторах). 

В модуле генерации С++\,--программы выделяются правила, связанные
с генерацией простых операторов и блоков (им соответствуют стандартные 
средства императивного языка) и генерацией специальных функций или методов 
для работы с объектами класса Expr. Также разделяются методы вычисления
значений целочисленных, логических выражений и выражений типа Expr. 

Рассмотрим правила соответствия конструкций абстрактного им\-пе\-ра\-тив\-но\-го языка выходным С++\,--конструкциям, использованные в данной реа\-ли\-за\-ции компилятора. В рассматриваемых примерах отражена общая схема преобразований, при этом преобразование ASAIL--выражения \textbf{X} обо\-зна\-че\-но конструкцией \convert{\textbf{X}} и знаком ''=''. \\    
 
\textbf{\textsl{A. Генерация операторов и блоков.}}
\begin{itemize}

	\item 
	\textbf{Определение  функции }\\  \\
\textsl{ \convert{(FUNC t.name (e.arg) (e.res) e.body)}} = \\ \\
\textsl{RF\_FUNC  \\
 (\convert{t.name}, (RF\_ARG \convert{e.arg}), (RF\_RES \convert{e.res})) \\
 \smallskip
\convert{e.body} \\
\smallskip
RF\_END}

	\item
\textbf{Вызовы функции} \\  \\
\textsl{\convert{ (CALL t.name (e.args1) (e.args2))} } = \\
 \\
\textsl{RF\_CALL (\convert{t.name}, (\convert{e.args1}), (\convert{e.args2}))}  \\ \\
 \textsl{ \convert{(TAILCALL t.name (e.args1) (e.args2)) }} = \\ \\
 \textsl{RF\_TAILCALL (\convert{t.name}, (\convert{e.args1}), (\convert{e.args2}))}

	\item
	\textbf{Оператор присваивания} \\  \\
\textsl{
\convert{(ASSIGN t.var e.expr)}} = \\  \\
\textsl{
 \convert{t.var} = \convert{e.expr}; }

	\item
	\textbf{ Объявление переменной} \\  \\
\textsl{
\convert{(DECL s.type t.var)}}  = \\ \\
\textsl{
\convert{s.type} \ \convert{t.var};}

	\item
	\textbf{Условный оператор} \\ \\
\textsl{
\convert{(IF (e.cond) e.body)}} = \\  \\
\textsl{
if (\convert{e.cond}) \\
\{  \\
\hspace*{5mm} \convert{e.body} \\
\}}

	\item
	\textbf{Генерация помеченного блока} \\ \\
\textsl{
\convert{(LABEL t.label e.body )}} = \\  \\
\textsl{
\{ \\
\hspace*{5mm} \convert{e.body} \\
\} \\
\convert {t.label}: \{\}} 

	\item
	\textbf{Цикл  FOR} \\ \\
\textsl{	
\convert{(FOR (t.label) (e.cond) (INC-ITER t.var) e.body)}} = \\ \\
\textsl{
for ( ; \convert{e.cond} ; iter(\convert{t.var})++) \\
\{  \\
 \hspace*{5mm} \convert{e.body} \\
 \smallskip
 \hspace*{5mm}  \convert{t.label} : \{ \} \\
\}}

	\item
	\textbf{Оператор перехода к следующей итерации цикла for} \\ \\
\textsl{
\convert{(CONTINUE t.label)}} = \\ \\
\textsl{
goto \convert{t.label} ;}

	\item
	\textbf{ Оператор выхода из цикла (t.label --- метка блока, со\-дер\-жа\-ще\-го цикл)} \\  \\
\textsl{
\convert{(BREAK t.label)}}\\  \\
\textsl{
goto \convert{t.label} ;}

	\item
\textbf{Функция отщепления слева фрагмента Рефал-выражения}  \\ \\
\textsl{
\convert{LSPLIT e.expr (e.min) t.left t.right)} } =\\ \\
\textsl{
lsplit (\convert{e.expr}, \convert{e.min}, \convert{t.left}, \convert{t.right});} 

	\item
\textbf{Функция отщепления справа фрагмента Рефал-выражения} \\ \\
\textsl{
\convert{(RSPLIT e.expr (e.min) t.left t.right)}} = \\ \\
\textsl{
rsplit (\convert{e.expr}, \convert{e.min}, \convert{t.left}, \convert{t.right});} 

	\item
	\textbf{Оператор генерации исключения} \\  \\
\textsl{
\convert{(ERROR e.expr)}} =\\  \\
\textsl{
error  (\convert{e.expr});}

	\item
	\textbf{try-блок} \\  \\
\textsl{
\convert{(TRY e.body )}} =\\  \\
\textsl{
trap \\
\{ \\
\hspace*{5mm} \convert{e.body} \\
\}}

	\item
	\textbf{Блок перехвата исключений} \\  \\
\textsl{
\convert{(CATCH-ERROR e.body)}} = \\  \\
\textsl{
with \\
\{  \\
\hspace*{5mm} \convert{e.body} \\
\}}

	\item
	\textbf{Вызов метода освобождения памяти, занимаемой объектом t.var} \\  \\
\textsl{
\convert{(DROP t.var)}}  = \\ \\
\textsl{
\convert{t.var}.drop\,();}

	\item
	\textbf{Оператор успешного выхода из функции} \\ \\
\textsl{
\convert{RETURN}} = \\  \\
\textsl{
return true;}

	\item
	\textbf{Оператор неуспешного выхода из функции} \\  \\
\textsl{
\convert{RETFAIL}} = \\  \\
\textsl{
retfail;}

	\item
	\textbf{Оператор неуспешного выхода из функции} \\ \\
\textsl{\convert{FATAL}} = \\ \\
\textsl{error (''Unexpected fail'');}

	\item
	\textbf{Конструктор объекта класса Expr} \\  \\
\textsl{\convert{(EXPR  t.var e.expr )}} = \\ \\
\textsl{Expr \convert{t.var}\,(\convert{e.expr});}

	\item
	\textbf{Конструктор объекта класса Expr, значение которого  ---  со\-дер\-жи\-мое  скобочного терма, занимающего в e.expr позицию e.pos} \\ \\
\textsl{\convert{(DEREF t.var e.expr  (e.pos))}} = \\ \\
\textsl{Expr \convert{t.var}\,(\convert{e.expr}, \convert{e.pos});}

	\item
	\textbf{Конструктор объекта класса Expr, который является 
под\-вы\-ра\-же\-ни\-ем выражения e.expr, 
начиная с элемента e.pos, длиной e.len} \\ \\
\textsl{ \convert{(SUBEXPR t.var e.expr (e.pos) (e.len))}} = \\ \\
\textsl{Expr \convert{t.var}\,(\convert{e.expr}, \convert{e.pos}, \convert{e.len});}

	\item  
	\textbf{Конструктор константного объекта класса Expr (термы, вхо\-дя\-щие в e.expr, объединены операцией конкатенации)} \\ \\
\textsl{\convert{(CONSTEXPR t.name e.expr )}} = \\ \\
\textsl{const Expr \convert{t.name} = \convert{e.expr};}

	\item
	\textbf{Объявление функции} \\  \\
\textsl{\convert{(DECL\_FUNC t.name)}} = \\ \\
\textsl{RF\_DECL (\convert{t.name});}

\end{itemize}


\textbf{\textsl{B. Генерация логических операций, их результат 
 --- true или false. }}

\begin{itemize}
	\item 
	\textbf{Условие истинно, если элемент, занимающий в выражении e.expr позицию e.pos, является символом (в смысле Рефал+)} \\ \\
\textsl{\convert{(SYMBOL? e.expr (e.pos))}} = \\  \\
\textsl{\convert{e.expr}.symbol\_at(\convert{e.pos})}

	\item
	\textbf{Условие истинно, если равны подвыражения  \\
	(e.expr1 и e.expr2 --- исходные выражения; e.pos1 и e.pos2 --- начальные позиции сравниваемых подвыражений, e.len1 и e.len2 --- их длины) } \\ \\
\textsl{\convert{(EQ (e.expr1)(e.pos1)(e.len1)(e.expr2)(e.pos2)(e.len2))}} = \\ \\
\textsl{Expr :: eq (\convert{e.expr1}, \convert{e.pos1}, \convert{e.len1}, \\ 
\convert{e.expr2}, \convert{e.pos2}, \convert{e.len2})}
 
 	\item 
 	\textbf{ Условие истинно, если равны подвыражения \\
 	(e.expr1 и e.expr2 --- исходные выражения; e.pos1 и e.pos2 --- начальные позиции сравниваемых подвыражений,  e.len --- их длина; известно, что подвыражения 
не содержат скобочных термов} \\ \\
\textsl{\convert{(FLAT-EQ (e.expr1)(e.pos1)(e.expr2)(e.pos2)(e.len))}} = \\  \\
\textsl{Expr :: flat\_eq \\
(\convert{e.expr1}, \convert{e.pos1}, \convert{e.expr2}, \convert{e.pos2}, \convert{e.len})}

	\item
	\textbf{Условие истинно, если в выражении e.expr   
подвыражение, начинающееся в e.pos и имеющее длину e.len,   
не содержит скобочных термов} \\ \\
\textsl{\convert{(FLAT-SUBEXPR? e.expr (e.pos)(e.len))}} = \\  \\
\textsl{\convert{e.expr}.flat\_at(\convert{e.pos}, \convert{e.len})}

	\item
	\textbf{Логическое отрицание} \\  \\
\textsl{\convert{(NOT e.cond)}} = \\ \\
\textsl{! \convert{e.cond}}

	\item
 	\textbf{Логическая операция (левоассоциативная)} \\ \\
\textsl{\convert{(INFIX  s.op (e.log1 e.log2 ...))}} = \\  \\
\textsl{ (\convert{e.log1} \ s.op \ \convert{e.log2} \ s.op ...)}

\end{itemize}


\textbf{\textsl{C. Генерация методов работы с объектами класса Expr, их ре\-зуль\-тат --- объект класса Expr.}}
   
\begin{itemize}
	
	\item    
	\textbf{Операция ''навешивания скобок''} \\  \\
\textsl{ \convert{(PAREN e.expr)}} = \\  \\
\textsl{\convert{e.expr} ()}

	\item
	\textbf{Извлечение содержимого скобочного терма, 
  находящегося в e.expr  в позиции e.pos} \\  \\
\textsl{\convert{(DEREF e.expr (e.pos)) }} = \\   \\
\textsl{Expr (\convert{e.expr}, \convert{e.pos})}

	\item
	\textbf{Выделение в выражении e.expr подвыражения, 
  на\-чи\-наю\-ще\-го\-ся  в e.pos и  имеющего длину e.len} \\  \\
\textsl{ \convert{(SUBEXPR e.expr (e.pos)(e.len))}} = \\  \\
\textsl{Expr (\convert{e.expr}, \convert{e.pos}, \convert{e.len})}
  
  	\item
  	\textbf{Создание объекта класса Expr} \\  \\
\textsl{\convert{(EXPR e.expr) } } = \\  \\
\textsl{Expr (\convert{e.expr})}
  
\end{itemize}

\textbf{\textsl{D. Генерация целочисленных операций. }}
   
\begin{itemize}

	\item 
	\textbf{Вычисление длины выражения} \\ \\
\textsl{\convert{(LENGTH e.expr)}} = \\  \\
\textsl{(int) \convert{e.expr}.get\_len()}

	\item
	\textbf{Вычисление минимума из целых аргументов} \\ \\
\textsl{\convert{(MIN e.args)}} = \\ \\
\textsl{pxx\_min (\convert{e.args})}

	\item
	\textbf{Вычисление максимума из целых аргументов} \\ \\
\textsl{\convert{(MAX e.args)}} = \\  \\
\textsl{pxx\_max (\convert{e.args})}
 
 	\item
 	\textbf{Арифметическая операция (левоассоциативная)} \\ \\
\textsl{\convert{(INFIX  s.op (e.int1 e.int2 ...))}} = \\  \\
\textsl{ (\convert{e.int1} s.op \ \convert{e.int2} \ s.op...)}

\end{itemize}

