From b8f7e7b6843c2bff778ce3c74e355a03e7565499 Mon Sep 17 00:00:00 2001 From: Adam NAILI Date: Sun, 3 Jun 2018 15:30:53 +0200 Subject: Functions tables + void functions working (need to work on returns and parameters cause all functions are void here) --- res/test_global.tpc | 15 ++++++--- src/generator.c | 24 +++++++++++--- src/generator.h | 3 ++ src/symbol_table.c | 91 ++++++++++++++++++++++++++++++++++++++++++----------- src/symbol_table.h | 16 ++++++++++ src/tpc.y | 27 ++++++++-------- 6 files changed, 136 insertions(+), 40 deletions(-) diff --git a/res/test_global.tpc b/res/test_global.tpc index 789f290..731fffb 100644 --- a/res/test_global.tpc +++ b/res/test_global.tpc @@ -4,9 +4,16 @@ entier r1,b,s,c,r2 ; caractere letter, digit, punct; +void calcul(void) { + entier i; + i = 3; + r1=12; + r2=13; + b = r1 + r2 + i; + print(b); +} + + entier main(void) { - r1=12; - r2=13; - b = r1 + r2; - print(b); + calcul(); } diff --git a/src/generator.c b/src/generator.c index c038b7f..d44bbd1 100644 --- a/src/generator.c +++ b/src/generator.c @@ -18,7 +18,7 @@ void gen_prologue_continue(int *bss_done){ if (*bss_done == 0){ fprintf(output, "globals: resq %d\n", nb_globals); fprintf(output, "section .text\n\nglobal _start\n"); - fprintf(output, "print: ;print needs an argument in rax\n"); + fprintf(output, "\nprint: ;print needs an argument in rax\n"); fprintf(output, "push rbp\n"); fprintf(output, "mov rbp, rsp\n"); fprintf(output, "push rsi\n"); @@ -29,19 +29,35 @@ void gen_prologue_continue(int *bss_done){ fprintf(output, "pop rsi\n"); fprintf(output, "pop rbp\n"); fprintf(output, "ret\n"); - fprintf(output, "\n_start:\n"); - fprintf(output, "push rbp\nmov rbp, rsp\n\n"); *bss_done = 1; } } void gen_const_declaration() { - fprintf(output, "mov rax,60 \n"); + fprintf(output, "\n_start:\n"); + fprintf(output, "push rbp\nmov rbp, rsp\n\n"); + fprintf(output, "call main\n"); + fprintf(output, "\nmov rax,60 \n"); fprintf(output, "mov rdi,0 \n"); fprintf(output, "syscall \n\n"); fprintf(output, ";global table\n"); glo_display_table(); fprintf(output, ";local table\n"); loc_display_table(); + fprintf(output, ";function table\n"); + fun_display_table(); +} + +void gen_function_declaration(const char name[], int return_type, int nb_param){ + fun_add(name,return_type,nb_param); + fprintf(output, "\n%s:\npush rbp\nmov rbp,rsp\n",name); +} + +void gen_function_end_declaration(){ + fprintf(output, "mov rsp, rbp\npop rbp\nret\n"); +} +int gen_function_call(const char name[], int nb_param){ + fprintf(output,"call %s\n",name); + return fun_lookup(name,nb_param); } void gen_declaration(const char name[], int type, Scope scope) { diff --git a/src/generator.h b/src/generator.h index 1a4c96a..b486172 100644 --- a/src/generator.h +++ b/src/generator.h @@ -19,6 +19,9 @@ FILE *output; void gen_prologue(); void gen_prologue_continue(int *bss_done); void gen_const_declaration(); +void gen_function_declaration(const char name[], int return_type, int nb_param); +void gen_function_end_declaration(); +int gen_function_call(const char name[], int nb_param); void gen_declaration(const char name[], int type, Scope scope); void gen_read(const char name[], Scope scope); diff --git a/src/symbol_table.c b/src/symbol_table.c index 6dc3e64..d03f858 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -10,6 +10,61 @@ extern int lineno; /* from lexical analyser */ SymbolTable glo_symbol_table = {{{{0}, 0}}, MAXSYMBOLS, 0}; SymbolTable loc_symbol_table = {{{{0}, 0}}, MAXSYMBOLS, 0}; +FunctionTable fun_table = {{{{0}, 0}}, MAXFUNCTIONS, 0}; + +void fun_add(const char name[], int rt_type, int nb_par) { + int count; + for (count = 0; count < fun_table.size; count++) { + if (!strcmp(fun_table.entries[count].name, name)) { + fprintf(stderr, + "semantic error, redefinition of function %s near line %d\n", + name, lineno); + return; + } + } + if (++fun_table.size > fun_table.maxsize) { + fprintf(stderr, "too many functions near line %d\n", lineno); + exit(1); + } + strcpy(fun_table.entries[fun_table.size - 1].name, name); + fun_table.entries[fun_table.size - 1].return_type = rt_type; + fun_table.entries[fun_table.size - 1].nb_parameters = nb_par; +} + +void fun_display_table() { + int count; + for (count = 0; count < fun_table.size; count++) { + if (fun_table.entries[count].return_type == INT) + fprintf(output, + ";%s, type de retour : entier, nombre de parametres : %d \n", + fun_table.entries[count].name, + fun_table.entries[count].nb_parameters); + else if (fun_table.entries[count].return_type == CHAR) + fprintf(output, + ";%s, type de retour : caractere, nombre de parametres : %d \n", + fun_table.entries[count].name, + fun_table.entries[count].nb_parameters); + else + fprintf(output, + ";%s, type de retour : void, nombre de parametres : %d \n", + fun_table.entries[count].name, + fun_table.entries[count].nb_parameters); + } + fprintf(output, "\n"); +} + +int fun_lookup(const char name[], int nb_param) { + int count; + + for (count = 0; count < fun_table.size; count++) { + if (!strcmp(fun_table.entries[count].name, name) && (fun_table.entries[count].nb_parameters == nb_param)) { + return fun_table.entries[count].return_type; + } + } + fprintf(stderr, "No definition of the function %s (or wrong number of parameters) near line %d\n", name, + lineno); + return -1; +} void glo_addVar(const char name[], int type) { int count; @@ -28,7 +83,7 @@ void glo_addVar(const char name[], int type) { strcpy(glo_symbol_table.entries[glo_symbol_table.size - 1].name, name); glo_symbol_table.entries[glo_symbol_table.size - 1].type = type; glo_symbol_table.entries[glo_symbol_table.size - 1].addr = - (glo_symbol_table.size - 1) * 8; + (glo_symbol_table.size - 1) * 8; } // Verifies that the variable exists and returns the type @@ -52,8 +107,6 @@ int glo_get_addr(const char name[]) { return glo_symbol_table.entries[count].addr; } } - fprintf(stderr, "No definition of the variable %s near line %d\n", name, - lineno); return -1; } @@ -62,12 +115,12 @@ void glo_display_table() { for (count = 0; count < glo_symbol_table.size; count++) { if (glo_symbol_table.entries[count].type == INT) fprintf(output, ";entier: %s, pos: %d \n", - glo_symbol_table.entries[count].name, - glo_symbol_table.entries[count].addr); + glo_symbol_table.entries[count].name, + glo_symbol_table.entries[count].addr); else fprintf(output, ";caractere: %s, pos: %d \n", - glo_symbol_table.entries[count].name, - glo_symbol_table.entries[count].addr); + glo_symbol_table.entries[count].name, + glo_symbol_table.entries[count].addr); } fprintf(output, "\n"); } @@ -89,7 +142,7 @@ void loc_addVar(const char name[], int type) { strcpy(loc_symbol_table.entries[loc_symbol_table.size - 1].name, name); loc_symbol_table.entries[loc_symbol_table.size - 1].type = type; loc_symbol_table.entries[loc_symbol_table.size - 1].addr = - (loc_symbol_table.size - 1) * 8; + (loc_symbol_table.size - 1) * 8 + 8; } int loc_lookup(const char name[]) { @@ -100,7 +153,7 @@ int loc_lookup(const char name[]) { return loc_symbol_table.entries[count].type; } } - //Check in global table + // Check in global table for (count = 0; count < glo_symbol_table.size; count++) { if (!strcmp(glo_symbol_table.entries[count].name, name)) { return glo_symbol_table.entries[count].type; @@ -128,12 +181,12 @@ void loc_display_table() { for (count = 0; count < loc_symbol_table.size; count++) { if (loc_symbol_table.entries[count].type == INT) fprintf(output, ";entier: %s, pos: %d \n", - loc_symbol_table.entries[count].name, - loc_symbol_table.entries[count].addr); + loc_symbol_table.entries[count].name, + loc_symbol_table.entries[count].addr); else fprintf(output, ";caractere: %s, pos: %d \n", - loc_symbol_table.entries[count].name, - loc_symbol_table.entries[count].addr); + loc_symbol_table.entries[count].name, + loc_symbol_table.entries[count].addr); } fprintf(output, "\n"); } @@ -148,16 +201,18 @@ void loc_clean_table() { static char *string_of_type(int type) { switch (type) { - case INT: return "INT"; - case CHAR: return "CHAR"; - default: return "UNEXPECTED"; + case INT: + return "INT"; + case CHAR: + return "CHAR"; + default: + return "UNEXPECTED"; } } void check_expected_type(int type_to_check, int type_expected) { if (type_to_check != type_expected) fprintf(stderr, "Expected type : %s -> Got type : %s (near line %d)\n", - string_of_type(type_to_check), - string_of_type(type_to_check), + string_of_type(type_to_check), string_of_type(type_to_check), lineno); } diff --git a/src/symbol_table.h b/src/symbol_table.h index fe0e35c..917e4f9 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -12,6 +12,7 @@ #define MAXNAME 32 #define MAXSYMBOLS 256 +#define MAXFUNCTIONS 256 typedef enum type { INT, @@ -30,6 +31,21 @@ typedef struct { int size; } SymbolTable; +typedef struct { + char name[MAXNAME]; + int return_type; + int nb_parameters; +} FTentry; + +typedef struct { + FTentry entries[MAXFUNCTIONS]; + int maxsize; + int size; +} FunctionTable; + +void fun_add(const char name[], int rt_type, int nb_par); +void fun_display_table(); +int fun_lookup(const char name[], int nb_param); void glo_addVar(const char name[], int type); int glo_lookup(const char name[]); int glo_get_addr(const char name[]); diff --git a/src/tpc.y b/src/tpc.y index 2938094..293f28e 100644 --- a/src/tpc.y +++ b/src/tpc.y @@ -5,9 +5,8 @@ * * TODO : * ------ - * - Gérer les globales avec .bss (Il faut donc décaler le début du programme après l'analyse des globales pour savoir combien de place réserver.) * - Gestion des tableaux - * - Tableau des fonctions + * - Fonctions avec paramètres et retour de fonctions (void fonctions déjà fonctionnelles) * */ @@ -44,7 +43,7 @@ static int num_if = 0; %token OR AND CONST IF ELSE WHILE RETURN VOID PRINT READC READE %token TYPE -%type Exp EB TB FB M E T F +%type Exp EB TB FB M E T F Parametres %type LValue %left ',' @@ -89,22 +88,22 @@ DeclFoncts: ; DeclFonct: EnTeteFonct { scope = LOCAL; } - Corps { scope = GLOBAL; } + Corps { gen_function_end_declaration(); scope = GLOBAL; } ; EnTeteFonct: - TYPE IDENT PrologueCont '(' Parametres ')' -| VOID IDENT PrologueCont '(' Parametres ')' + TYPE IDENT PrologueCont '(' Parametres ')' {gen_function_declaration($2, $1, $5);} +| VOID IDENT PrologueCont '(' Parametres ')' {gen_function_declaration($2, 2, $5);} ; PrologueCont: {gen_prologue_continue(&bss_done);}; Parametres: - VOID -| ListTypVar + VOID {$$ = 0;} +| ListTypVar { $$ = $1;} ; ListTypVar: - ListTypVar ',' TYPE IDENT { gen_declaration($4, $3, scope); } -| TYPE IDENT { gen_declaration($2, $1, scope); } + ListTypVar ',' TYPE IDENT { gen_declaration($4, $3, scope); $$ = $1+1; } +| TYPE IDENT { gen_declaration($2, $1, scope); $$ = 1; } ; Corps: '{' DeclConsts DeclVars SuiteInstr '}' @@ -164,7 +163,7 @@ F: | LValue { $$ = gen_value($1, scope); } | NUM { $$ = gen_num($1, scope); } | CARACTERE { $$ = gen_char($1, scope); } -| IDENT '(' Arguments ')' { $$ = INT; } // tableau d'entiers uniquement +| IDENT '(' Arguments ')' { $$ = gen_function_call($1,$3);} ; LValue: IDENT { gen_read($1, scope); } @@ -172,11 +171,11 @@ LValue: ; Arguments: ListExp -| +| {$$ = 0;} ; ListExp: - ListExp ',' Exp -| Exp + ListExp ',' Exp {$$ = $1 + 1;} +| Exp {$$ = 1;} ; %% -- cgit v1.2.3