|
@@ -121,6 +121,7 @@ t_io_infos *file_infos; /* input and output files used by the compiler */
|
|
|
%token RETURN
|
|
|
%token READ
|
|
|
%token WRITE
|
|
|
+%token PLUSINFTY MINUSINFTY UNDEF
|
|
|
|
|
|
%token <label> DO
|
|
|
%token <while_stmt> WHILE
|
|
@@ -190,11 +191,23 @@ var_declaration : TYPE declaration_list SEMI
|
|
|
declaration_list : declaration_list COMMA declaration
|
|
|
{ /* add the new declaration to the list of declarations */
|
|
|
$$ = addElement($1, $3, -1);
|
|
|
+ if (! $3->isArray) {
|
|
|
+ char *s = malloc(sizeof(char)*strlen($3->ID) + 3);
|
|
|
+ strcpy(s, $3->ID);
|
|
|
+ s = strcat(s, "_i");
|
|
|
+ $$ = addElement($$, alloc_declaration(s, 0, 0, 0), -1);
|
|
|
+ }
|
|
|
}
|
|
|
| declaration
|
|
|
{
|
|
|
/* add the new declaration to the list of declarations */
|
|
|
- $$ = addElement(NULL, $1, -1);
|
|
|
+ $$ = addElement(NULL, $1, -1);
|
|
|
+ if (! $1->isArray) {
|
|
|
+ char *s = malloc(sizeof(char)*strlen($1->ID) + 3);
|
|
|
+ strcpy(s, $1->ID);
|
|
|
+ s = strcat(s, "_i");
|
|
|
+ $$ = addElement($$, alloc_declaration(s, 0, 0, 0), -1);
|
|
|
+ }
|
|
|
}
|
|
|
;
|
|
|
|
|
@@ -275,7 +288,7 @@ assign_statement : IDENTIFIER LSQUARE exp RSQUARE ASSIGN exp
|
|
|
}
|
|
|
| IDENTIFIER ASSIGN exp
|
|
|
{
|
|
|
- int location;
|
|
|
+ int location, infty;
|
|
|
t_axe_instruction *instr;
|
|
|
|
|
|
/* in order to assign a value to a variable, we have to
|
|
@@ -291,13 +304,18 @@ assign_statement : IDENTIFIER LSQUARE exp RSQUARE ASSIGN exp
|
|
|
|
|
|
/* get the location of the symbol with the given ID. */
|
|
|
location = get_symbol_location(program, $1, 0);
|
|
|
+ infty = get_symbol_location(program, strcat($1, "_i"), 0);
|
|
|
|
|
|
/* update the value of location */
|
|
|
- if ($3.expression_type == IMMEDIATE)
|
|
|
+ if ($3.expression_type == IMMEDIATE) {
|
|
|
gen_move_immediate(program, location, $3.value);
|
|
|
+ gen_addi_instruction(program, infty, REG_0, $3.infty);
|
|
|
+ }
|
|
|
else
|
|
|
instr = gen_add_instruction
|
|
|
(program, location, REG_0, $3.value, CG_DIRECT_ALL);
|
|
|
+ gen_add_instruction(program, infty, REG_0, $3.infty,
|
|
|
+ CG_DIRECT_ALL);
|
|
|
|
|
|
/* free the memory associated with the IDENTIFIER */
|
|
|
free($1);
|
|
@@ -415,7 +433,7 @@ return_statement : RETURN
|
|
|
|
|
|
read_statement : READ LPAR IDENTIFIER RPAR
|
|
|
{
|
|
|
- int location;
|
|
|
+ int locationi, infty;
|
|
|
|
|
|
/* read from standard input an integer value and assign
|
|
|
* it to a variable associated with the given identifier */
|
|
@@ -424,9 +442,11 @@ read_statement : READ LPAR IDENTIFIER RPAR
|
|
|
/* lookup the symbol table and fetch the register location
|
|
|
* associated with the IDENTIFIER $3. */
|
|
|
location = get_symbol_location(program, $3, 0);
|
|
|
+ infty = get_symbol_location(program, strcat($3, "_i"), 0);
|
|
|
|
|
|
/* insert a read instruction */
|
|
|
gen_read_instruction (program, location);
|
|
|
+ gen_addi_instruction(program, infty, REG_0, 1)
|
|
|
|
|
|
/* free the memory associated with the IDENTIFIER */
|
|
|
free($3);
|
|
@@ -436,32 +456,40 @@ read_statement : READ LPAR IDENTIFIER RPAR
|
|
|
write_statement : WRITE LPAR exp RPAR
|
|
|
{
|
|
|
|
|
|
- int location;
|
|
|
+ int location, infty;
|
|
|
|
|
|
if ($3.expression_type == IMMEDIATE)
|
|
|
{
|
|
|
/* load `immediate' into a new register. Returns the new register
|
|
|
* identifier or REG_INVALID if an error occurs */
|
|
|
location = gen_load_immediate(program, $3.value);
|
|
|
+ infty = gen_load_immediate(program, $3.infty);
|
|
|
}
|
|
|
- else
|
|
|
+ else {
|
|
|
location = $3.value;
|
|
|
+ infty = $3.infty;
|
|
|
+ }
|
|
|
|
|
|
/* write to standard output an integer value */
|
|
|
gen_write_instruction (program, location);
|
|
|
+ gen_write_instruction (program, infty);
|
|
|
}
|
|
|
;
|
|
|
|
|
|
-exp: NUMBER { $$ = create_expression ($1, IMMEDIATE); }
|
|
|
+exp: NUMBER { $$ = create_expression ($1, 1, IMMEDIATE); }
|
|
|
+ | UNDEF { $$ = create_expression (0, 0, IMMEDIATE); }
|
|
|
+ | PLUSINFTY { $$ = create_expression (1, -1, IMMEDIATE); }
|
|
|
+ | MINUSINFTY { $$ = create_expression (2, -1, IMMEDIATE); }
|
|
|
| IDENTIFIER {
|
|
|
- int location;
|
|
|
+ int location, infty;
|
|
|
|
|
|
/* get the location of the symbol with the given ID */
|
|
|
location = get_symbol_location(program, $1, 0);
|
|
|
+ infty = get_symbol_location(program, strcat($1, "_i"), 0);
|
|
|
|
|
|
/* return the register location of IDENTIFIER as
|
|
|
* a value for `exp' */
|
|
|
- $$ = create_expression (location, REGISTER);
|
|
|
+ $$ = create_expression (location, infty, REGISTER);
|
|
|
|
|
|
/* free the memory associated with the IDENTIFIER */
|
|
|
free($1);
|
|
@@ -531,8 +559,33 @@ exp: NUMBER { $$ = create_expression ($1, IMMEDIATE); }
|
|
|
$$ = handle_binary_comparison (program, $1, $3, _GT_);
|
|
|
}
|
|
|
| exp EQ exp {
|
|
|
- $$ = handle_binary_comparison (program, $1, $3, _EQ_);
|
|
|
+` if (($1.expression_type == IMMEDIATE) &&
|
|
|
+ ($3.expression_type == IMMEDIATE)) {
|
|
|
+ int undef = ($1.infty * $3.infty != 0);
|
|
|
+ int value = (($1.infty + $3.infty) * ($1.value == $3.value)) != 0;
|
|
|
+ $$ = create_expression_inf(value, undef, IMMEDIATE);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ int temp_reg = getNewRegister(program);
|
|
|
+ int infty_reg = getNewRegister(program);
|
|
|
+ int value_reg = getNewRegister(program);
|
|
|
+
|
|
|
+ gen_mul_instruction(program, infty_reg, $1.infty, $3.infty,
|
|
|
+ CG_DIRECT_ALL);
|
|
|
+ gen_sne_instruction(program, infty_reg);
|
|
|
+ gen_eorl_instruction(program, value_reg, $1.infty, $3.infty,
|
|
|
+ CG_DIRECT_ALL);
|
|
|
+ gen_seq_instruction(program, value_reg);
|
|
|
+ gen_sub_instruction(program, temp_reg, $1.value, $3.value,
|
|
|
+ CG_DIRECT_ALL);
|
|
|
+ gen_seq_instruction(program, temp_reg);
|
|
|
+ gen_mul_instruction(program, value_reg, temp_reg, value_reg,
|
|
|
+ CG_DIRECT_ALL);
|
|
|
+ $$ = create_expression_inf(value_reg, infty_reg, REGISTER);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
| exp NOTEQ exp {
|
|
|
$$ = handle_binary_comparison (program, $1, $3, _NOTEQ_);
|
|
|
}
|