From a1c0f7a19fc9b9c53de69da47c15027fce4087e3 Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Tue, 6 Apr 2021 18:17:10 +0200 Subject: [PATCH] add if --- al.lex | 51 ++++++++++++++++++++++++++++++++++++++------ as.y | 53 ++++++++++++++++++++++++---------------------- asm_instructions.c | 4 ++++ asm_instructions.h | 3 +++ test.c | 5 +++++ yacc_util.c | 38 +++++++++++++++++++++++++++++---- yacc_util.h | 12 +++++++++++ 7 files changed, 130 insertions(+), 36 deletions(-) diff --git a/al.lex b/al.lex index 6ecdebb..f0ffd47 100644 --- a/al.lex +++ b/al.lex @@ -2,6 +2,7 @@ #include "asm_instructions.h" #include "symbol_table.h" #include "as.tab.h" +#include "yacc_util.h" %} D [0-9] @@ -36,13 +37,49 @@ D [0-9] "," { return tVIRG; } "{" { return tAO; } "}" { return tAF; } -"!" { return tNOT; } -"==" { return tEQ2; } -"!=" { return tNOTEQ; } -"<" { return tINF; } -"<=" { return tINFEQ; } -">" { return tSUP; } -">=" { return tSUPEQ; } +"==" { + struct Condition* c = malloc(sizeof(struct Condition)); + c->instruction = EQU; + c->not = 0; + yylval.condition = c; + return tEQ2; + } +"!=" { + struct Condition* c = malloc(sizeof(struct Condition)); + c->instruction = EQU; + c->not = 1; + yylval.condition = c; + return tNOTEQ; + } +"<" { + struct Condition* c = malloc(sizeof(struct Condition)); + c->instruction = INF; + c->not = 0; + yylval.condition = c; + return tINF; + } +"<=" { + struct Condition* c = malloc(sizeof(struct Condition)); + c->instruction = SUP; + c->not = 1; + yylval.condition = c; + return tINFEQ; + } +">" { + struct Condition* c = malloc(sizeof(struct Condition)); + c->instruction = SUP; + c->not = 0; + yylval.condition = c; + return tSUP; + } +">=" { + struct Condition* c = malloc(sizeof(struct Condition)); + c->instruction = INF; + c->not = 1; + yylval.condition = c; + return tSUPEQ; + } +"!" { return tNOT; } "&&" { return tAND; } "||" { return tOR; } [ \t\n]+ { } diff --git a/as.y b/as.y index 42dc931..5b20585 100644 --- a/as.y +++ b/as.y @@ -16,7 +16,9 @@ InstructionTable instruction_table; char* symbol_name; SymbolItem* symbol; int nombre; + int address; Instruction instruction; + struct Condition* condition; } %token tNB @@ -31,13 +33,13 @@ InstructionTable instruction_table; %token tAO %token tAF %token tEQ -%token tEQ2 -%token tNOTEQ +%token tEQ2 +%token tNOTEQ +%token tINF +%token tINFEQ +%token tSUP +%token tSUPEQ %token tNOT -%token tINF -%token tINFEQ -%token tSUP -%token tSUPEQ %token tAND %token tOR @@ -56,6 +58,8 @@ InstructionTable instruction_table; %left tMUL %left tDIV %type E +%type Cond +%type
IfSimple %% @@ -74,7 +78,7 @@ Body : tAO Instructions tAF { printf("Body\n"); } ; Instructions : Instruction Instructions | { printf("Instructions\n"); } ; -Instruction : Aff | Printf { printf("Instruction\n"); } ; +Instruction : Aff | Printf | If { printf("Instruction\n"); } ; Aff : tID tEQ E tPV { write_affectation(&symbol_table, &instruction_table, $1, $3); } ; @@ -97,30 +101,29 @@ DeclarationConst : tCONST { current_type = TYPE_CONST; } DeclarationBody tPV ; DeclarationBody : VariableIdentifier tVIRG DeclarationBody | VariableIdentifier ; -VariableIdentifier: tID { add_symbol(&symbol_table, current_type, $1); } +VariableIdentifier: tID { add_symbol(&symbol_table, current_type, $1); } ; // While : tWHILE tPO Cond tPF Body { printf("While\n"); } ; -// -// If : IfSimple | IfElse { printf("If\n"); } ; -// -// IfSimple : tIF tPO Cond tPF Body { printf("IfSimple\n"); } ; -// + +If : IfSimple { update_jmf(&instruction_table, $1); } ; + +IfSimple : tIF tPO Cond tPF { $
$ = write_jmf(&instruction_table, $3); } Body { $$ = $
5; }; + // IfElse : IfSimple tELSE Body { printf("IfElse\n"); } ; -// -// Cond : tNOT Cond | Cond tAND Cond | Cond tOR Cond | E tEQ2 E | E tINF E | E tINFEQ E | E tSUP E | E tSUPEQ E | E tNOTEQ E | tNOT tPO Cond tPF { printf("Cond\n"); } ; + +Cond : tNOT Cond { $$ = write_not_condition(&symbol_table, &instruction_table, $2); } +| Cond tAND Cond { $$ = write_op(&symbol_table, &instruction_table, MUL, $1, $3); } +| Cond tOR Cond { $$ = write_op(&symbol_table, &instruction_table, ADD, $1, $3); } +| E tEQ2 E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); } +| E tINF E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); } +| E tINFEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); } +| E tSUP E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); } +| E tSUPEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); } +| E tNOTEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); } +| tNOT tPO Cond tPF { $$ = write_not_condition(&symbol_table, &instruction_table, $3); } ; Printf : tPRINTF tPO E tPF tPV { write_print(&instruction_table, $3); } ; -// If : tIF tPO Cond tPF Body ; -// -// Cond : Cond tAND Cond | Cond tOR Cond | E tEQ2 E | E tINF E | tNOT Cond ; - -// Invocation : tID tPO Args tPF ; - -// Args : .... cf params - -// Return : tRET E tPV ; - %% #include diff --git a/asm_instructions.c b/asm_instructions.c index 8a44798..d92a236 100644 --- a/asm_instructions.c +++ b/asm_instructions.c @@ -48,4 +48,8 @@ void write_instruction(InstructionItem *item, FILE *file) { } else { fprintf(file, "%s %d %d %d\n", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3); } +} + +int get_current_address(struct InstructionTable *table) { + return table->index; } \ No newline at end of file diff --git a/asm_instructions.h b/asm_instructions.h index e095ecd..c09cf6d 100644 --- a/asm_instructions.h +++ b/asm_instructions.h @@ -2,6 +2,7 @@ #define COMPILATOR_2000_ASM_INSTRUCTIONS_H #include +#include "symbol_table.h" #define INSTRUCTION_TABLE_SIZE 100 @@ -43,4 +44,6 @@ void write_instruction_table(InstructionTable *table, FILE *file); void write_instruction(InstructionItem *item, FILE *file); +int get_current_address(InstructionTable *table); + #endif //COMPILATOR_2000_ASM_INSTRUCTIONS_H diff --git a/test.c b/test.c index c647b12..c8a936f 100644 --- a/test.c +++ b/test.c @@ -4,4 +4,9 @@ int main(){ x = 2; printf(x); y = 3 + 3 + x; + if (x == 2) { + printf(x); + printf(y); + } + x = 3; } diff --git a/yacc_util.c b/yacc_util.c index b7d3cbb..a2482a3 100644 --- a/yacc_util.c +++ b/yacc_util.c @@ -15,13 +15,11 @@ const SymbolItem* write_op(SymbolTable* symbol_table, InstructionTable *instruct const SymbolItem* write_negation(SymbolTable* symbol_table, InstructionTable *instruction_table, SymbolItem *op2) { // Create temp variable with 0 const SymbolItem* op1 = init_temp_symbol(symbol_table, instruction_table, 0); - const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT); // Make the 0 - variable operation - add_instruction(instruction_table, SOU, dest->address, op1->address, op2->address); - return dest; + add_instruction(instruction_table, SOU, op1->address, op1->address, op2->address); + return op1; } - const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *instruction_table, int constant) { const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT); add_instruction(instruction_table, AFC, dest->address, constant, 0); @@ -32,4 +30,36 @@ void write_print(InstructionTable *instruction_table, SymbolItem *src) { add_instruction(instruction_table, PRI, src->address, 0, 0); } +int update_jmf(InstructionTable *table, int address) { + if (address > table->index) { + return -1; + } + table->table[address].arg2 = get_current_address(table); + return 0; +} + +int write_jmf(InstructionTable *table, SymbolItem* cond) { + int addr = get_current_address(table); + add_instruction(table, JMF, cond->address, 0, 0); + return addr; +} + +const SymbolItem* write_not_condition(SymbolTable* symbol_table, InstructionTable *instruction_table, const SymbolItem* cond) { +// Create temp variable with 0 + const SymbolItem* op1 = init_temp_symbol(symbol_table, instruction_table, 0); +// Check if the condition is equal to 0 (makes the negation) + add_instruction(instruction_table, EQU, op1->address, op1->address, cond->address); + return op1; +} + +const SymbolItem* write_condition(SymbolTable* symbol_table, InstructionTable *instruction_table, Condition* op, SymbolItem* cond1, SymbolItem* cond2) { + const SymbolItem *dest = write_op(symbol_table, instruction_table, op->instruction, cond1, cond2); + if (op->not) { + return write_not_condition(symbol_table, instruction_table, dest); + } + return dest; +} + + + diff --git a/yacc_util.h b/yacc_util.h index 2c5277a..c7c539c 100644 --- a/yacc_util.h +++ b/yacc_util.h @@ -4,6 +4,10 @@ #ifndef COMPILATOR_2000_YACC_UTIL_H #define COMPILATOR_2000_YACC_UTIL_H +typedef struct Condition { + Instruction instruction; + int not; +} Condition; void write_affectation(SymbolTable* symbolTable, InstructionTable *instructionTable, char* symbol_dest, SymbolItem* src); @@ -15,4 +19,12 @@ const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable * void write_print(InstructionTable *instruction_table, SymbolItem *src); +int update_jmf(InstructionTable *table, int address); + +int write_jmf(InstructionTable *table, SymbolItem* cond); + +const SymbolItem* write_not_condition(SymbolTable* symbol_table, InstructionTable *table, const SymbolItem* cond); + +const SymbolItem* write_condition(SymbolTable* symbol_table, InstructionTable *table, Condition* op, SymbolItem* cond1, SymbolItem* cond2); + #endif //COMPILATOR_2000_YACC_UTIL_H