diff options
-rw-r--r-- | src/generator.c | 16 | ||||
-rw-r--r-- | src/generator.h | 12 | ||||
-rw-r--r-- | src/tpc.y | 116 |
3 files changed, 72 insertions, 72 deletions
diff --git a/src/generator.c b/src/generator.c index 1b11b67..553161a 100644 --- a/src/generator.c +++ b/src/generator.c | |||
@@ -12,9 +12,8 @@ void gen_prologue() { | |||
12 | fprintf(output, "section .data\n"); | 12 | fprintf(output, "section .data\n"); |
13 | } | 13 | } |
14 | 14 | ||
15 | void gen_prologue_continue(int *bss_done) { | 15 | void gen_prologue_continue(bool *bss_done) { |
16 | if (*bss_done != 0) | 16 | if (!*bss_done) return; |
17 | return; | ||
18 | 17 | ||
19 | fprintf(output, "format_int db \"%%d\",10,0\n"); | 18 | fprintf(output, "format_int db \"%%d\",10,0\n"); |
20 | fprintf(output, "format_char db \"%%c\",10,0\n"); | 19 | fprintf(output, "format_char db \"%%c\",10,0\n"); |
@@ -115,8 +114,7 @@ Type gen_function_declaration(const char name[], int return_type) { | |||
115 | return return_type; | 114 | return return_type; |
116 | } | 115 | } |
117 | 116 | ||
118 | void gen_function_end_declaration(const char name[], int return_type, | 117 | void gen_function_end_declaration(const char name[], Type return_type, int nb_param) { |
119 | int nb_param) { | ||
120 | fun_add(name, return_type, nb_param); | 118 | fun_add(name, return_type, nb_param); |
121 | fprintf(output, "mov rax,-1\nmov rsp, rbp\npop rbp\nret\n"); | 119 | fprintf(output, "mov rax,-1\nmov rsp, rbp\npop rbp\nret\n"); |
122 | } | 120 | } |
@@ -139,7 +137,7 @@ Type gen_function_call(const char name[], int nb_param) { | |||
139 | return return_type; | 137 | return return_type; |
140 | } | 138 | } |
141 | 139 | ||
142 | void gen_declaration(const char name[], int type, Scope scope) { | 140 | void gen_declaration(const char name[], Type type, Scope scope) { |
143 | switch (scope) { | 141 | switch (scope) { |
144 | case GLOBAL: | 142 | case GLOBAL: |
145 | glo_addVar(name, type); | 143 | glo_addVar(name, type); |
@@ -220,7 +218,7 @@ void gen_readc(const char name[], Scope scope) { | |||
220 | fprintf(output, "mov rax,globals\nadd rax,%d\ncall readc\n", g_addr); | 218 | fprintf(output, "mov rax,globals\nadd rax,%d\ncall readc\n", g_addr); |
221 | } | 219 | } |
222 | 220 | ||
223 | void gen_print(int type) { | 221 | void gen_print(Type type) { |
224 | // check if the name exists in both tables | 222 | // check if the name exists in both tables |
225 | fprintf(output, "pop rax\n"); | 223 | fprintf(output, "pop rax\n"); |
226 | switch (type) { | 224 | switch (type) { |
@@ -437,7 +435,7 @@ void gen_divstar(char op, int left, int right) { | |||
437 | } | 435 | } |
438 | } | 436 | } |
439 | 437 | ||
440 | int gen_signed_expr(char op, int type) { | 438 | int gen_signed_expr(char op, Type type) { |
441 | check_expected_types(type, INT, TAB); | 439 | check_expected_types(type, INT, TAB); |
442 | switch (op) { | 440 | switch (op) { |
443 | case '+': | 441 | case '+': |
@@ -453,7 +451,7 @@ int gen_signed_expr(char op, int type) { | |||
453 | return type; | 451 | return type; |
454 | } | 452 | } |
455 | 453 | ||
456 | int gen_negate_expr(int type) { | 454 | int gen_negate_expr(Type type) { |
457 | check_expected_types(type, INT, TAB); | 455 | check_expected_types(type, INT, TAB); |
458 | fprintf(output, ";!F\npop rax\nxor rax,1\npush rax\n"); | 456 | fprintf(output, ";!F\npop rax\nxor rax,1\npush rax\n"); |
459 | return type; | 457 | return type; |
diff --git a/src/generator.h b/src/generator.h index e1e47df..e1fd714 100644 --- a/src/generator.h +++ b/src/generator.h | |||
@@ -15,23 +15,23 @@ extern int lineno; | |||
15 | FILE *output; | 15 | FILE *output; |
16 | 16 | ||
17 | void gen_prologue(); | 17 | void gen_prologue(); |
18 | void gen_prologue_continue(int *bss_done); | 18 | void gen_prologue_continue(bool *bss_done); |
19 | void gen_epilogue(); | 19 | void gen_epilogue(); |
20 | void gen_const(const char name[], int value, Scope scope); | 20 | void gen_const(const char name[], int value, Scope scope); |
21 | 21 | ||
22 | Type gen_function_declaration(const char name[], int return_type); | 22 | Type gen_function_declaration(const char name[], int return_type); |
23 | void gen_tab_declaration(const char name[], Scope scope, int size); | 23 | void gen_tab_declaration(const char name[], Scope scope, int size); |
24 | void gen_function_end_declaration(const char name[], int return_type, int nb_param); | 24 | void gen_function_end_declaration(const char name[], Type return_type, int nb_param); |
25 | void gen_function_return(Type expect, Type actual); | 25 | void gen_function_return(Type expect, Type actual); |
26 | Type gen_function_call(const char name[], int nb_param); | 26 | Type gen_function_call(const char name[], int nb_param); |
27 | 27 | ||
28 | void gen_declaration(const char name[], int type, Scope scope); | 28 | void gen_declaration(const char name[], Type type, Scope scope); |
29 | void gen_check(const char name[], Scope scope); | 29 | void gen_check(const char name[], Scope scope); |
30 | 30 | ||
31 | void gen_reade(const char name[], Scope scope); | 31 | void gen_reade(const char name[], Scope scope); |
32 | void gen_readc(const char name[], Scope scope); | 32 | void gen_readc(const char name[], Scope scope); |
33 | 33 | ||
34 | void gen_print(int type); | 34 | void gen_print(Type type); |
35 | 35 | ||
36 | void gen_if_label(int idx); | 36 | void gen_if_label(int idx); |
37 | void gen_if_start(int idx); | 37 | void gen_if_start(int idx); |
@@ -47,8 +47,8 @@ void gen_order(const char op[], int left, int right, int idx); | |||
47 | void gen_addsub(char op, int left, int right); | 47 | void gen_addsub(char op, int left, int right); |
48 | void gen_divstar(char op, int left, int right); | 48 | void gen_divstar(char op, int left, int right); |
49 | 49 | ||
50 | int gen_signed_expr(char op, int type); | 50 | int gen_signed_expr(char op, Type type); |
51 | int gen_negate_expr(int type); | 51 | int gen_negate_expr(Type type); |
52 | int gen_value(const char ident[], Scope scope); | 52 | int gen_value(const char ident[], Scope scope); |
53 | 53 | ||
54 | int gen_num(int value, Scope scope); | 54 | int gen_num(int value, Scope scope); |
@@ -15,14 +15,14 @@ int yylex(); | |||
15 | void yyerror(char *); | 15 | void yyerror(char *); |
16 | static Scope scope = GLOBAL; | 16 | static Scope scope = GLOBAL; |
17 | static Type return_type = VOID_T; | 17 | static Type return_type = VOID_T; |
18 | static int bss_done = 0; | 18 | static bool bss_done = false; |
19 | static int num_label = 0; | 19 | static int num_label = 0; |
20 | static int num_if = 0; | 20 | static int num_if = 0; |
21 | static int num_while = 0; | 21 | static int num_while = 0; |
22 | static int nb_param[255]; | 22 | static int nb_param[255]; |
23 | static int num_scope = -1; | 23 | static int num_scope = -1; |
24 | static int offset = 0; | 24 | static int offset = 0; |
25 | static int is_array = 0; | 25 | static bool is_array = false; |
26 | static char fname[64]; | 26 | static char fname[64]; |
27 | %} | 27 | %} |
28 | 28 | ||
@@ -76,50 +76,49 @@ DeclVars: | |||
76 | | | 76 | | |
77 | ; | 77 | ; |
78 | Declarateurs: | 78 | Declarateurs: |
79 | Declarateurs ',' Declarateur { | 79 | Declarateurs ',' Declarateur { if (is_array) gen_tab_declaration($<ident>3, scope, offset); |
80 | if(!is_array){ | 80 | else gen_declaration($<ident>3, $<type>0, scope); } |
81 | gen_declaration($<ident>3, $<type>0, scope); | 81 | | Declarateur { if (is_array) gen_tab_declaration($<ident>1, scope, offset); |
82 | }else{ | 82 | else gen_declaration($<ident>1, $<type>0, scope); } |
83 | gen_tab_declaration($<ident>3, scope, offset); | ||
84 | } | ||
85 | } | ||
86 | | Declarateur { | ||
87 | if(!is_array){ | ||
88 | gen_declaration($<ident>1, $<type>0, scope); | ||
89 | }else{ | ||
90 | gen_tab_declaration($<ident>1, scope, offset); | ||
91 | } | ||
92 | } | ||
93 | ; | 83 | ; |
94 | Declarateur: | 84 | Declarateur: |
95 | IDENT {strcpy($$,$1);is_array = 0;} | 85 | IDENT { strcpy($$, $1); is_array = false; } |
96 | | IDENT '[' NUM ']' {offset = $<num>3;strcpy($$,$1);is_array=1;} | 86 | | IDENT '[' NUM ']' { offset = $<num>3; strcpy($$, $1); is_array = true; } |
97 | ; | 87 | ; |
98 | DeclFoncts: | 88 | DeclFoncts: |
99 | DeclFoncts DeclFonct | 89 | DeclFoncts DeclFonct |
100 | | DeclFonct | 90 | | DeclFonct |
101 | ; | 91 | ; |
102 | DeclFonct: | 92 | DeclFonct: |
103 | EnTeteFonct { scope = LOCAL; } | 93 | EnTeteFonct { scope = LOCAL; } |
104 | Corps { gen_function_end_declaration(fname,return_type,nb_param[num_scope]); scope = GLOBAL; return_type = VOID_T; num_scope--; loc_clean_table(); } | 94 | Corps { gen_function_end_declaration(fname, return_type, nb_param[num_scope]); |
95 | scope = GLOBAL; return_type = VOID_T; num_scope--; loc_clean_table(); } | ||
105 | ; | 96 | ; |
106 | EnTeteFonct: | 97 | EnTeteFonct: |
107 | TYPE IDENT PrologueCont {strcpy(fname,$<ident>2); return_type = gen_function_declaration($<ident>2, $<type>1);} '(' Parametres ')' { nb_param[++num_scope] = $<num>6 ; scope = GLOBAL;} | 98 | TYPE IDENT PrologueCont { strcpy(fname, $<ident>2); |
108 | | VOID IDENT PrologueCont {strcpy(fname,$<ident>2); return_type = gen_function_declaration($<ident>2, VOID_T);} '(' Parametres ')' { nb_param[++num_scope] = $<num>6 ; scope = GLOBAL; } | 99 | return_type = gen_function_declaration($<ident>2, $<type>1); } |
100 | '(' Parametres ')' { nb_param[++num_scope] = $<num>6; scope = GLOBAL;} | ||
101 | | VOID IDENT PrologueCont { strcpy(fname, $<ident>2); | ||
102 | return_type = gen_function_declaration($<ident>2, VOID_T); } | ||
103 | '(' Parametres ')' { nb_param[++num_scope] = $<num>6; scope = GLOBAL; } | ||
109 | ; | 104 | ; |
110 | 105 | ||
111 | PrologueCont: {scope = LOCAL;gen_prologue_continue(&bss_done);}; | 106 | PrologueCont: { scope = LOCAL; gen_prologue_continue(&bss_done); }; |
112 | 107 | ||
113 | Parametres: | 108 | Parametres: |
114 | VOID {$$ = 0;} | 109 | VOID { $$ = 0; } |
115 | | ListTypVar { $<num>$ = $<num>1;} | 110 | | ListTypVar { $<num>$ = $<num>1; } |
116 | ; | 111 | ; |
117 | ListTypVar: | 112 | ListTypVar: |
118 | ListTypVar ',' TYPE IDENT { gen_declaration($<ident>4, $<type>3, scope); $<num>$ = $<num>1+1; } | 113 | ListTypVar ',' TYPE IDENT { gen_declaration($<ident>4, $<type>3, scope); $<num>$ = $<num>1+1; } |
119 | | TYPE IDENT { gen_declaration($<ident>2, $<type>1, scope); $<num>$ = 1; } | 114 | | TYPE IDENT { gen_declaration($<ident>2, $<type>1, scope); $<num>$ = 1; } |
120 | ; | 115 | ; |
121 | Corps: | 116 | Corps: |
122 | '{' {int i; for(i=1;i<=nb_param[num_scope];i++){fprintf(output, "mov r8, [rbp + %d]\nmov [rbp - %d], r8\n", (nb_param[num_scope]-i+2)*8, i*8);} } DeclConsts DeclVars SuiteInstr '}' | 117 | '{' { int i; |
118 | for(i=1;i<=nb_param[num_scope];i++){ | ||
119 | fprintf(output, "mov r8, [rbp + %d]\nmov [rbp - %d], r8\n", (nb_param[num_scope]-i+2)*8, i*8); | ||
120 | } } | ||
121 | DeclConsts DeclVars SuiteInstr '}' | ||
123 | ; | 122 | ; |
124 | SuiteInstr: | 123 | SuiteInstr: |
125 | SuiteInstr Instr | 124 | SuiteInstr Instr |
@@ -128,67 +127,70 @@ SuiteInstr: | |||
128 | Instr: | 127 | Instr: |
129 | Exp ';' | 128 | Exp ';' |
130 | | ';' | 129 | | ';' |
131 | | RETURN Exp ';' { gen_function_return(return_type, $<type>2); } | 130 | | RETURN Exp ';' { gen_function_return(return_type, $<type>2); } |
132 | | RETURN ';' { gen_function_return(return_type, VOID_T);} | 131 | | RETURN ';' { gen_function_return(return_type, VOID_T); } |
133 | | READE '(' IDENT ')' ';' { gen_reade($<ident>3, scope); } | 132 | | READE '(' IDENT ')' ';' { gen_reade($<ident>3, scope); } |
134 | | READC '(' IDENT ')' ';' { gen_readc($<ident>3, scope); } | 133 | | READC '(' IDENT ')' ';' { gen_readc($<ident>3, scope); } |
135 | | PRINT '(' Exp ')' ';' { gen_print($<type>3);} | 134 | | PRINT '(' Exp ')' ';' { gen_print($<type>3);} |
136 | | IF '(' Exp IfHandling')' Instr { gen_if_label($<num>4); } | 135 | | IF '(' Exp IfHandling')' Instr { gen_if_label($<num>4); } |
137 | | IF '(' Exp IfHandling')' Instr ELSE IfEndHandling Instr IfElseEndHandling | 136 | | IF '(' Exp IfHandling')' Instr |
138 | | WHILE {fprintf(output,".upwhile%d:\n",num_w |