aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/rapport.md7
-rw-r--r--src/generator.c81
-rw-r--r--src/symbol_table.c42
3 files changed, 72 insertions, 58 deletions
diff --git a/doc/rapport.md b/doc/rapport.md
index d1c0226..28f8446 100644
--- a/doc/rapport.md
+++ b/doc/rapport.md
@@ -96,6 +96,13 @@ Dans les langages tel que le C, l'associativité se fait à gauche.
96On déclare donc `%left ,` pour l'indiquer à Bison. 96On déclare donc `%left ,` pour l'indiquer à Bison.
97 97
98 98
99# Analyse sémantique
100
101Le compilateur gère l'analyse sémantique.
102Par exemple l'opération `tab[1] * 3` est légale mais `'a' * 'b'` ne l'est pas. La grammaire l'accepte, mais l'analyse sémantique à parti des attributs interdits.
103
104
105
99# Génération de code cible 106# Génération de code cible
100 107
101## Gestion de la mémoire 108## Gestion de la mémoire
diff --git a/src/generator.c b/src/generator.c
index bb95e08..601f482 100644
--- a/src/generator.c
+++ b/src/generator.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "generator.h" 6#include "generator.h"
7 7void yyerror(char *);
8// ----- GLOBAL FUNCTIONS ----- 8// ----- GLOBAL FUNCTIONS -----
9 9
10void gen_prologue() { 10void gen_prologue() {
@@ -21,7 +21,6 @@ void gen_prologue_continue(int *bss_done) {
21 fprintf(output, "format_int_in: db \"%%d\", 0\n"); 21 fprintf(output, "format_int_in: db \"%%d\", 0\n");
22 fprintf(output, "format_char_in: db \"%%c\", 0\n\n"); 22 fprintf(output, "format_char_in: db \"%%c\", 0\n\n");
23 fprintf(output, "section .bss\n"); 23 fprintf(output, "section .bss\n");
24
25 fprintf(output, "globals: resq %d\n", nb_globals); 24 fprintf(output, "globals: resq %d\n", nb_globals);
26 fprintf(output, "section .text\n\nglobal _start\n"); 25 fprintf(output, "section .text\n\nglobal _start\n");
27 fprintf(output, "\nprinte: ;print needs an argument in rax\n"); 26 fprintf(output, "\nprinte: ;print needs an argument in rax\n");
@@ -121,8 +120,8 @@ void gen_function_end_declaration(const char name[], int return_type,
121 120
122void gen_function_return(Type expect, Type actual) { 121void gen_function_return(Type expect, Type actual) {
123 if (actual != expect) { 122 if (actual != expect) {
124 fprintf(stderr, "Return type mismatch at line %d.\n", lineno); 123 yyerror("Return type mismatch");
125 exit(1); 124 return;
126 } 125 }
127 if (actual != VOID_T) 126 if (actual != VOID_T)
128 fprintf(output, "pop rax\n"); 127 fprintf(output, "pop rax\n");
@@ -180,12 +179,12 @@ void gen_check(const char name[], Scope scope) {
180// ----- READ AND PRINT FUNCTIONS ----- 179// ----- READ AND PRINT FUNCTIONS -----
181void gen_reade(const char name[], Scope scope) { 180void gen_reade(const char name[], Scope scope) {
182 if (is_read_only(name, scope)) { 181 if (is_read_only(name, scope)) {
183 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, lineno); 182 yyerror("Symbol is read only");
184 exit(1); 183 return;
185 } 184 }
186 185
187 if (loc_lookup(name) != INT) { 186 if (loc_lookup(name) != INT) {
188 fprintf(stderr, "Need to be a INT in the reade() function\n"); 187 yyerror("Need to be a INT in the reade() function");
189 return; 188 return;
190 } 189 }
191 int l_addr = loc_get_addr(name); 190 int l_addr = loc_get_addr(name);
@@ -200,12 +199,12 @@ void gen_reade(const char name[], Scope scope) {
200 199
201void gen_readc(const char name[], Scope scope) { 200void gen_readc(const char name[], Scope scope) {
202 if (is_read_only(name, scope)) { 201 if (is_read_only(name, scope)) {
203 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, lineno); 202 yyerror("Symbol is read only");
204 exit(1); 203 return;
205 } 204 }
206 205
207 if (loc_lookup(name) != CHAR) { 206 if (loc_lookup(name) != CHAR) {
208 fprintf(stderr, "Need to be a CHAR in the readc() function\n"); 207 yyerror("Need to be a CHAR in the readc() function");
209 return; 208 return;
210 } 209 }
211 int l_addr = loc_get_addr(name); 210 int l_addr = loc_get_addr(name);
@@ -232,7 +231,7 @@ void gen_print(int type) {
232 fprintf(output, "call printe\n"); 231 fprintf(output, "call printe\n");
233 break; 232 break;
234 default: 233 default:
235 fprintf(stderr, "Error print, supposed to have type CHAR or INT or TAB\n"); 234 yyerror("Error print, supposed to have type CHAR or INT or TAB");
236 } 235 }
237} 236}
238 237
@@ -267,8 +266,8 @@ int gen_assign(const char ident[], Scope scope) {
267 int g_addr = glo_get_addr(ident); 266 int g_addr = glo_get_addr(ident);
268 267
269 if (is_read_only(ident, scope)) { 268 if (is_read_only(ident, scope)) {
270 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", ident, lineno); 269 yyerror("Symbol is read only");
271 exit(1); 270 return loc_lookup(ident);
272 } 271 }
273 272
274 switch (scope) { 273 switch (scope) {
@@ -293,20 +292,26 @@ int gen_assign_tab(const char ident[], Scope scope) {
293 int g_addr = glo_get_addr(ident); 292 int g_addr = glo_get_addr(ident);
294 293
295 if (is_read_only(ident, scope)) { 294 if (is_read_only(ident, scope)) {
296 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", ident, lineno); 295 yyerror("Symbol is read only");
297 exit(1); 296 return loc_lookup(ident);
298 } 297 }
299 298
300 switch (scope) { 299 switch (scope) {
301 case GLOBAL: 300 case GLOBAL:
302 fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov rax,globals\n add rax,rcx\npop QWORD [rax + %d] ;%s\n", g_addr, ident); 301 fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov "
302 "rax,globals\n add rax,rcx\npop QWORD [rax + %d] ;%s\n",
303 g_addr, ident);
303 return glo_lookup(ident); 304 return glo_lookup(ident);
304 case LOCAL: 305 case LOCAL:
305 if (l_addr != -1) { 306 if (l_addr != -1) {
306 fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov rax,rbp\nsub rax,rcx\npop QWORD [rax - %d] ;%s\n", l_addr, ident); 307 fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov "
308 "rax,rbp\nsub rax,rcx\npop QWORD [rax - %d] ;%s\n",
309 l_addr, ident);
307 return loc_lookup(ident); 310 return loc_lookup(ident);
308 } else { 311 } else {
309 fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov rax,globals\n add rax,rcx\npop QWORD [rax + %d] ;%s\n", g_addr, ident); 312 fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov "
313 "rax,globals\n add rax,rcx\npop QWORD [rax + %d] ;%s\n",
314 g_addr, ident);
310 return glo_lookup(ident); 315 return glo_lookup(ident);
311 } 316 }
312 default: 317 default:
@@ -315,8 +320,8 @@ int gen_assign_tab(const char ident[], Scope scope) {
315} 320}
316 321
317void gen_or(int left, int right, int idx) { 322void gen_or(int left, int right, int idx) {
318 check_expected_types(left, INT,TAB); 323 check_expected_types(left, INT, TAB);
319 check_expected_types(right, INT,TAB); 324 check_expected_types(right, INT, TAB);
320 325
321 fprintf(output, ";a OR c\n"); 326 fprintf(output, ";a OR c\n");
322 fprintf(output, "pop rax\n"); 327 fprintf(output, "pop rax\n");
@@ -333,8 +338,8 @@ void gen_or(int left, int right, int idx) {
333} 338}
334 339
335void gen_and(int left, int right, int idx) { 340void gen_and(int left, int right, int idx) {
336 check_expected_types(left, INT,TAB); 341 check_expected_types(left, INT, TAB);
337 check_expected_types(right, INT,TAB); 342 check_expected_types(right, INT, TAB);
338 343
339 fprintf(output, ";a AND c\n"); 344 fprintf(output, ";a AND c\n");
340 fprintf(output, "pop rax\n"); 345 fprintf(output, "pop rax\n");
@@ -351,8 +356,8 @@ void gen_and(int left, int right, int idx) {
351} 356}
352 357
353void gen_eq(const char op[], int left, int right, int idx) { 358void gen_eq(const char op[], int left, int right, int idx) {
354 check_expected_types(left, INT,TAB); 359 check_expected_types(left, INT, TAB);
355 check_expected_types(right, INT,TAB); 360 check_expected_types(right, INT, TAB);
356 361
357 fprintf(output, ";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n"); 362 fprintf(output, ";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n");
358 363
@@ -368,8 +373,8 @@ void gen_eq(const char op[], int left, int right, int idx) {
368} 373}
369 374
370void gen_order(const char op[], int left, int right, int idx) { 375void gen_order(const char op[], int left, int right, int idx) {
371 check_expected_types(left, INT,TAB); 376 check_expected_types(left, INT, TAB);
372 check_expected_types(right, INT,TAB); 377 check_expected_types(right, INT, TAB);
373 378
374 fprintf(output, ";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n"); 379 fprintf(output, ";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n");
375 380
@@ -389,8 +394,8 @@ void gen_order(const char op[], int left, int right, int idx) {
389} 394}
390 395
391void gen_addsub(char op, int left, int right) { 396void gen_addsub(char op, int left, int right) {
392 check_expected_types(left, INT,TAB); 397 check_expected_types(left, INT, TAB);
393 check_expected_types(right, INT,TAB); 398 check_expected_types(right, INT, TAB);
394 399
395 switch (op) { 400 switch (op) {
396 case '+': 401 case '+':
@@ -405,8 +410,8 @@ void gen_addsub(char op, int left, int right) {
405} 410}
406 411
407void gen_divstar(char op, int left, int right) { 412void gen_divstar(char op, int left, int right) {
408 check_expected_types(left, INT,TAB); 413 check_expected_types(left, INT, TAB);
409 check_expected_types(right, INT,TAB); 414 check_expected_types(right, INT, TAB);
410 415
411 switch (op) { 416 switch (op) {
412 case '*': 417 case '*':
@@ -423,7 +428,7 @@ void gen_divstar(char op, int left, int right) {
423} 428}
424 429
425int gen_signed_expr(char op, int type) { 430int gen_signed_expr(char op, int type) {
426 check_expected_types(type, INT,TAB); 431 check_expected_types(type, INT, TAB);
427 switch (op) { 432 switch (op) {
428 case '+': 433 case '+':
429 fprintf(output, ";+F\n"); 434 fprintf(output, ";+F\n");
@@ -439,7 +444,7 @@ int gen_signed_expr(char op, int type) {
439} 444}
440 445
441int gen_negate_expr(int type) { 446int gen_negate_expr(int type) {
442 check_expected_types(type, INT,TAB); 447 check_expected_types(type, INT, TAB);