diff --git a/Makefile b/compiler/Makefile similarity index 82% rename from Makefile rename to compiler/Makefile index b9fae54..0960ff6 100644 --- a/Makefile +++ b/compiler/Makefile @@ -6,7 +6,7 @@ compiler: analyse_lexicale.lex analyse_syntaxique.y table_symboles.c table_fonct gcc -w *.c -ly -o compiler run: compiler - ./compiler < test_file + ./compiler < code_c clean: rm -f lex.yy.c compiler analyse_syntaxique.output analyse_syntaxique.tab.c analyse_syntaxique.tab.h \ No newline at end of file diff --git a/compiler/analyse_lexicale.lex b/compiler/analyse_lexicale.lex new file mode 100644 index 0000000..b8d5686 --- /dev/null +++ b/compiler/analyse_lexicale.lex @@ -0,0 +1,106 @@ +%{ +#include "analyse_syntaxique.tab.h" +int yywrap(void){ + return 1; +} + +%} + + + + +ADD "+" +SUB "-" +MUL "*" +DIV "/" +tPO "(" +tPF ")" +tAO "{" +tAF "}" +EOL "\n" +EOI ";" +SPACE " " +TAB "\t" +VIRGULE "," +AFFECTATION "=" +EQUAL "==" +LT "<" +GT ">" +LTE "<=" +GTE ">=" +tINT "int" +tMAIN "main" +tPRINT "printf" +tRETURN "return" +tIF "if" +tELSE "else" +tWHILE "while" +tNOT "!" +tAND "&&" +tOR "||" +tDIFF "!=" +tAPPERSAND "&" +DIGIT [0-9] +VARIABLE [A-Za-z0-9_]+ +CONST "const" +DECIMAL {DIGIT}+ +EXPONENTIEL {DIGIT}+"e"{DIGIT}+ +ENTIER {DECIMAL} +ENTIEREXP {EXPONENTIEL} +OPERATION {ADD}|{SUB}|{MUL}|{DIV} +COMPARATEUR {EGAL}|{LT}|{GT} +SEPARATOR {SPACE}|{TAB} + +%% + +{ADD} {return tADD ;} +{SUB} {return tSUB ;} +{MUL} {return tMUL ;} +{DIV} {return tDIV ;} + +{tPO} {return tPO ;} +{tPF} {return tPF ;} +{tAO} {return tAO ;} +{tAF} {return tAF ;} + +{EOI} {return tPV ;} +{SEPARATOR} {} +{EOL} {} +{VIRGULE} {return tVIRGULE ;} + +{AFFECTATION} {return tAFFECTATION ;} + +{EQUAL} {return tEGAL ;} +{tDIFF} {return tDIFF ;} +{LT} {return tLT ;} +{GT} {return tGT ;} +{LTE} {return tLTE ;} +{GTE} {return tGTE ;} +{tNOT} {return tNOT ;} + + +{tMAIN} {return tMAIN ;} +{tINT} {return tINT ;} +{tPRINT} {return tPRINT ;} +{tRETURN} {return tRETURN ;} + +{tOR} {return tOR ;} +{tAND} {return tAND ;} + +{tIF} {return tIF ;} +{tELSE} {return tELSE ;} +{tWHILE} {return tWHILE ;} + +{tAPPERSAND} {return tAPPERSAND;} +{CONST} {return tCONST ;} +{ENTIER} {yylval.nombre = atoi(yytext); return tENTIER ;} +{ENTIEREXP} {yylval.nombre = -1; return tENTIEREXP;} +{VARIABLE} {strcpy(yylval.id, yytext); return tVAR ;} + +%% + +//int main(void){ +// yylex(); +//} + + diff --git a/compiler/analyse_syntaxique.y b/compiler/analyse_syntaxique.y new file mode 100644 index 0000000..4660fcb --- /dev/null +++ b/compiler/analyse_syntaxique.y @@ -0,0 +1,230 @@ +%union { +int nombre; +char id[30]; +} + +%{ +#include +#include "table_symboles.h" +#include "table_fonctions.h" +#include "gen_assembleur.h" + +enum Initialised_Variable init; +enum Symbole_Type type; +enum Return_Type return_type; +Table_Symboles table; +Table_Fonctions table_fonctions; +instructions_array array; +int whileCondition; +int return_value; +%} + + +%token tENTIER +%token tENTIEREXP + +%type E +%type Return Instructions +%type Cond +%type While Else Invocation + + +%token tADD +%token tSUB +%token tMUL +%token tDIV + +%token tPO +%token tPF +%token tAO +%token tAF + +%token tERROR + +%token tAPPERSAND +%token tPV +%token tVIRGULE +%token tAFFECTATION +%token tEGAL +%token tDIFF +%token tLT +%token tGT +%token tGTE +%token tLTE +%token tMAIN +%token tINT +%token tPRINT +%token tRETURN +%token tOR +%token tAND +%token tIF +%token tELSE +%token tWHILE +%token tCONST +%token tVAR +%token tNOT + +%left tADD +%left tSUB +%left tMUL +%left tDIV +%right tEGAL + + +%% + +/*C : Fonctions Main ; + +Fonctions : ; +Fonctions : Fonction Fonctions ; + +Fonction : tINT tVAR tPO Params tPF Body;*/ + +C : {generate_instruction_1(&array, JMP, -1);} Fonctions; + +Fonctions: Main; +Fonctions: Fonction Fonctions; + + +Main : tINT tMAIN {update_jmp(&array, 0, array.index); add_function(&table_fonctions, "Main", RET_INT, array.index); table.depth++;} tPO Params tPF Body {print_table(&table);remove_symboles(&table); table.depth--;}; +Fonction : Function_type tVAR {{add_function(&table_fonctions, $2, return_type, array.index); table.depth++;}} tPO Params tPF Body {print_table(&table);remove_symboles(&table); table.depth--;}; + +Function_type: tINT {type = TYPE_INT;} ; +Function_type: tINT tMUL {type = TYPE_INT_PTR;}; + +Params : {} ; +Params : Param SuiteParams ; + +Param : Param_type tVAR {add_symbole_top(&table, $2, type, INITIALISED, table.depth);} ; + +Param_type: tINT {type = TYPE_INT;} ; +Param_type: tINT tMUL {type = TYPE_INT_PTR;}; + +SuiteParams : tVIRGULE Param SuiteParams ; +SuiteParams : ; + + +Body : tAO Instructions Return tAF {} ; + +Instructions : Instruction Instructions {$$ = array.index;}; +Instructions : {$$ = array.index;}; + +Instruction : Aff ; +Instruction : If ; +Instruction : While ; +Instruction : Print ; +Instruction : Decl ; +Instruction : Invocation tPV ; + +Decl : Type Valeur SuiteDecl tPV ; + +SuiteDecl: tVIRGULE Valeur SuiteDecl ; +SuiteDecl: ; + +Type : tINT {type = TYPE_INT;} ; +Type : tCONST tINT {type = TYPE_CONST_INT;} ; +Type : tINT tMUL {type = TYPE_INT_PTR;}; + +Valeur : tVAR {add_symbole_top(&table, $1, type, INITIALISED, table.depth);} tAFFECTATION E {int varAddr = variable_exists(&table, $1); generate_instruction_2(&array, COP, varAddr, $4); free_temp(&table);}; +Valeur : tVAR {add_symbole_top(&table, $1, type, NOT_INITIALISED, table.depth);}; + + +Aff : tVAR tAFFECTATION E tPV {int varAddr = variable_exists(&table, $1); generate_instruction_2(&array, COP, varAddr, $3); free_temp(&table); }; +Aff : tMUL tVAR tAFFECTATION E tPV {int varAddr = variable_exists(&table, $2); generate_instruction_2(&array, COP_STR, varAddr, $4); free_temp(&table); }; + + +E : tENTIER {int vt = new_temp(&table); generate_instruction_2(&array, AFC, vt, $1); $$ = vt;}; +E : tVAR {int vt = new_temp(&table); int varAddr = variable_exists(&table, $1); generate_instruction_2(&array, COP, vt, varAddr); $$ = vt;}; +E : E tADD E {generate_instruction_3(&array, ADD, $1, $1, $3); free_temp(&table); $$ = $1;} ; +E : E tMUL E {generate_instruction_3(&array, MUL, $1, $1, $3); free_temp(&table); $$ = $1;} ; +E : E tSUB E {generate_instruction_3(&array, SOU, $1, $1, $3); free_temp(&table); $$ = $1;} ; +E : E tDIV E {generate_instruction_3(&array, DIV, $1, $1, $3); free_temp(&table); $$ = $1;} ; +E : tSUB E {printf("Variable negative\n");} ; +E : Invocation { + //int vt = new_temp(&table); + //generate_instruction_2(&array, COP, vt, $1); + remove_symboles(&table); + table.depth--; + $$ = $1;}; +E : tPO E tPF {printf("Parenthèse\n"); $$ = $2; } ; +E : tAPPERSAND tVAR {int vt = new_temp(&table); int varAddr = variable_exists(&table, $2); generate_instruction_2(&array, LEA, vt, varAddr); $$ = vt;}; +E : tMUL tVAR {int vt = new_temp(&table); int varAddr = variable_exists(&table, $2); generate_instruction_2(&array, COP, vt, varAddr); generate_instruction_2(&array, COP_LD, vt, vt); $$ = vt;}; + + +If : tIF tPO Cond tPF { + //gen_jmpf(&table, &array, $3, -1); + generate_instruction_2(&array, JMF, $3, -1); + free_temp(&table); + $1 = array.index; +} +tAO {table.depth++;} Instructions {generate_instruction_1(&array, JMP, -1);} tAF {remove_symboles(&table); table.depth--;} +{ + int adr_jmp = array.index; + update_jmf(&array, $1, adr_jmp); +} +Else {printf("updating jump\n"); update_jmp(&array, $8, $13);}; + +Else : tELSE tAO {table.depth++;} Instructions tAF {remove_symboles(&table); table.depth--;} {$$ = array.index;} ; +Else : {$$ = array.index;}; +Else : tELSE If {$$ = array.index;} ; + +While : tWHILE tPO { + $2 = array.index ; +} Cond tPF { + //gen_jmpf(&table, &array, $4, -1); + generate_instruction_2(&array, JMF, $4, -1); + free_temp(&table); + $1 = array.index; +} +tAO {table.depth++;} Instructions tAF {remove_symboles(&table); table.depth--;} { + int adr_jmp = array.index; + update_jmf(&array, $1, adr_jmp); + //gen_jmpf(&table, &array, $1, $2); + generate_instruction_1(&array, JMP, $2); +}; + +Cond : E tEGAL E {generate_instruction_3(&array, EQ, $1, $1, $3); free_temp(&table); $$ = $3;}; +Cond : E tDIFF E {generate_instruction_3(&array, NEQ, $1, $1, $3); free_temp(&table); $$ = $3;} ; +Cond : E tLT E {generate_instruction_3(&array, LT, $1, $1, $3); free_temp(&table); $$ = $3;} ; +Cond : E tGT E {generate_instruction_3(&array, GT, $1, $1, $3); free_temp(&table); $$ = $3;} ; +Cond : E tLTE E {generate_instruction_3(&array, LTE, $1, $1, $3); free_temp(&table); $$ = $3;} ; +Cond : E tGTE E {generate_instruction_3(&array, GTE, $1, $1, $3); free_temp(&table); $$ = $3;} ; +Cond : E tAND E {generate_instruction_3(&array, AND, $1, $1, $3); free_temp(&table); $$ = $3;} ; +Cond : E tOR E {generate_instruction_3(&array, OR, $1, $1, $3); free_temp(&table); $$ = $3;} ; +Cond : tNOT Cond {generate_instruction_2(&array, NOT, $2, $2); $$ = $2;} ; +Cond : E {$$ = $1; }; + +Invocation : tVAR tPO {table.depth++; prepare_function_call(&table); return_value = (table.indexAvailableBottom);} Args tPF + {int function_index = function_exists(&table_fonctions, $1); + int jmp_addr = (table_fonctions.array[function_index]).start_addr; + generate_instruction_2(&array, CALL, jmp_addr, table.indexAvailableTop); + $$ = return_value; + }; + +Args : Arg SuiteArgs ; +Args : +Arg : E {int arg_addr = prepare_argument_push(&table); generate_instruction_2(&array, COP, arg_addr, $1); free_temp(&table);}; +SuiteArgs : tVIRGULE Arg SuiteArgs ; +SuiteArgs : ; + +Print : tPRINT tPO E tPF tPV {generate_instruction_1(&array, PRI, $3); free_temp(&table);}; + +Return : tRETURN E tPV {$$ = generate_instruction_1(&array, RET, $2); free_temp(&table);}; + +%% +#include +void main(void){ + //TODO: rajouter gestion des erreurs + initialise_table(&table); + initialise_function_table(&table_fonctions); + initialise_asm(&array); + yyparse(); + print_table(&table); + printf("\n"); + print_fonction_table(&table_fonctions); + + //remove_symboles(&table, 0); + //print_table(&table); + exportInstructions(&array); +} + diff --git a/compiler/code_c b/compiler/code_c new file mode 100644 index 0000000..f0dfdca --- /dev/null +++ b/compiler/code_c @@ -0,0 +1,16 @@ +int fonction1(int * a){ + int b = *a; + printf(b); + return 1; + } + +int main(){ + int l = 21; + int * p = &l; + int c = fonction1(p); + printf(c); + p = &c; + *p = 2; + printf(c); + + return 0; \ No newline at end of file diff --git a/compiler/gen_assembleur.c b/compiler/gen_assembleur.c new file mode 100644 index 0000000..9e14992 --- /dev/null +++ b/compiler/gen_assembleur.c @@ -0,0 +1,357 @@ +#include "gen_assembleur.h" +#include +#include + +char * operationName(enum operation op){ + switch(op){ + case EQ: + return "EQ"; + case NEQ: + return "NEQ"; + case LT: + return "LT"; + case GT: + return "GT"; + case LTE: + return "LTE"; + case GTE: + return "GTE"; + case ADD: + return "ADD"; + case SOU: + return "SOU"; + case DIV: + return "DIV"; + case MUL: + return "MUL"; + case COP: + return "COP"; + case AFC: + return "AFC"; + case RET: + return "RET"; + case JMF: + return "JPF"; + case JMP: + return "JMP"; + case AND: + return "AND"; + case OR: + return "OR"; + case NOT: + return "NOT"; + case PRI: + return "PRI"; + case LEA: + return "LEA"; + case COP_LD: + return "COP_LD"; + case COP_STR: + return "COP_STR"; + case RET_FUN: + return "RET_FUN"; + case CALL: + return "CALL"; + default: + break; + } + return ""; +} + +void initialise_asm(instructions_array * array){ + array->index = 0; +} + +int add_instruction(instructions_array * array, instruction * instru){ + if (array->index >= INSTRUCTION_TABLE_SIZE){ + return 1; + } + array->array[array->index] = *instru; + array->index++; + + return 0; +} + +int new_temp(Table_Symboles * table){ + int ret_addr ; + if(add_symbole_bottom(table) == -1) { + return -1; + } + ret_addr = table->indexAvailableBottom + 1; + return ret_addr; +} + +int generate_instruction_0(instructions_array * array, enum operation op){ + instruction instru; + char * opName = operationName(op); + + instru.operation = op; + + printf("%d\t %s\n", array->index, opName); + + if (add_instruction(array, &instru) != 0){ + //TODO: Error handling + exit(1); + } + + return 0; +} + +int generate_instruction_1(instructions_array * array, enum operation op, int arg1){ + instruction instru; + char * opName = operationName(op); + + instru.operation = op; + instru.reg1 = arg1; + + printf("%d\t %s %d\n", array->index, opName, instru.reg1); + + if (add_instruction(array, &instru) != 0){ + //TODO: Error handling + exit(1); + } + + return 0; +} + +int generate_instruction_2(instructions_array * array, enum operation op, int arg1, int arg2){ + instruction instru; + char * opName = operationName(op); + + instru.operation = op; + instru.reg1 = arg1; + instru.reg2 = arg2; + + printf("%d\t %s %d %d\n", array->index, opName, instru.reg1, instru.reg2); + + if (add_instruction(array, &instru) != 0){ + //TODO: Error handling + exit(1); + } + + return 0; +} + +int generate_instruction_3(instructions_array * array, enum operation op, int arg1, int arg2, int arg3){ + instruction instru; + char * opName = operationName(op); + + instru.operation = op; + instru.reg1 = arg1; + instru.reg2 = arg2; + instru.reg3 = arg3; + + printf("%d\t %s %d %d %d\n", array->index, opName, instru.reg1, instru.reg2, instru.reg3); + + if (add_instruction(array, &instru) != 0){ + //TODO: Error handling + exit(1); + } + + return 0; +} + +void update_jmf(instructions_array * array, int instru_index, int adr_jmp){ + array->array[instru_index - 1].reg2 = adr_jmp; + printf("%d\t JMP %d %d\n", (instru_index - 1), array->array[instru_index].reg1, array->array[instru_index].reg2); +} + +void update_jmp(instructions_array * array, int instru_index, int adr_jmp){ + array->array[instru_index].reg1 = adr_jmp; + printf("%d\t JMP %d\n", (instru_index - 1), array->array[instru_index].reg1); +} + +void exportInstructions(instructions_array * array){ + FILE *file; + file = fopen("memory_oriented_assembly.txt", "w"); + instruction instru; + enum operation op; + + for (int i = 0; i < array->index; i++){ + instru = array->array[i]; + op = instru.operation; + switch (op) { + //0 parameters + case RET_FUN: + fprintf(file, "%s\n", operationName(op)); + break; + //1 parameter + case JMP: + case PRI: + case RET: + fprintf(file, "%s %d\n", operationName(op), instru.reg1); + break; + //2 parameters + case JMF: + case NOT: + case AFC: + case COP: + case LEA: + case CALL: + fprintf(file, "%s %d %d\n", operationName(op), instru.reg1, instru.reg2); + break; + case COP_LD: + fprintf(file, "%s %d [%d]\n", operationName(op), instru.reg1, instru.reg2); + break; + case COP_STR: + fprintf(file, "%s [%d] %d\n", operationName(op), instru.reg1, instru.reg2); + break; + //3 parameters + case ADD: + case SOU: + case DIV: + case MUL: + case AND: + case OR: + case EQ: + case NEQ: + case LT: + case LTE: + case GT: + case GTE: + fprintf(file, "%s %d %d %d\n", operationName(op), instru.reg1, instru.reg2, instru.reg3); + break; + default: + break; + } + } + + fclose(file); +} + +/*int gen_print(Table_Symboles * table, instructions_array * array, int arg1){ + instruction instru; + instru.operation = PRI; + instru.reg1 = arg1; + + printf("%d\t PRI %d\n", array->index, instru.reg1); + + if (array->index < INSTRUCTION_TABLE_SIZE){ + array->array[array->index] = instru; + array->index++; + } + + free_temp(table); +}*/ + +/*void gen_arithmetique(instructions_array * array, enum operation op, int arg1, int arg2){ + instruction instru; + instru.reg1 = arg1; + instru.reg2 = arg1; + instru.reg3 = arg2; + + char * opName = operationName(op); + printf("%d\t %s %d %d %d\n", array->index, opName, arg1, arg1, arg2); + + if (array->index < INSTRUCTION_TABLE_SIZE){ + array->array[array->index] = instru; + array->index++; + } + +} + +int gen_var(Table_Symboles * table, instructions_array * array, char * varName){ + int vt = new_temp(table); + int varAddr = variable_exists(table, varName); + + //vérifier que non null + instruction instru; + instru.operation = COP; + instru.reg1 = vt; + instru.reg2 = varAddr; + + printf("%d\t COP %d %d\n", array->index, vt, varAddr); + + if (array->index < INSTRUCTION_TABLE_SIZE){ + array->array[array->index] = instru; + array->index++; + } + + return vt; + +} + +int gen_entier(Table_Symboles * table, instructions_array * array, int entier){ + int vt = new_temp(table); + + //vérifier que non null + instruction instru; + instru.operation = AFC; + instru.reg1 = vt; + instru.reg2 = entier; + + printf("%d\t AFC %d %d\n", array->index, vt, entier); + + if (array->index < INSTRUCTION_TABLE_SIZE){ + array->array[array->index] = instru; + array->index++; + } + + return vt; +} + +int gen_condition(Table_Symboles * table, instructions_array * array, enum operation op, int arg1, int arg2){ + + char * opName = operationName(op); + + instruction instru; + instru.operation = op; + instru.reg1 = arg1; + instru.reg2 = arg1; + if (op != NOT){ + instru.reg3 = arg2; + printf("%d\t %s %d %d %d\n", array->index, opName, instru.reg1, instru.reg2, instru.reg3); + free_temp(table); + } else { + printf("%d\t %s %d %d \n", array->index, opName, instru.reg1, instru.reg2); + } + + if (array->index < INSTRUCTION_TABLE_SIZE){ + array->array[array->index] = instru; + array->index++; + } + + return instru.reg1; +} + +int gen_return(Table_Symboles * table, instructions_array * array, int adr){ + + //vérifier que non null + instruction instru; + instru.operation = RET; + instru.reg1 = adr; + + printf("%d\t RET %d\n", array->index, adr); + + if (array->index < INSTRUCTION_TABLE_SIZE){ + array->array[array->index] = instru; + array->index++; + } + + //free_temp(table); + + return adr; +} + +int gen_jmpf(Table_Symboles * table, instructions_array * array, int cond, int dest){ + //vérifier que non null + instruction instru; + instru.operation = JMF; + instru.reg1 = cond; + instru.reg2 = dest; + + printf("%d\t JMPF %d %d\n", array->index, instru.reg1 , instru.reg2); + + if (array->index < INSTRUCTION_TABLE_SIZE){ + array->array[array->index] = instru; + array->index++; + } + + //free_temp(table); + + return cond; +} + + */ + + diff --git a/compiler/gen_assembleur.h b/compiler/gen_assembleur.h new file mode 100644 index 0000000..8028c89 --- /dev/null +++ b/compiler/gen_assembleur.h @@ -0,0 +1,121 @@ +#ifndef GEN_ASSEMBLEUR_H +#define GEN_ASSEMBLEUR_H + +#define INSTRUCTION_TABLE_SIZE 1000 + +#include "table_symboles.h" + +enum operation{ADD, SOU, MUL, DIV, COP, AFC, RET, JMF, JMP, EQ, NEQ, LT, GT, LTE, + GTE, AND, OR, NOT, PRI, LEA, COP_LD, COP_STR, CALL, RET_FUN}; + +typedef struct instruction{ + enum operation operation; + int reg1; + int reg2; + int reg3; +}instruction; + +//table des instructions +typedef struct instructions_array{ + instruction array[INSTRUCTION_TABLE_SIZE]; + int index; +} instructions_array; + +/** + * + * @param op operation + * @return returns the string that corresponds to the enum operation op + */ +char * operationName(enum operation op); + +/** + * Initialises the instructions array + * @param array + */ +void initialise_asm(instructions_array * array); + +//renvoie l'index (ou valeur?) de la premiere @ dispo +/** + * Fetch address of a temporary variable + * @param table + * @return first available temp address + */ +int new_temp(Table_Symboles * table); + +/** + * Adds intruction to instruction array + * @param array + * @param intru + * @return 0 if instruction was added successfully, -1 if not + */ +int add_instruction(instructions_array * array, instruction * intru); + +/** + * Generates intruction with no parameter + * @param array + * @param op + * @return + */ +int generate_instruction_0(instructions_array * array, enum operation op); + +/** + * Generates intruction with one parameter + * @param array + * @param op + * @param arg1 + * @return + */ +int generate_instruction_1(instructions_array * array, enum operation op, int arg1); + +/** + * Generates intruction with two parameters + * @param array + * @param op + * @param arg1 + * @param arg2 + * @return + */ +int generate_instruction_2(instructions_array * array, enum operation op, int arg1, int arg2); + +/** + * Generates intruction with three parameters + * @param array + * @param op + * @param arg1 + * @param arg2 + * @param arg3 + * @return + */ +int generate_instruction_3(instructions_array * array, enum operation op, int arg1, int arg2, int arg3); + +/** + * Updates the JMF instruction with the correct jump destination address + * @param array + * @param instru_index + * @param adr_jmp + */ +void update_jmf(instructions_array * array, int instru_index, int adr_jmp); + +void update_jmp(instructions_array * array, int instru_index, int adr_jmp); + + + + +void exportInstructions(instructions_array * array); + +/* +void gen_arithmetique(instructions_array * array, enum operation op, int arg1, int arg2); + +int gen_var(Table_Symboles * table, instructions_array * array, char * varName); + +int gen_entier(Table_Symboles * table, instructions_array * array, int entier); + +int gen_return(Table_Symboles * table, instructions_array * array, int adr); + +int gen_jmpf(Table_Symboles * table, instructions_array * array, int cond, int dest); + +int gen_condition(Table_Symboles * table, instructions_array * array, enum operation op, int arg1, int arg2); + +int gen_print(Table_Symboles * table, instructions_array * array, int arg1); + */ +#endif \ No newline at end of file diff --git a/compiler/memory_oriented_assembly.txt b/compiler/memory_oriented_assembly.txt new file mode 100644 index 0000000..8a5ed67 --- /dev/null +++ b/compiler/memory_oriented_assembly.txt @@ -0,0 +1,26 @@ +JMP 8 +COP 255 0 +COP_LD 255 [255] +COP 1 255 +COP 255 1 +PRI 255 +AFC 255 1 +RET 255 +AFC 255 21 +COP 0 255 +LEA 255 0 +COP 1 255 +COP 255 1 +COP 5 255 +CALL 1 6 +COP 2 255 +COP 255 2 +PRI 255 +LEA 255 2 +COP 1 255 +AFC 255 2 +COP_STR [1] 255 +COP 255 2 +PRI 255 +AFC 255 0 +RET 255 diff --git a/compiler/table_fonctions.c b/compiler/table_fonctions.c new file mode 100644 index 0000000..1671275 --- /dev/null +++ b/compiler/table_fonctions.c @@ -0,0 +1,59 @@ +#include "table_fonctions.h" +#include +#include + +void initialise_function_table(Table_Fonctions * table){ + table->depth = 1; +} + +void add_function(Table_Fonctions * table, char * function_name, enum Return_Type return_type, int start_addr){ + Fonction fonction; + strcpy(fonction.function_name,function_name); + fonction.start_addr = start_addr; + fonction.type = return_type; + fonction.function_depth = table->depth; + table->array[table->depth] = fonction; + table->depth++; +} + +void print_function(Fonction * fonction){ + char * function_name = fonction->function_name; + int start_addr = fonction->start_addr; + int depth = fonction->function_depth; + int return_type = fonction->type; + char typeStr[20]; + if (return_type == RET_INT){ + strcpy(typeStr, "INT"); + } else if (return_type == RET_INT_PTR){ + strcpy(typeStr, "INT_PTR"); + } + printf("%-20s\t\t %-12s\t\t %-12d\t %-12d\n", function_name, typeStr, start_addr, depth); +} + +void print_fonction_table(Table_Fonctions * table) { + printf("%-20s\t\t %-12s\t\t %-12s\t %-20s\n", "Function Name", "Return Type", "Start Address", "Depth"); + Fonction fonction; + for (int i = 1; i < table->depth; i++) { + fonction = table->array[i]; + print_function(&fonction); + } +} + +int function_exists(Table_Fonctions * table, char * func_name){ + for (int i = 0; i < table->depth; i++){ + if (strcmp(table->array[i].function_name, func_name) == 0){ + return i; + } + } + return -1; +} + +/* +int main(){ + Table_Fonctions table; + initialise_function_table(&table); + add_function(&table, "Fonction1", 0, 7); + add_function(&table, "Fonction2", 1, 23); + print_fonction_table(&table); + return 1; +}*/ diff --git a/compiler/table_fonctions.h b/compiler/table_fonctions.h new file mode 100644 index 0000000..2c77e2c --- /dev/null +++ b/compiler/table_fonctions.h @@ -0,0 +1,35 @@ +// +// Created by Nahom Belay on 29/04/2021. +// + +#ifndef PROJET_SYSTEME_TABLE_FONCTIONS_H +#define PROJET_SYSTEME_TABLE_FONCTIONS_H + +#define FUNCTION_TABLE_SIZE 50 +#define FUNCTION_NAME_SIZE 30 + +enum Return_Type {RET_INT , RET_INT_PTR}; + +typedef struct Fonction { + char function_name[FUNCTION_NAME_SIZE]; + int start_addr ; + enum Return_Type type; + int function_depth; +} Fonction; + +typedef struct Table_Fonctions { + Fonction array[FUNCTION_TABLE_SIZE]; + int depth; +} Table_Fonctions; + +void initialise_function_table(Table_Fonctions * table); + +void add_function(Table_Fonctions * table, char * function_name, enum Return_Type return_type, int start_addr); + +void print_fonction_table(Table_Fonctions * table); + +int function_exists(Table_Fonctions * table, char * func_name); + + + +#endif //PROJET_SYSTEME_TABLE_FONCTIONS_H diff --git a/compiler/table_symboles.c b/compiler/table_symboles.c new file mode 100644 index 0000000..31f4899 --- /dev/null +++ b/compiler/table_symboles.c @@ -0,0 +1,152 @@ +#include "table_symboles.h" +#include +#include + + +void initialise_table(Table_Symboles * table){ + table->indexAvailableBottom = TABLE_SIZE - 1; + table->indexAvailableTop = 0; + table->depth = 0; +} + +int variable_exists(Table_Symboles * table, char * varName){ + for (int i = 0; i < table->indexAvailableTop; i++){ + if (strcmp(varName, table->array[i].Variable_Name) == 0){ + return i; + } + } + + for (int i = (table->indexAvailableBottom + 1); i < TABLE_SIZE; i++){ + if (strcmp(varName, table->array[i].Variable_Name) == 0){ + return i; + } + } + return 0; +} +int add_symbole_top(Table_Symboles * table, char * varName, enum Symbole_Type type, enum Initialised_Variable init, int depth){ + Symbole symbole; + strcpy(symbole.Variable_Name, varName); + symbole.addr = table->indexAvailableTop; + symbole.init = init; + symbole.type = type; + symbole.symbole_depth = table->depth; + if (table->indexAvailableTop >= table->indexAvailableBottom){ + return -1; + } else if (variable_exists(table, varName) != 0){ + return -2; + } else { + table->array[table->indexAvailableTop] = symbole; + table->indexAvailableTop++; + } + return 0; +} + +int add_symbole_bottom(Table_Symboles * table){ + Symbole symbole; + symbole.addr = table->indexAvailableBottom; + //symbole.symbole_depth = -1; + if (table->indexAvailableTop >= table->indexAvailableBottom){ + return -1; + } else { + table->array[table->indexAvailableBottom] = symbole; + table->indexAvailableBottom--; + } + return 0; +} + +int remove_symboles(Table_Symboles * table){ + if (table->indexAvailableTop > 0){ + while(table->indexAvailableTop > 0){ + if (table->array[table->indexAvailableTop-1].symbole_depth == table->depth){ + table->indexAvailableTop--; + } else { + break; + } + + } + } + + + //TODO: vérifier qu'il n'y a pas de varaibles temporarires au moment de changement de profondeur + return 0; +} + +void free_temp(Table_Symboles * table){ + table->indexAvailableBottom++; + if (table->indexAvailableBottom >= TABLE_SIZE){ + printf("Huge error\n"); + table->indexAvailableBottom--; + } +} + +int prepare_function_call(Table_Symboles * table){ + prepare_argument_push(table); + prepare_argument_push(table); +} + +int prepare_argument_push(Table_Symboles * table){ + Symbole symbole; + symbole.addr = table->indexAvailableTop; + symbole.symbole_depth = table->depth; + if (table->indexAvailableTop < table->indexAvailableBottom){ + table->array[table->indexAvailableTop] = symbole; + table->indexAvailableTop++; + return (table->indexAvailableTop) - 1 ; + } + +} + +int initialise_symbole(Table_Symboles * table, char * varName){ + int index = variable_exists(table, varName); + if (index == -1){ + return -1; + } else { + table->array[index].init = INITIALISED; + } +} + +void print_symbole(Symbole * symbole){ + char * var = symbole->Variable_Name; + int addr = symbole->addr; + enum Symbole_Type type = symbole->type; + char typeStr[20]; + if (type == TYPE_INT){ + strcpy(typeStr, "INT"); + } else if (type == TYPE_CONST_INT){ + strcpy(typeStr, "CONST_INT"); + } else if (type == TYPE_INT_PTR) { + strcpy(typeStr, "INT_PTR"); + } else { + strcpy(typeStr, "Error type"); + } + enum Initialised_Variable init = symbole->init; + char initStr[20]; + if (init == INITIALISED){ + strcpy(initStr,"INITIALISED"); + } else{ + strcpy(initStr,"NOT_INITIALISED"); + } + int depth = symbole->symbole_depth; + printf("%-20s\t\t %-12s\t\t %-12d\t %-20s\t %-12d\n", var, typeStr, addr, initStr, depth); +} + +void print_table(Table_Symboles * table){ + printf("%-20s\t\t %-12s\t\t %-12s\t %-20s\t %-12s\n", "Variable Name", "Type", "Address", "Initialised", "Depth"); + int indexTop = table->indexAvailableTop; + int indexBottom = table->indexAvailableBottom; + Symbole symbole; + for (int i = 0; i < indexTop; i++){ + symbole = table->array[i]; + print_symbole(&symbole); + } + if (table->indexAvailableBottom != TABLE_SIZE - 1){ + printf("%-20s\t\t %-12s\t\t %-12s\t %-20s\t %-12s\n", "...", "...", "...", "...", "..."); + for (int i = (indexBottom + 1); i < TABLE_SIZE; i++){ + symbole = table->array[i]; + print_symbole(&symbole); + } + } + + + +} diff --git a/compiler/table_symboles.h b/compiler/table_symboles.h new file mode 100644 index 0000000..0eac03f --- /dev/null +++ b/compiler/table_symboles.h @@ -0,0 +1,95 @@ +#ifndef TABLE_SYMBOLES_H +#define TABLE_SYMBOLES_H + +#define TABLE_SIZE 256 +#define VARIABLE_SIZE 30 + +enum Symbole_Type {TYPE_INT , TYPE_CONST_INT, TYPE_INT_PTR}; +enum Initialised_Variable{INITIALISED , NOT_INITIALISED}; + +typedef struct Symboles { + char Variable_Name[VARIABLE_SIZE]; + int addr ; + enum Symbole_Type type; + enum Initialised_Variable init; + int symbole_depth; +} Symbole; + +typedef struct Table_Symboles { + Symbole array[TABLE_SIZE]; + int indexAvailableTop; + int indexAvailableBottom; + int depth; +} Table_Symboles; + +/** + * Initialises indexAvailableTop at 0 and indexAvailableBottom at TABLE_SIZE - 1 + * @param table + */ +void initialise_table(Table_Symboles * table); + +/** + * Adds a symbole at the top (regular varaibles) + * @param table + * @param varName + * @param type + * @param init + * @return if symbole added successfully, -1 if the table is full and -2 if the varaible already exists in the table + */ +int add_symbole_top(Table_Symboles * table, char * varName, enum Symbole_Type type , enum Initialised_Variable init, int depth); + +/** + * Adds a symbole at the bottom (temp variables) + * @param table + * @return 0 if symbole added successfully, -1 if the table is full and -2 if the varaible already exists in the table + */ +int add_symbole_bottom(Table_Symboles * table); + + + +/** + * Verifies if a varaible name is already present in the table to avoid duplicates + * @param table + * @param varName + * @return -1 if the varaible name exists, 0 if it doesn't + */ +int variable_exists(Table_Symboles * table, char * varName); + +/** + * Removes symbole from table having certain depth + * @param table + * @return -1 if the symbole isn't in the table, 0 otherwise + */ +int remove_symboles(Table_Symboles * table); + + +void free_temp(Table_Symboles * table); + +int prepare_function_call(Table_Symboles * table); + +int prepare_argument_push(Table_Symboles * table); + + +/** + * Initialises an already exisiting symbole + * @param table + * @param varName + * @return -1 if the symbole isn't in the table, 0 otherwise + */ +int initialise_symbole(Table_Symboles * table, char * varName); + + +/** + * Prints a symbole with this format + * varName | Type | Address | Initialised/Not_Initialised + * @param symbole + */ +void print_symbole(Symbole * symbole); + +/** + * Prints the table + * @param table + */ +void print_table(Table_Symboles * table); + +#endif \ No newline at end of file diff --git a/interpreter/input.txt b/interpreter/interpreter_input.txt similarity index 100% rename from interpreter/input.txt rename to interpreter/interpreter_input.txt