\chapter{Acse}
\label{cha:acse}
\texttt{ACSE} (Advanced Compiler System for Education) is a simple compiler developed for educational purpose as a tool for the course ``Formal languages and compiler'' .
\texttt{ACSE} is able to translate a source code written in \texttt{LanCE}~\ref{sec:sourcecode} (Language for Compilers Education) into an assembly for the MACE architecture (see the \texttt{MACE} documentation).

The main goal of this documentation is to show the compilation process by introducing every single step made by the compiler.
Also, in the following sections is briefly discussed the grammar for a source code written in \texttt{LanCE} that can be given as input to the \texttt{ACSE} compiler.
Finally, a brief introduction is given for each module and library used by ACSE.

\section{Compilation process}
In figure~\ref{fig:images:compiler} is shown the entire compilation process.
Every phase of the compilation chain takes as input the output of the previous phase.
\texttt{ACSE} takes as input a source file written in LanCE language. (see\ref{sec:sourcecode}).

\begin{figure}[!hbp]
\centering
\resizebox{16cm}{!}
{\includegraphics{acse/compiler}}
\caption{Compilation process}
\label{fig:images:compiler}
\end{figure}

The source file is analyzed and `tokenized'(i.e. subdivided into tokens) by a lexer in the first phase of the compilation process.
The string of tokens is then processed by the parser in order to check and analyze the overall structure of the source program.

\texttt{ACSE} uses a parser automatically generated with \texttt{Bison}.
Bison is a general-purpose parser generator that converts an annotated context-free grammar into an LALR(1) deterministic bottom-up or parser for a given grammar.

At first the SDT analyzes the correctness of a tokenized input provided by the lexer; then it executes some semantic actions (if any) in correspondence of each recognized grammatical rule.
The current parser implementation provides support for both error tracking and notification of simple warning messages.

During the parsing process, the tokenized input is transformed into specific assembly statements for the target machine (\texttt{MACE}).
However at this point of the compilation process, the assembly produced as output uses an unbounded number of registers.
Since the target machine owns a limited set of general-purpose registers, the liveness analysis and a register allocation steps are then performed.

Finally the assembly code is written as output in the last phase of the compilation process.

\section{Tokens for \texttt{LanCE}}
As previously said, a lexer component scans the input source code in search of specific patterns of strings.
These patterns are defined via regular expressions and are used in order to identify lexical tokens (or lexemes).
Regular expressions are coded in the form of \texttt{FLEX} rules (see the \texttt{FLEX} documentation).

\texttt{ACSE} delegates the lexical analysis to a `lexer' automatically generated by \texttt{FLEX}.

The following is a list of bindings between tokens and regular expressions.

\begin{tabular}{l}
\\
\\
\\
\\
\\
\\
\\
\\
\end{tabular}

\begin{tabular}{l|l|l|l}
\hline
Token  &Regular Expression  &Token  &Regular Expression  \\
\hline
DIGIT    &[0-9]   &ID       &[a-zA-Z\_][a-zA-Z0-9\_]* \\
LBRACE   &\{ &RBRACE   &\} \\
LSQUARE   &[ &RSQUARE   &] \\
LPAR     &( &RPAR     &) \\
SEMI     &; &COLON    &: \\
PLUS     &+ &MINUS    &- \\
MUL\_OP   &* &DIV\_OP   &/ \\
MOD\_OP   &\% &AND\_OP   &\& \\
OR\_OP    &$\mid$ &NOT\_OP    &! \\
ASSIGN   &= &LT       &< \\
GT       &> &SHL\_OP   &$\ll$ \\
SHR\_OP   &$\gg$ &EQ       &== \\
NOTEQ    &!= &LTEQ     &$<=$ \\
GTEQ     &$>=$ &ANDAND   &\&\& \\
OROR     &$\parallel$ &COMMA    &, \\
DO       &do &ELSE     &else \\
FOR      &for &IF       &if \\
TYPE     &int &WHILE    &while \\
RETURN   &return &READ     &read \\
WRITE    &write & &\\
\hline
\end{tabular}

\begin{tabular}{l}
\\
\\
\end{tabular}

\section{A grammar for \texttt{LanCE}}
\label{sec:sourcecode}
In this section is provided a grammar for the source code.

\begin{tabular}{l}
\\
\\
\end{tabular}

\begin{tabular}{lp{0.6\textwidth}}
\hline
\emph{\textbf{\texttt{program}}}  : &\emph{var\_declarations} \emph{statements} \\
\emph{\textbf{\texttt{var\_declarations}}}  : &\emph{var\_declarations} \emph{var\_declaration} \\
   & $\mid$ $\varepsilon$ \\
\emph{\textbf{\texttt{var\_declaration}}}  : &TYPE \emph{declaration\_list} SEMI \\
\emph{\textbf{\texttt{declaration\_list}}}  : &\emph{declaration\_list} COMMA \emph{declaration} \\
   & $\mid$ \emph{declaration} \\
\emph{\textbf{\texttt{declaration}}} : &IDENTIFIER ASSIGN NUMBER \\
\emph{\textbf{\texttt{statements}}}  : &\emph{statements statement} \\
   & $\mid$  \emph{statement} \\
\emph{\textbf{\texttt{statement}}} : &IDENTIFIER LSQUARE \emph{exp} RSQUARE ASSIGN \emph{exp} SEMI \\
   & $\mid$ IDENTIFIER ASSIGN \emph{exp} SEMI \\
   & $\mid$ \emph{if\_statements} \\
   & $\mid$ \emph{if\_statements} ELSE \emph{code\_block} \\
   & $\mid$ \emph{while\_statements}  \\
   & $\mid$ \emph{do\_while\_statements} SEMI \\
   & $\mid$ SEMI \\
   & $\mid$ RETURN SEMI \\
   & $\mid$ READ LPAR IDENTIFIER RPAR SEMI \\
   & $\mid$ WRITE LPAR \emph{exp} RPAR SEMI \\
\emph{\textbf{\texttt{code\_block}}}  : &\emph{statement} \\
   & $\mid$ LBRACE \emph{statements} RBRACE \\
\emph{\textbf{\texttt{while\_statements}}}  : &WHILE LPAR \emph{exp} RPAR \emph{code\_block} \\
\emph{\textbf{\texttt{do\_while\_statements}}}  : &DO \emph{code\_block} WHILE LPAR \emph{exp} RPAR \\
\emph{\textbf{\texttt{if\_statements}}}  :  &IF LPAR \emph{exp} RPAR \emph{code\_block} \\
\end{tabular}

\begin{tabular}{lp{0.6\textwidth}}
\emph{\textbf{\texttt{\emph{exp}}}} : &NUMBER  \\
   & $\mid$ IDENTIFIER \\
   & $\mid$ IDENTIFIER LSQUARE \emph{exp} RSQUARE \\
   & $\mid$ NOT\_OP NUMBER \\
   & $\mid$ NOT\_OP IDENTIFIER \\
   & $\mid$ \emph{exp} AND\_OP \emph{exp} \\
   & $\mid$ \emph{exp} OR\_OP \emph{exp} \\
   & $\mid$ \emph{exp} PLUS \emph{exp} \\
   & $\mid$ \emph{exp} MINUS \emph{exp} \\
   & $\mid$ \emph{exp} MUL\_OP \emph{exp} \\
   & $\mid$ \emph{exp} DIV\_OP \emph{exp}  \\
   & $\mid$ \emph{exp} LT \emph{exp}  \\
   & $\mid$ \emph{exp} GT \emph{exp}  \\
   & $\mid$ \emph{exp} EQ \emph{exp}  \\
   & $\mid$ \emph{exp} NOTEQ \emph{exp}  \\
   & $\mid$ \emph{exp} LTEQ \emph{exp}  \\
   & $\mid$ \emph{exp} GTEQ \emph{exp}  \\
   & $\mid$ \emph{exp} SHL\_OP \emph{exp}  \\
   & $\mid$ \emph{exp} SHR\_OP \emph{exp}  \\
   & $\mid$ \emph{exp} ANDAND \emph{exp}  \\
   & $\mid$ \emph{exp} OROR \emph{exp}  \\
   & $\mid$ LPAR \emph{exp} RPAR \\
   & $\mid$ MINUS \emph{exp} \\
   \hline
\end{tabular}

\begin{tabular}{l}
\\
\\
\end{tabular}

Taking the parser generated by Bison starting from this grammar, the syntax analyzer is able to check that a token string is syntactically correct.

\section{Example of Source Code}
An example of a program - compliant with the grammar shown in the previous section - that computes the factorial of an integer number and prints out to standard output the result is shown in table~\ref{tab:fact}.

If the number given as input is negative the program writes to standard output `-1' before exiting.

\begin {table}
\begin {verbatim}


int value, fact;        /* variables declarations */

read(value);            /* read from standard input the
                         * value of 'value' */
if (value < 0) {        /* invalid input */
   write(-1);        
   return;           
}

fact = 1;               /* initialize 'fact' */
while(value > 0) {      /* compute the factorial of value */
   fact = value * fact;
   value = value - 1;
}

write(fact);            /* write the result to standard output */
\end{verbatim}
\caption{An example of source code}
\label{tab:fact}
\end{table}

\section{Semantic actions}
The parser tests the correctness of each statement found in the source program and eventually performs some semantic actions.
In a Bison grammar, a grammar rule can have an action made up of C statements. Each time the parser recognizes a match for that rule, the action is executed.

If the statement is syntactically correct, a semantic action (a Bison rule) is executed every time a non-terminal, associated with a semantic action, is recognized and reduced.

The main goal of the ACSE SDT is to gather all the useful information about each statement of the source program (the source code given as input).
Each instruction is typically translated into one or more assembly instructions.
Then, each assembly instruction is stored inside a data structure called \texttt{t\_program\_infos} defined in \texttt{axe\_engine.h}.

\section{Program information}
An instance of \texttt{t\_program\_infos} contains all the useful information about a program being compiled.

A \texttt{t\_program\_infos} is a composition of various element:
\begin {itemize}
   \item An instance of a symbol table
   \item An instance of label manager
   \item A list of program variables
   \item A list of instruction and assembler directives.
\end {itemize}

Before starting with the lexical analysis and the syntactical analysis, the compiler initializes an instance of \texttt{t\_program\_infos} called \texttt{program}.

Source program is translated (by executing various semantic actions) into various assembly instructions and assembler directives that are orderly stored inside the \texttt{program} instance.

Data structures for assembly instructions and assembler directives are defined in a file called \texttt{axe\_struct.h}.

An assembly instruction is described by:

\begin {itemize}
   \item An operation identifier (for example: `SUB');
   \item A set of instruction parameters which depend on the instruction type;
   \item A user comment (optional);
   \item A label identifier (optional).
\end {itemize}

Valid instruction parameters are:
\begin {itemize}
      \item Register identifiers;
      \item Immediate values (signed integer values);
      \item Addresses (for example: label identifiers).
\end {itemize}

For example: an assembly ADD instruction is a ternary instruction that performs a binary add between two values.
An instruction that performs a sum between \texttt{`R1'} and \texttt{`R2'}, and stores the result in \texttt{`R3'} can be declared as follows:\texttt{ADD R3 R1 R2}

the keyword ``\texttt{ADD}'' is used as an operation identifier.
The number of instruction parameters depends only on the instruction type. For example: ternary instructions accept only register identifiers as parameters.

In the previous example the parameters \texttt{`R3' `R1' `R2'} were all register identifiers.
A register identifier is an alias for a machine general-purpose register.

A user comment can be associated to an assembly instruction for debugging purpose.
A label can be associated to an assembly instruction as shown in the example below:

\texttt{L1: ADD R3 R1 R2}

In this example, a label `L1' is associated to an assembly ADD instruction.

A Assembler directive is defined as follows:
\begin {itemize}
   \item Directive type identifier (for example: \texttt{.WORD})
   \item Value associated with the directive
   \item A label identifier (optional)
\end {itemize}

Here is an example of assembler directive .WORD:
\texttt{.WORD 0}

More information about assembly instructions and assembler directives can be found in the Assembler documentation.

\section{Source Program Variables}
\label{sec:spv}
Every time a program variable declaration is found in the source code, an instance of \texttt{t\_axe\_variable} is created and assigned to the list of variables of a \texttt{t\_program\_infos} instance.

Structure \texttt{t\_axe\_variable} defines:
\begin {itemize}   
   \item A data type (for example: INTEGER );
   \item An Array Size (defined only if the variable is an array);
   \item An initial value;
   \item A variable identifier;
\end {itemize}

Here is an example of how it's possible to declare in a Source Program a variable called ``\texttt{var}'' as an integer with an initial value of `100':

\texttt{int var = 100;}

An instance of \texttt{t\_axe\_variable} for the program variable ``var'' would be defined in the following manner:
 \texttt{INTEGER} as data type;
 \texttt{100} as initial value;
 the string ``\texttt{var}'' as variable identifier.

All the instances \texttt{t\_axe\_variable} are used at the end of the compilation process in order to produce \texttt{.WORD} and/or \texttt{.SPACE} assembler directives (see the MACE documentation).

In our example, the \texttt{t\_axe\_variable} defined for the program variable ``var'' will produce a \texttt{.WORD 100} data directive.

\section{Symbol Table}
A symbol table is a data structure used at translation time to keep track of each program variable encountered in the source program.

Each entry of the symbol table is associated to a single program variable. An entry of the symbol table is defined in the following manner:
\begin {itemize}
   \item ID - A variable identifier (see section~\ref{sec:spv})
   \item Type  - The data type of the variable `ID' (see section~\ref{sec:spv})
   \item A Register identifier.
\end {itemize}

The register identifier refers to a register location (a machine general-purpose register) where the variable is currently stored.


\section{Example}

After parsing, the program in table~\ref{tab:fact} produces the intermediate assembly shown in table~\ref{tab:assem}.

\begin{table}
\begin{tabular}{|l|ll|l|}
\hline
Source Program & &Assembly &Comments \\
\hline
int value, fact;        &    &.DATA      & /* variables declarations */ \\
                        &L0: \ \ &.WORD 0    & /* initialize 4 bytes of data to 0 */\\
                        &L1: \ \ &.WORD 0    & /* initialize 4 bytes of data to 0 */\\
read(value);            &    &.TEXT      & /* start of a block of code */ \\
                        &    &READ R1 0  & /* read from standard input */ \\
if (value $<$ 0) \{     &    &SUBI R3 R1 \#0 & /* sub immediate */ \\
                        &    &SLT R3 0   & /* set R3 on less than zero */ \\
                        &    &BEQ L2     & /* `branch on equal' to label L2 */ \\
write(-1);              &    &ADDI R4 R0 \#-1 & /* add immediate */ \\
                        &    &WRITE R4 0 & /* write R4 to standard output */ \\
return; \}              &    &HALT       & /* stop the program execution */ \\
fact = 1;               &L2: \ \ &ADDI R2 R0 \#1 & \\
while(value $>$ 0) \{   &L3: \ \ &SUBI R5 R1 \#0 & \\
                        &    &SGT R5 0  & /* set R3 on `less than zero' */ \\
                        &    &BEQ L4  & /* `branch on equal' to label L4 */ \\
fact = value * fact;    &    &MUL R6 R1 R2 & /* binary mult. operation */\\
                        &    &ADDI R2 R6 \#0 &\\
value = value - 1; \}   &    &SUBI R7 R1 \#1 &\\
                        &    &ADDI R1 R7 \#0 &\\
                        &    &BT L3  & /* `branch true' to label `L3' */ \\
write(fact);            &L4: \ \ &WRITE R2 0 &/* write R2 to standard output */ \\
                        &    &HALT & /* stop the program execution */ \\
\hline
\end{tabular}
\caption{Intermediate Assembly representation}
\label{tab:assem}
\end{table}

\begin{tabular}{l}
\\
\\
\end{tabular}

The content of the symbol table is shown in table~\ref{tab:sytable}.

\begin{table}
\begin{tabular}{|l|l|l|}
\hline
Variable Identifier &Type &Register Location \\
\hline
value      &INTEGER       &R1 \\
fact       &INTEGER       &R2 \\
\hline
\end{tabular}
\caption{Symbol Table}
\label{tab:sytable}
\end{table}

\begin{tabular}{l}
\\
\\
\end{tabular}

\section{API documentation}
\label{sec:api}
The main purpose of this section is to give an overview of the essential programming interfaces of ACSE.
Since the ACSE design defines several functions over a number of header files, the user is also referred to the commented source code.

The file \textbf{\texttt{symbol\_table.h}} declares the functions needed to manipulate the content of a symbol table:
\begin{itemize}
   \item look up a symbol table for a symbol
   \item define and insert a new symbol into a symbol table
   \item set the register location information of a symbol
   \item retrieve the register location information associated with a symbol
\end{itemize}

\begin{tabular}{l}
\\
\\
\end{tabular}
The \textbf{\texttt{symbol\_table.h}} includes a file called \textbf{\texttt{sy\_table\_constants.h}} which defines a set of macros used for error tracking.

\begin{tabular}{l}
\\
\\
\end{tabular}

The file \textbf{\texttt{axe\_struct.h}} defines many data structures used by the parser. The parser is automatically generated with Bison giving as input the file \texttt{Acse.y}.

\begin{tabular}{l}
\\
\\
\end{tabular}

The \texttt{Label Manager} is defined in \textbf{\texttt{axe\_labels.h}}.
A Label Manger offers a set of functions to works with labels:
\begin{itemize}
   \item \texttt{reserveLabelID}
   \item \texttt{fixLabelID}.
\end{itemize}

\texttt{reserveLabelID} is used when the user code requires the creation of a new label.
\texttt{fixLabelID} is used to assign a given label to an instruction.

\begin{tabular}{l}
\\
\\
\end{tabular}

The library \texttt{axe\_gencode.h} defines a set of functions that can be directly used to generate assembly instructions and insert them into an instance of \texttt{t\_program\_infos}.

For example: the function \texttt{gen\_add\_instruction} is used to create an ADD instruction.

\begin{tabular}{l}
\\
\\
\end{tabular}

The file \texttt{axe\_engine.h} defines the \texttt{t\_program\_infos} data structure and other useful functions used (for example) to:
\begin{itemize}
   \item initialize a new instance of \texttt{t\_program\_infos}
   \item add an assembly instruction to a \texttt{t\_program\_infos} instance
   \item create a variable (i.e. an instance of t\_axe\_variable) and assign it to an instance of \texttt{t\_program\_infos}
   \item request for a free register location (see the function \texttt{getNewRegister})
   \item write an assembly file as output of the compilation process (see the function \texttt{writeAssembly})
\end{itemize}

\begin{tabular}{l}
\\
\\
\end{tabular}

The file \texttt{axe\_array.h} provides a set of functions used to generate load/store instructions from/to array elements.

An example is the function \texttt{loadArrayElement} that takes as input:
\begin {itemize}
   \item an array variable identifier
   \item an array subscript identifying an array element.
\end {itemize}

This function returns as output a register location identifier that holds the value of the specified array element.

\begin{tabular}{l}
\\
\\
\end{tabular}

According to the Bison grammar defined in \texttt{Acse.y}, an expression is defined by the non-terminal \texttt{exp} (see also the section ~\ref{sec:sourcecode}).
The file \texttt{axe\_structs.h} defines an expression as an instance of \texttt{t\_axe\_expression}.
An instance of \texttt{t\_axe\_expression} contains two fields:
\begin {itemize}
   \item A value (a register identifier or an immediate value)
   \item An expression type.
\end {itemize}
The expression type is used to determine if the value of the expression is stored into a register or is an immediate value.
The file \texttt{axe\_expressions.h} defines two functions used to generate instructions for expressions:
\begin {itemize}
   \item perform\_binary\_comparison;
   \item perform\_bin\_numeric\_op.
\end {itemize}

The function \texttt{perform\_bin\_numeric\_op} is used to generate instructions for binary numeric operations (for example: the expression ``a + 5'').
\texttt{perform\_binary\_comparison} is used to generate instructions that perform a comparison between two values.
These functions take as input two expressions (the two operands of the binary comparison/operation) and return an instance of \texttt{t\_axe\_expression} (containing the result of the binary comparison/operation).

Finally, the file \texttt{axe\_utils.h} defines the function \texttt{get\_symbol\_location} that works as a wrapper for the functions defined in \texttt{symbol\_table.h}.
Given as input a variable/symbol identifier, the \texttt{get\_symbol\_location} look up the symbol table in search of the register location where the symbol is stored.
If the requested variable/symbol was never loaded from memory to a register (i.e. the symbol holds an invalid register location info), this function asks for a free register where to assign the variable/symbol.
At last, the register location (where the variable/symbol is stored) is returned as output to the caller.

\section{Examples of Bison semantic actions}
In this section we discuss three examples of bison semantic actions.
The first and the second example describes how to manipulate expressions.
The third example describes how to define semantic actions for a \texttt{do-while} statement.

\subsection{Expressions}
Section~\ref{sec:api} introduced what is an expression and which functions exposed by \texttt{axe\_expressions.h} can be used in order to generate code for expressions.

Here we will discuss the semantic rules associated with the following Bison rules:
\begin{tabular}{lp{0.6\textwidth}}
\emph{\textbf{\texttt{\emph{exp}}}} : &\\
   & $\mid$ \emph{exp} AND\_OP \emph{exp} \\
   & $\mid$ \emph{exp} LT \emph{exp}  \\
\end{tabular}

According to the FLEX source file \texttt{Acse.lex}, an AND\_OP token represent a `binary and' operator (\&).
An example of `binary and' operation is the following:
\texttt{``a \& b''} (where \texttt{a} and \texttt{b} are variables declared in the source program).

Suppose in this example that both \texttt{a} and \texttt{b} are program variables which values are stored into unknown register locations.
At first we have to query the symbol table in order to retrieve the register locations associated with both \texttt{a} and \texttt{b}. This can be done by calling the function \texttt{get\_symbol\_location} declared in \texttt{axe\_utils.h} for each of the two program variables.

Finally, we can use the function \texttt{gen\_andb\_instruction} declared in \texttt{axe\_gencode.h} in order to generate an assembly \texttt{ANDB} instruction.
A \texttt{gen\_andb\_instruction} requires five parameters:
\begin{itemize}
   \item An instance of t\_program\_infos that contains all the information about the program being compiled;
   \item A destination register identifier;
   \item Two register identifiers as parameters for the \texttt{ANDB} instruction;
   \item A field that is used to specify the addressing mode for both destination register and the second source register. This field can assume one of the following values (defined in \texttt{axe\_constants.h}:
   \begin {itemize}
      \item \texttt{CG\_DIRECT\_ALL}
      \item \texttt{CG\_INDIRECT\_ALL}
      \item \texttt{CG\_INDIRECT\_DEST}
      \item \texttt{CG\_INDIRECT\_SOURCE}
   \end {itemize}
\end{itemize}

The value \texttt{CG\_DIRECT\_ALL} is used when both destination register and the second source register are directly addressed.
The value \texttt{CG\_INDIRECT\_ALL} is used when both destination register and source register are indirectly addressed.
The value \texttt{CG\_INDIRECT\_DEST} is used when the destination register is indirectly addressed.
The value \texttt{CG\_INDIRECT\_SOURCE} is used when the second source register is indirectly addressed.

If we want to store result of the ANDB instruction in a new register (i.e. a register that is unused), at first we must call the function \texttt{getNewRegister} declared in \texttt{axe\_engine.h}.
Once called, the function \texttt{getNewRegister} returns as output a new register identifier. At last, we are able to call the \texttt{gen\_andb\_instruction}.

However, according to the Bison grammar, the result must be stored in an instance of \texttt{t\_axe\_expression}. Thus, in our example we have to create an instance of \texttt{t\_axe\_expression} by calling the function \texttt{create\_expression} defined in \texttt{axe\_struct.h}.

Actually the function \texttt{perform\_bin\_numeric\_op} is used to perform all the operations discussed so far in this section.

The function \texttt{perform\_bin\_numeric\_op} takes as input the following parameters:
\begin{itemize}
   \item An instance of t\_program\_infos that contains all the information about the program being compiled;
   \item Two instances of \texttt{t\_axe\_expression} (one for each of the two operands);
   \item An operation identifier (for example: the macro \texttt{ANDB} defined in \texttt{axe\_constants.h} should be used as identifier for the previous example);
\end{itemize}

Valid binary operation identifiers are:
\begin{itemize}
   \item \texttt{ADD}
   \item \texttt{ANDB}
   \item \texttt{ORB}
   \item \texttt{SUB}
   \item \texttt{MUL}
   \item \texttt{DIV}
\end{itemize}

The function \texttt{perform\_binary\_comparison} can be used to implement the semantic action for the rule
\begin{tabular}{lp{0.6\textwidth}}
   \emph{\textbf{\texttt{\emph{exp}}}} : &$\mid$ \emph{exp} LT \emph{exp}  \\
\end{tabular}

The function \texttt{perform\_binary\_comparison} takes as input the following parameters:
\begin{itemize}
   \item An instance of t\_program\_infos that contains all the information about the program being compiled;
   \item Two instances of \texttt{t\_axe\_expression} (one for each of the two operands);
   \item A condition code (for example: the macro \texttt{\_LT\_} defined in \texttt{axe\_constants.h} should be used in this last example);
\end{itemize}

Valid condition codes are:
\begin{itemize}
   \item \texttt{\_LT\_} (i.e. ``less than zero '');
   \item \texttt{\_GT\_} (i.e. ``greater than zero '');
   \item \texttt{\_EQ\_} (i.e. ``equal to zero '');
   \item \texttt{\_NOTEQ\_} (i.e. ``not equal to zero'');
   \item \texttt{\_LTEQ\_} (i.e. ``less than or equal to zero'');
   \item \texttt{\_GTEQ\_} (i.e. ``greater than or equal to zero'').
\end{itemize}

Both the function \texttt{perform\_bin\_numeric\_op} and the function \texttt{perform\_binary\_comparison} return as output an instance of \texttt{t\_axe\_expression}.

\subsection{do-while statement}
A Bison semantic action for a \emph{do-while} statement can be formalized in the following manner:

\begin{verbatim}

do_while_statements  : DO
                     {
                        $1 = reserveLabel(program);
                        
                        fixLabel(program, $1);
                     }
                     code_block WHILE LPAR exp RPAR
                     {
                        gen_bne_instruction (program, $1, 0);
                     };
                     
\end{verbatim}

In order to implement a \emph{do-while} statement, we have to assign a label to the first instruction in the loop body.
That label will be used as a target for a conditional jump instruction. An expression is used to formalize the loop termination condition.
In the given example, if the outcome of \texttt{exp} is different from zero (i.e. the loop condition is verified), the control should jump back to the first instruction of the loop body (defined by using the non-terminal \texttt{code\_block}); otherwise the control get out from the loop.

We can use the function \texttt{reserveLabel} declared in \texttt{axe\_engine.h} to ask the Label Manager (associated with a specific instance of \texttt{t\_program\_infos}) for a new label identifier.
A label is an instances of \texttt{t\_axe\_label} (a structure declared in \texttt{axe\_stuct.h} which only field is an integer value).

The function \texttt{fixLabel} declared in \texttt{axe\_engine.h} takes as input an instance of \texttt{t\_program\_infos} and an instance of \texttt{t\_axe\_label} (the label that must be assigned to the following assembly statement).
We can use the \texttt{fixLabel} to assign a label to the first instruction of the loop body.

Note that both the function \texttt{reserveLabel} and the function \texttt{fixLabel} are defined as wrappers respectively for the \texttt{reserveLabelID} and \texttt{fixLabelID} (declared in \texttt{axe\_labels.h}).

Finally, we use a \texttt{gen\_bne\_instruction} to generate a conditional branch instruction to the first instruction of the loop body.
