From 337ca2a847e6c5f7555c90807f13412c349b753f Mon Sep 17 00:00:00 2001 From: pacien Date: Tue, 8 May 2018 22:51:11 +0200 Subject: Extract generators and reformat grammar --- src/generator.c | 60 ++++++++++++++- src/generator.h | 8 +- src/tpc.y | 225 +++++++++++++++++++++++--------------------------------- 3 files changed, 158 insertions(+), 135 deletions(-) (limited to 'src') diff --git a/src/generator.c b/src/generator.c index 004e559..e547a23 100644 --- a/src/generator.c +++ b/src/generator.c @@ -96,8 +96,19 @@ void gen_ifelse_end(int idx) { // ----- OPERATORS ----- -void gen_assign(int ident, Scope scope) { - // TODO: what's "$$" and how do we extract it? +int gen_assign(const char ident[], Scope scope) { + const char instr_fmt[] = "pop QWORD [rbp - %d] ;%s\n"; + + switch (scope) { + case GLOBAL: + printf(instr_fmt, glo_get_addr(ident), ident); + return glo_lookup(ident); + case LOCAL: + printf(instr_fmt, loc_get_addr(ident), ident); + return loc_lookup(ident); + default: + exit(1); + } } void gen_or(int left, int right, int idx) { @@ -206,3 +217,48 @@ void gen_divstar(char op, int left, int right) { } } +int gen_signed_expr(char op, int type) { + switch (op) { + case '+': + printf(";+F\n"); + break; + case '-': + printf(";-F\npop rdx\nxor rax,rax\nsub rax,rdx\npush rax\n"); + break; + default: + exit(1); + } + + return type; +} + +int gen_negate_expr(int type) { + printf(";!F\npop rax\nxor rax,1\npush rax\n"); + return type; +} + +int gen_value(const char ident[], Scope scope) { + switch (scope) { + case GLOBAL: + printf("push QWORD [rbp - %d] ;%s\n", glo_get_addr(ident), ident); + return glo_lookup(ident); + case LOCAL: + printf("push QWORD [rbp - %d] ;%s\n", loc_get_addr(ident), ident); + return loc_lookup(ident); + default: + exit(1); + } +} + +int gen_num(int value, Scope scope) { + if (scope == LOCAL) printf("push %d\n", value); // TODO: remove if? + // stored for the semantic analysis. + + return INT; +} + +int gen_char(int value, Scope scope) { + if(scope == LOCAL) printf("push %d\n", value); // TODO: remove if? + return CHAR; +} + diff --git a/src/generator.h b/src/generator.h index 17ea662..c907f66 100644 --- a/src/generator.h +++ b/src/generator.h @@ -23,7 +23,7 @@ void gen_if_start(int idx); void gen_if_end(int idx); void gen_ifelse_end(int idx); -void gen_assign(int ident, Scope scope); +int gen_assign(const char ident[], Scope scope); void gen_or(int left, int right, int idx); void gen_and(int left, int right, int idx); void gen_eq(const char op[], int left, int right, int idx); @@ -31,4 +31,10 @@ void gen_order(const char op[], int left, int right, int idx); void gen_addsub(char op, int left, int right); void gen_divstar(char op, int left, int right); +int gen_signed_expr(char op, int type); +int gen_negate_expr(int type); +int gen_value(const char ident[], Scope scope); +int gen_num(int value, Scope scope); +int gen_char(int value, Scope scope); + #endif diff --git a/src/tpc.y b/src/tpc.y index 12ff20d..17b8718 100644 --- a/src/tpc.y +++ b/src/tpc.y @@ -50,167 +50,128 @@ static int num_if = 0; %% Prog: { gen_prologue(); } - DeclConsts DeclVars DeclFoncts { gen_const_declaration(); } - ; + DeclConsts DeclVars DeclFoncts { gen_const_declaration(); } +; DeclConsts: - DeclConsts CONST ListConst ';' - | - ; + DeclConsts CONST ListConst ';' +| +; ListConst: - ListConst ',' IDENT '=' Litteral - | IDENT '=' Litteral - ; + ListConst ',' IDENT '=' Litteral +| IDENT '=' Litteral +; Litteral: - NombreSigne - | CARACTERE - ; + NombreSigne +| CARACTERE +; NombreSigne: - NUM - | ADDSUB NUM - ; + NUM +| ADDSUB NUM +; DeclVars: - DeclVars TYPE Declarateurs ';' - | - ; + DeclVars TYPE Declarateurs ';' +| +; Declarateurs: - Declarateurs ',' Declarateur { gen_declaration($3, $0, scope); } - | Declarateur { gen_declaration($1, $0, scope); } - ; + Declarateurs ',' Declarateur { gen_declaration($3, $0, scope); } +| Declarateur { gen_declaration($1, $0, scope); } +; Declarateur: - IDENT - | IDENT '[' NUM ']' - ; + IDENT +| IDENT '[' NUM ']' +; DeclFoncts: - DeclFoncts DeclFonct - | DeclFonct - ; + DeclFoncts DeclFonct +| DeclFonct +; DeclFonct: - EnTeteFonct { scope = LOCAL; } - Corps { scope = GLOBAL; } - ; + EnTeteFonct { scope = LOCAL; } + Corps { scope = GLOBAL; } +; EnTeteFonct: - TYPE IDENT '(' Parametres ')' - | VOID IDENT '(' Parametres ')' - ; + TYPE IDENT '(' Parametres ')' +| VOID IDENT '(' Parametres ')' +; Parametres: - VOID - | ListTypVar - ; + VOID +| ListTypVar +; ListTypVar: - ListTypVar ',' TYPE IDENT { gen_declaration($4, $3, scope); } - | TYPE IDENT { gen_declaration($2, $1, scope); } - ; + ListTypVar ',' TYPE IDENT { gen_declaration($4, $3, scope); } +| TYPE IDENT { gen_declaration($2, $1, scope); } +; Corps: - '{' DeclConsts DeclVars SuiteInstr '}' - ; + '{' DeclConsts DeclVars SuiteInstr '}' +; SuiteInstr: - SuiteInstr Instr - | - ; + SuiteInstr Instr +| +; Instr: - Exp ';' - | ';' - | RETURN Exp ';' - | RETURN ';' - | READE '(' IDENT ')' ';' { gen_read($3, scope); } - | READC '(' IDENT ')' ';' { gen_read($3, scope); } - | PRINT '(' Exp ')' ';' { gen_print();} - | IF '(' Exp IfHandling')' Instr { gen_if_label($4); } - | IF '(' Exp IfHandling')' Instr ELSE IfEndHandling Instr IfElseEndHandling - | WHILE '(' Exp ')' Instr - | '{' SuiteInstr '}' - ; + Exp ';' +| ';' +| RETURN Exp ';' +| RETURN ';' +| READE '(' IDENT ')' ';' { gen_read($3, scope); } +| READC '(' IDENT ')' ';' { gen_read($3, scope); } +| PRINT '(' Exp ')' ';' { gen_print();} +| IF '(' Exp IfHandling')' Instr { gen_if_label($4); } +| IF '(' Exp IfHandling')' Instr ELSE IfEndHandling Instr IfElseEndHandling +| WHILE '(' Exp ')' Instr +| '{' SuiteInstr '}' +; IfHandling: { gen_if_start($$ = num_if++); }; IfEndHandling: { gen_if_end($-3); }; IfElseEndHandling: { gen_ifelse_end($-5); }; Exp: - LValue '=' Exp { /* TODO: extract this into func */ - if(scope == 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 - ; + LValue '=' Exp { $$ = gen_assign($1, scope); } +| EB +; EB: - EB OR TB { gen_or($1, $3, num_label++); } - | TB - ; + EB OR TB { gen_or($1, $3, num_label++); } +| TB +; TB: - TB AND FB { gen_and($1, $3, num_label++); } - | FB - ; + TB AND FB { gen_and($1, $3, num_label++); } +| FB +; FB: - FB EQ M { gen_eq($2, $1, $3, num_label++); } - | M - ; + FB EQ M { gen_eq($2, $1, $3, num_label++); } +| M +; M: - M ORDER E { gen_order($2, $1, $3, num_label++); } - | E - ; + M ORDER E { gen_order($2, $1, $3, num_label++); } +| E +; E: - E ADDSUB T { gen_addsub($2, $1, $3); } - | T - ; + E ADDSUB T { gen_addsub($2, $1, $3); } +| T +; T: - T DIVSTAR F { gen_divstar($2, $1, $3); } - | F - ; + T DIVSTAR F { gen_divstar($2, $1, $3); } +| F + ; F: - ADDSUB F {$$ = $2;//on fait remonter le type - if($1 == '+') { - printf(";+F\n"); - } - else{ - printf(";-F\npop rdx\nxor rax,rax\nsub rax,rdx\npush rax\n"); - } - } - | '!' F {$$ = $2;printf(";!F\npop rax\nxor rax,1\npush rax\n");} - | '(' Exp ')' {$$ = $2;} - | LValue { - if(scope == 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; if(scope == LOCAL) printf("push %d\n",$1);} // on stocke les types pour l'analyse sémantique - | CARACTERE {$$ = CHAR; if(scope == LOCAL) printf("push %d\n",$1);} - | IDENT '(' Arguments ')' {$$ = INT;} //tableau d'entiers uniquement - ; + ADDSUB F { $$ = gen_signed_expr($1, $2); } +| '!' F { $$ = gen_negate_expr($2); } +| '(' Exp ')' { $$ = $2; } +| LValue { $$ = gen_value($1, scope); } +| NUM { $$ = gen_num($1, scope); } +| CARACTERE { $$ = gen_char($1, scope); } +| IDENT '(' Arguments ')' { $$ = INT; } // tableau d'entiers uniquement +; LValue: - IDENT { - if(scope == GLOBAL) { - glo_lookup($1); - } - else { - loc_lookup($1); - } - } - | IDENT '[' Exp ']' { - if(scope == GLOBAL) { - glo_lookup($1); - } - else { - loc_lookup($1); - } - } - ; + IDENT { gen_read($1, scope); } +| IDENT '[' Exp ']' { gen_read($1, scope); } +; Arguments: - ListExp - | - ; + ListExp +| +; ListExp: - ListExp ',' Exp - | Exp - ; + ListExp ',' Exp +| Exp +; %% void yyerror(char *msg){ -- cgit v1.2.3