From c9c4fbbde6e4f4f3942777cd9930cf40375e0ea9 Mon Sep 17 00:00:00 2001 From: Adam NAILI Date: Fri, 4 May 2018 01:03:21 +0200 Subject: Add sub working (local/global not fully implemented, checking type function available --- src/symboltable.c | 124 ++++++++++++++++++++++++++++++++++++++---------------- src/symboltable.h | 3 ++ src/tpc.y | 92 ++++++++++++++++++++++++++++------------ 3 files changed, 157 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/symboltable.c b/src/symboltable.c index cdbd442..5c63d3f 100644 --- a/src/symboltable.c +++ b/src/symboltable.c @@ -2,28 +2,30 @@ extern int lineno; /* from lexical analyser */ -SymbolTable glo_symbol_table = {{{{0},0}},MAXSYMBOLS,0}; -SymbolTable loc_symbol_table = {{{{0},0}},MAXSYMBOLS,0}; +SymbolTable glo_symbol_table = {{{{0}, 0}}, MAXSYMBOLS, 0}; +SymbolTable loc_symbol_table = {{{{0}, 0}}, MAXSYMBOLS, 0}; void glo_addVar(const char name[], int type) { int count; for (count = 0; count < glo_symbol_table.size; count++) { if (!strcmp(glo_symbol_table.entries[count].name, name)) { - fprintf(stderr,"semantic error, redefinition of variable %s near line %d\n", name, - lineno); + fprintf(stderr, + "semantic error, redefinition of variable %s near line %d\n", + name, lineno); return; } } if (++glo_symbol_table.size > glo_symbol_table.maxsize) { - fprintf(stderr,"too many variables near line %d\n", lineno); + fprintf(stderr, "too many variables near line %d\n", lineno); exit(1); } 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.entries[glo_symbol_table.size - 1].addr = + (glo_symbol_table.size - 1) * 8; } -//Verifies that the variable exists and returns the type +// Verifies that the variable exists and returns the type int glo_lookup(const char name[]) { int count; @@ -32,43 +34,58 @@ int glo_lookup(const char name[]) { return glo_symbol_table.entries[count].type; } } - fprintf(stderr,"No definition of the variable %s near line %d\n", name, - lineno); + fprintf(stderr, "No definition of the variable %s near line %d\n", name, + lineno); return -1; } +int glo_get_addr(const char name[]) { + int count; - -void glo_display_table(){ - int count; - for (count=0;count glo_symbol_table.maxsize) { - fprintf(stderr,"too many variables near line %d\n", lineno); + if (++loc_symbol_table.size > loc_symbol_table.maxsize) { + fprintf(stderr, "too many variables near line %d\n", lineno); exit(1); } - 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; + 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; } - int loc_lookup(const char name[]) { int count; @@ -77,17 +94,52 @@ int loc_lookup(const char name[]) { return loc_symbol_table.entries[count].type; } } - fprintf(stderr,"No definition of the variable %s near line %d\n", name, - lineno); + fprintf(stderr, "No definition of the variable %s near line %d\n", name, + lineno); return -1; } -void loc_display_table(){ - int count; - for (count=0;count Got type : %s (near line %d)\n", + type_expected == INT ? "INT" : type_expected == CHAR ? "CHAR" + : "UNDEFINED", + type_to_check == INT ? "INT" : type_to_check == CHAR ? "CHAR" + : "UNDEFINED", + lineno); } \ No newline at end of file diff --git a/src/symboltable.h b/src/symboltable.h index bd7a373..ac6db36 100644 --- a/src/symboltable.h +++ b/src/symboltable.h @@ -26,8 +26,11 @@ typedef struct { void glo_addVar(const char name[], int type); int glo_lookup(const char name[]); +int glo_get_addr(const char name[]); void glo_display_table(); void loc_addVar(const char name[], int type); int loc_lookup(const char name[]); +int loc_get_addr(const char name[]); void loc_display_table(); +void check_expected_type(int type_to_check, int type_expected); #endif \ No newline at end of file diff --git a/src/tpc.y b/src/tpc.y index c575863..387b3ef 100644 --- a/src/tpc.y +++ b/src/tpc.y @@ -10,10 +10,10 @@ extern int lineno; int yylex(); void yyerror(char *); - #define GLOBAL 0 #define LOCAL 1 static int status = GLOBAL; + %} %union { @@ -44,9 +44,9 @@ static int status = GLOBAL; %% Prog:{printf("extern printf\n"); printf("section .data\n"); - printf("format_int db \"%%d \\n\",10,0\n\n"); + printf("format_int db \"%%d\",10,0\n\n"); printf("section .bss\nsection .text\n\nglobal _start\n"); - printf("print: ;print needs an argument in rax\n\n"); + printf("print: ;print needs an argument in rax\n"); printf("push rbp\n"); printf("mov rbp, rsp\n"); printf("push rsi\n"); @@ -58,12 +58,17 @@ Prog:{printf("extern printf\n"); printf("pop rbp\n"); printf("ret\n"); printf("\n_start:\n"); + printf("push rbp\nmov rbp, rsp\n\n"); } DeclConsts DeclVars DeclFoncts { printf("mov rax,60 \n"); printf("mov rdi,0 \n"); printf("syscall \n"); + printf(";global table\n"); + glo_display_table(); + printf(";local table\n"); + loc_display_table(); } ; DeclConsts: @@ -87,8 +92,12 @@ DeclVars: | ; Declarateurs: - Declarateurs ',' Declarateur {glo_addVar($3, $0);} - | Declarateur {glo_addVar($1, $0);} + Declarateurs ',' Declarateur {if(status == GLOBAL) glo_addVar($3, $0); + else loc_addVar($3, $0); + printf("push 0\n");} + | Declarateur {if(status == GLOBAL) glo_addVar($1, $0); + else loc_addVar($1, $0); + printf("push 0\n");} ; Declarateur: IDENT @@ -110,8 +119,12 @@ Parametres: | ListTypVar ; ListTypVar: - ListTypVar ',' TYPE IDENT {glo_addVar($4, $3);} - | TYPE IDENT {glo_addVar($2, $1);} + ListTypVar ',' TYPE IDENT {if(status == GLOBAL) glo_addVar($4, $3); + else loc_addVar($4, $3); + printf("push 0\n");} + | TYPE IDENT {if(status == GLOBAL) glo_addVar($2, $1); + else loc_addVar($2, $1); + printf("push 0\n");} ; Corps: '{' DeclConsts DeclVars SuiteInstr '}' @@ -124,54 +137,81 @@ Instr: | ';' | RETURN Exp ';' | RETURN ';' - | READE '(' IDENT ')' ';' {glo_lookup($3);} - | READC '(' IDENT ')' ';' {glo_lookup($3);} - | PRINT '(' Exp ')' ';' + | READE '(' IDENT ')' ';' {if(status == GLOBAL) glo_lookup($3); + else loc_lookup($3);} + | READC '(' IDENT ')' ';' {if(status == GLOBAL) glo_lookup($3); + else loc_lookup($3);} + | PRINT '(' Exp ')' ';' {printf("pop rax\ncall print\n");} | IF '(' Exp ')' Instr | IF '(' Exp ')' Instr ELSE Instr | WHILE '(' Exp ')' Instr | '{' SuiteInstr '}' ; Exp: - LValue '=' Exp {$$ = glo_lookup($1);} + LValue '=' Exp {if(status == GLOBAL){ + $$ = glo_lookup($1); + printf("pop QWORD [rbp - %d] ;%s\n",glo_get_addr($1),$1); + } + else { + $$ = loc_lookup($1); + printf("pop QWORD [rbp - %d] ;%s\n",loc_get_addr($1),$1); + } + } | EB ; EB: - EB OR TB + EB OR TB {check_expected_type($1,INT);check_expected_type($3,INT);} | TB ; TB: - TB AND FB + TB AND FB {check_expected_type($1,INT);check_expected_type($3,INT);} | FB ; FB: - FB EQ M + FB EQ M {check_expected_type($1,INT);check_expected_type($3,INT);} | M ; M: - M ORDER E + M ORDER E {check_expected_type($1,INT);check_expected_type($3,INT);} | E ; E: - E ADDSUB T + E ADDSUB T {check_expected_type($1,INT);check_expected_type($3,INT); + if($2 == '+'){ + printf(";E + T\npop rcx\npop rax\nadd rax,rcx\npush rax\n"); + } + else{ + printf(";E - T\npop rcx\npop rax\nsub rax,rcx\npush rax\n"); + } + } | T ; T: - T DIVSTAR F + T DIVSTAR F {check_expected_type($1,INT);check_expected_type($3,INT);} | F ; F: - ADDSUB F {$$ = $2;} //on fait remonter le type - | '!' F {$$ = $2;} - | '(' Exp ')' {$$ = $2;} - | LValue {$$ = glo_lookup($1);} - | NUM {$$ = INT;} // on stocke les types pour l'analyse sémantique - | CARACTERE {$$ = CHAR;} - | IDENT '(' Arguments ')' {$$ = INT;} //tableau d'entiers uniquement + ADDSUB F {$$ = $2;//on fait remonter le type + if($1 == '+') { + printf(";+F\n"); + } + else{ + printf(";-F\npop rdx\nxor eax,eax\nsub eax,edx\npush rax\n"); + } + } + | '!' F {$$ = $2;printf(";!F\npop rax\nxor rax,1\npush rax\n");} + | '(' Exp ')' {$$ = $2;} + | LValue {if(status == GLOBAL) {$$ = glo_lookup($1);printf("push QWORD [rbp - %d] ;%s\n",glo_get_addr($1),$1);} + else {$$ = loc_lookup($1); printf("push QWORD [rbp - %d] ;%s\n",loc_get_addr($1),$1);}} + | NUM {$$ = INT; printf("push %d\n",$1);} // on stocke les types pour l'analyse sémantique + | CARACTERE {$$ = CHAR; printf("push %d\n",$1);} + | IDENT '(' Arguments ')' {$$ = INT;} //tableau d'entiers uniquement ; LValue: - IDENT {glo_lookup($1);} - | IDENT '[' Exp ']' {glo_lookup($1);} + IDENT {if(status == GLOBAL) {glo_lookup($1);} + else {loc_lookup($1);}} + | IDENT '[' Exp ']' {if(status == GLOBAL) {glo_lookup($1);} + else {loc_lookup($1);}} ; Arguments: ListExp -- cgit v1.2.3