From 74e97fe96396d6c2e8c57a326239a7787fb6b139 Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Tue, 6 Apr 2021 16:19:44 +0200 Subject: [PATCH] implement arithmetic operations asm generation --- Makefile | 6 +++--- al.lex | 22 ++++++++++++++++++---- as.y | 34 +++++++++++++++++++++++++--------- asm_instructions.c | 17 ++++++++++++++++- asm_instructions.h | 17 ++--------------- symbol_table.c | 34 ++++++++++++++++++---------------- symbol_table.h | 16 ++++++++++++---- symbol_table.test.c | 25 ++++++++++--------------- test.c | 4 ++-- yacc_util.c | 30 ++++++++++++++++++++++++++++++ yacc_util.h | 16 ++++++++++++++++ 11 files changed, 152 insertions(+), 69 deletions(-) create mode 100644 yacc_util.c create mode 100644 yacc_util.h diff --git a/Makefile b/Makefile index 3082bcd..cd8f27a 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,10 @@ CC = gcc all: compilateur test test: symbol_table.test.c symbol_table.c symbol_table.h - $(CC) -o test symbol_table.test.c symbol_table.c + $(CC) -g -o test symbol_table.test.c symbol_table.c -compilateur: as.tab.c lex.yy.c symbol_table.c symbol_table.h asm_instructions.c asm_instructions.h - $(CC) -o compilateur as.tab.c lex.yy.c symbol_table.c asm_instructions.c +compilateur: as.tab.c lex.yy.c symbol_table.c symbol_table.h asm_instructions.c asm_instructions.h yacc_util.c yacc_util.h + $(CC) -o compilateur as.tab.c lex.yy.c symbol_table.c asm_instructions.c yacc_util.c as.tab.c: as.y $(YACC) as.y diff --git a/al.lex b/al.lex index db2fe35..6ecdebb 100644 --- a/al.lex +++ b/al.lex @@ -1,4 +1,6 @@ %{ +#include "asm_instructions.h" +#include "symbol_table.h" #include "as.tab.h" %} @@ -11,10 +13,22 @@ D [0-9] return tNB; } -"+" { return tADD; } -"-" { return tSUB; } -"*" { return tMUL; } -"/" { return tDIV; } +"+" { + yylval.instruction = ADD; + return tADD; + } +"-" { + yylval.instruction = SOU; + return tSUB; + } +"*" { + yylval.instruction = MUL; + return tMUL; + } +"/" { + yylval.instruction = DIV; + return tDIV; + } "=" { return tEQ; } "(" { return tPO; } ")" { return tPF; } diff --git a/as.y b/as.y index 7a1be23..89a3678 100644 --- a/as.y +++ b/as.y @@ -2,23 +2,28 @@ #include "stdio.h" #include "stdlib.h" #include "symbol_table.h" +#include "asm_instructions.h" +#include "yacc_util.h" enum Type current_type = TYPE_INT; SymbolTable symbol_table; +InstructionTable instruction_table; %} %union { char* symbol_name; + SymbolItem* symbol; int nombre; + Instruction instruction; } %token tNB -%token tADD -%token tSUB -%token tMUL -%token tDIV +%token tADD +%token tSUB +%token tMUL +%token tDIV %token tPO %token tPF %token tPV @@ -50,7 +55,7 @@ SymbolTable symbol_table; %left tSUB %left tMUL %left tDIV -// %type E +%type E %% @@ -71,13 +76,20 @@ Instructions : Instruction Instructions | { printf("Instructions\n"); } ; Instruction : Aff | Printf { printf("Instruction\n"); } ; -Aff : tID tEQ E tPV { mark_symbol_initialized(&symbol_table, $1); } ; +Aff : tID tEQ E tPV { write_affectation(&symbol_table, &instruction_table, $1, $3); } ; -E : tNB { printf("%d\n", $1); } | tID | E tADD E | E tMUL E | E tSUB E | E tDIV E | tPO E tPF | tSUB E ; +E : tNB { $$ = init_temp_symbol(&symbol_table, &instruction_table, $1); } + | tID { $$ = get_symbol_item(&symbol_table, $1); } + | E tADD E {$$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); } + | E tMUL E { $$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); } + | E tSUB E { $$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); } + | E tDIV E { $$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); } + | tPO E tPF { $$ = $2; } + | tSUB E { $$ = write_negation(&symbol_table, &instruction_table, $2); } ; -Declarations : | Declaration Declarations { printf("Declarations\n"); } ; +Declarations : | Declaration Declarations ; -Declaration : DeclarationInt | DeclarationConst { printf("Declaration\n"); } ; +Declaration : DeclarationInt | DeclarationConst ; DeclarationInt : tINT { current_type = TYPE_INT; } DeclarationBody tPV ; @@ -162,6 +174,7 @@ On suppose que E est tout le temps une vt, donc on génère tout le temps le mê void init() { init_table(&symbol_table); + init_instruction_table(&instruction_table); } void yyerror(char const* err) { @@ -173,4 +186,7 @@ void main(void) { init(); yyparse(); print_table(&symbol_table); + FILE *f = fopen("instruction_table.txt", "w+"); + write_instruction_table(&instruction_table, f); + fclose(f); } diff --git a/asm_instructions.c b/asm_instructions.c index b54e08f..c9b5af5 100644 --- a/asm_instructions.c +++ b/asm_instructions.c @@ -1,5 +1,20 @@ #include "asm_instructions.h" +char* instructions_labels[12] = { + "ADD", + "MUL", + "SOU", + "DIV", + "COP", + "AFC", + "JMP", + "JMF", + "INF", + "SUP", + "EQU", + "PRI" +}; + void init_instruction_table(InstructionTable *table) { table->index = 0; } @@ -26,5 +41,5 @@ void write_instruction_table(InstructionTable *table, FILE *file) { } void write_instruction(InstructionItem *item, FILE *file) { - fprintf(file, "%s %d %d %d", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3); + fprintf(file, "%s %d %d %d\n", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3); } \ No newline at end of file diff --git a/asm_instructions.h b/asm_instructions.h index f82d4f5..e095ecd 100644 --- a/asm_instructions.h +++ b/asm_instructions.h @@ -8,7 +8,7 @@ typedef enum Instruction { ADD, MUL, - SUO, + SOU, DIV, COP, AFC, @@ -20,20 +20,7 @@ typedef enum Instruction { PRI } Instruction; -char* instructions_labels[12] = { - "ADD", - "MUL", - "SUO", - "DIV", - "COP", - "AFC", - "JMP", - "JMF", - "INF", - "SUP", - "EQU", - "PRI" -}; +char* instructions_labels[12]; typedef struct InstructionItem { diff --git a/symbol_table.c b/symbol_table.c index 5f8d4ab..b1d2d9f 100644 --- a/symbol_table.c +++ b/symbol_table.c @@ -8,6 +8,13 @@ void init_table(SymbolTable *table) { table->temp_index = SYMBOL_TABLE_SIZE - 1; } +void init_symbol_item(SymbolItem *symbol_item, size_t name_size) { + symbol_item->type = 0; + symbol_item->name = malloc(name_size); + symbol_item->address = 0; + symbol_item->init = 0; +} + int has_symbol(SymbolTable* table, char *name) { for (int i = 0; i < table->index; i++) { if (strcmp(table->table[i].name, name) == 0) { @@ -30,6 +37,7 @@ int add_symbol(SymbolTable *table, enum Type type, char *name) { return -1; } SymbolItem newItem; + init_symbol_item(&newItem, strlen(name)); newItem.type = type; newItem.name = name; newItem.address = table->index; @@ -40,26 +48,20 @@ int add_symbol(SymbolTable *table, enum Type type, char *name) { return 0; } -int add_temp_symbol(SymbolTable* table, enum Type type, char *name) { +const SymbolItem* add_temp_symbol(SymbolTable* table, enum Type type) { if (table->temp_index < table->index) { - return -2; - } - if (has_symbol(table, name)) { - return -1; - } - if (name[0] != '_') { - return -3; + return NULL; } - SymbolItem newItem; - newItem.type = type; - newItem.name = name; - newItem.address = table->temp_index; - newItem.init = 0; + SymbolItem *newItem = &table->table[table->temp_index]; + init_symbol_item(newItem, 10); + newItem->type = type; + sprintf(newItem->name, "_temp%d", table->temp_index); + newItem->address = table->temp_index; + newItem->init = 0; - table->table[table->temp_index] = newItem; table->temp_index--; - return 0; + return newItem; } int mark_symbol_initialized(SymbolTable *table, char *name) { @@ -107,7 +109,7 @@ void print_item(struct SymbolItem *item) { } } -SymbolItem *get_symbol_item(SymbolTable *table, char *name) { +SymbolItem *get_symbol_item(SymbolTable *table, const char *name) { for (int i = 0; i < table->index; i++) { if (strcmp(table->table[i].name, name) == 0) { return &table->table[i]; diff --git a/symbol_table.h b/symbol_table.h index 342ffa4..ef908df 100644 --- a/symbol_table.h +++ b/symbol_table.h @@ -1,6 +1,8 @@ #ifndef SYMBOL_TABLE_H_INCLUDED #define SYMBOL_TABLE_H_INCLUDED +#include + #define SYMBOL_TABLE_SIZE 100 enum Type { @@ -31,6 +33,13 @@ typedef struct SymbolTable { */ void init_table(SymbolTable *table); +/** + * Initializes the symbol + * + * @param table + */ +void init_symbol_item(SymbolItem *symbol_item, size_t name_size); + /** * Checks if the given symbol is in the table * @@ -57,10 +66,9 @@ int add_symbol(SymbolTable* table, enum Type type, char *name); * @param table * @param type * @param name - * @return 0 on success, -1 if the symbol already exists, -2 if the table is full - * -3 if the name doesn't start by _ + * @return 0 on success, -1 if the table is full */ -int add_temp_symbol(SymbolTable* table, enum Type type, char *name); +const SymbolItem* add_temp_symbol(SymbolTable* table, enum Type type); /** * Marks the given symbol as initialized @@ -100,6 +108,6 @@ char* type_to_string(enum Type type); * @param name * @return the item if found, NULL otherwise */ -SymbolItem *get_symbol_item(SymbolTable* table, char *name); +SymbolItem *get_symbol_item(SymbolTable* table, const char *name); #endif /* !SYMBOL_TABLE_H_INCLUDED */ diff --git a/symbol_table.test.c b/symbol_table.test.c index 4f60b57..743f4da 100644 --- a/symbol_table.test.c +++ b/symbol_table.test.c @@ -1,6 +1,7 @@ #include "symbol_table.h" #include #include +#include int main() { int err; @@ -33,23 +34,17 @@ int main() { printf("Mark b initialized\n"); assert(err == -1); - err = add_temp_symbol(&table, TYPE_INT, "_temp1"); - printf("Add _temp1 temporary variable\n"); - assert(err == 0); - err = add_temp_symbol(&table, TYPE_INT, "_temp2"); - printf("Add _temp2 temporary variable\n"); - assert(err == 0); - err = add_temp_symbol(&table, TYPE_INT, "_temp1"); - printf("Add _temp1 temporary variable\n"); - assert(err == -1); - err = add_temp_symbol(&table, TYPE_INT, "temp1"); - printf("Add temp1 temporary variable\n"); - assert(err == -3); + const SymbolItem* var1 = add_temp_symbol(&table, TYPE_INT); + printf("Add _temp99 temporary variable\n"); + assert(strcmp(var1->name, "_temp99") == 0); + const SymbolItem* var2 = add_temp_symbol(&table, TYPE_INT); + printf("Add _temp98 temporary variable\n"); + assert(strcmp(var2->name, "_temp98") == 0); - item = get_symbol_item(&table, "_temp1"); - printf("_temp1:\n"); + item = get_symbol_item(&table, "_temp98"); + printf("_temp98:\n"); print_item(item); - item = get_symbol_item(&table, "_temp5"); + item = get_symbol_item(&table, "_temp0"); printf("_temp5:\n"); print_item(item); diff --git a/test.c b/test.c index eb3c602..78697ad 100644 --- a/test.c +++ b/test.c @@ -2,6 +2,6 @@ int main(){ int x, y, z; const PL5_op, b, c; printf(x); - x = 3 + 2; - y = 3; + x = 2; + y = 3 + 3 + x; } diff --git a/yacc_util.c b/yacc_util.c new file mode 100644 index 0000000..12d4572 --- /dev/null +++ b/yacc_util.c @@ -0,0 +1,30 @@ +#include "yacc_util.h" + +void write_affectation(SymbolTable* symbol_table, InstructionTable *instruction_table, char* symbol_dest, SymbolItem* src) { + mark_symbol_initialized(symbol_table, symbol_dest); + SymbolItem *dest = get_symbol_item(symbol_table, symbol_dest); + add_instruction(instruction_table, COP, src->address, dest->address, 0); +} + +const SymbolItem* write_op(SymbolTable* symbol_table, InstructionTable *instruction_table, Instruction instruction, SymbolItem *op1, SymbolItem *op2) { + const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT); + add_instruction(instruction_table, instruction, dest->address, op1->address, op2->address); + return dest; +} + +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; +} + + +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); + return dest; +} + diff --git a/yacc_util.h b/yacc_util.h new file mode 100644 index 0000000..0fd1058 --- /dev/null +++ b/yacc_util.h @@ -0,0 +1,16 @@ +#include "symbol_table.h" +#include "asm_instructions.h" + +#ifndef COMPILATOR_2000_YACC_UTIL_H +#define COMPILATOR_2000_YACC_UTIL_H + + +void write_affectation(SymbolTable* symbolTable, InstructionTable *instructionTable, char* symbol_dest, SymbolItem* src); + +const SymbolItem* write_op(SymbolTable* symbol_table, InstructionTable *instruction_table, Instruction instruction, SymbolItem *op1, SymbolItem *op2); + +const SymbolItem* write_negation(SymbolTable* symbol_table, InstructionTable *instruction_table, SymbolItem *op2); + +const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *instruction_table, int constant); + +#endif //COMPILATOR_2000_YACC_UTIL_H