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 44fdeab..bbb2af5 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");
@@ -124,8 +123,8 @@ void gen_function_end_declaration(const char name[], int return_type,
124 123
125void gen_function_return(Type expect, Type actual) { 124void gen_function_return(Type expect, Type actual) {
126 if (actual != expect) { 125 if (actual != expect) {
127 fprintf(stderr, "Return type mismatch at line %d.\n", lineno); 126 yyerror("Return type mismatch");
128 exit(1); 127 return;
129 } 128 }
130 if (actual != VOID_T) 129 if (actual != VOID_T)
131 fprintf(output, "pop rax\n"); 130 fprintf(output, "pop rax\n");
@@ -183,12 +182,12 @@ void gen_check(const char name[], Scope scope) {
183// ----- READ AND PRINT FUNCTIONS ----- 182// ----- READ AND PRINT FUNCTIONS -----
184void gen_reade(const char name[], Scope scope) { 183void gen_reade(const char name[], Scope scope) {
185 if (is_read_only(name, scope)) { 184 if (is_read_only(name, scope)) {
186 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, lineno); 185 yyerror("Symbol is read only");
187 exit(1); 186 return;
188 } 187 }
189 188
190 if (loc_lookup(name) != INT) { 189 if (loc_lookup(name) != INT) {
191 fprintf(stderr, "Need to be a INT in the reade() function\n"); 190 yyerror("Need to be a INT in the reade() function");
192 return; 191 return;
193 } 192 }
194 int l_addr = loc_get_addr(name); 193 int l_addr = loc_get_addr(name);
@@ -203,12 +202,12 @@ void gen_reade(const char name[], Scope scope) {
203 202
204void gen_readc(const char name[], Scope scope) { 203void gen_readc(const char name[], Scope scope) {
205 if (is_read_only(name, scope)) { 204 if (is_read_only(name, scope)) {
206 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, lineno); 205 yyerror("Symbol is read only");
207 exit(1); 206 return;
208 } 207 }
209 208
210 if (loc_lookup(name) != CHAR) { 209 if (loc_lookup(name) != CHAR) {
211 fprintf(stderr, "Need to be a CHAR in the readc() function\n"); 210 yyerror("Need to be a CHAR in the readc() function");
212 return; 211 return;
213 } 212 }
214 int l_addr = loc_get_addr(name); 213 int l_addr = loc_get_addr(name);
@@ -235,7 +234,7 @@ void gen_print(int type) {
235 fprintf(output, "call printe\n"); 234 fprintf(output, "call printe\n");
236 break; 235 break;
237 default: 236 default:
238 fprintf(stderr, "Error print, supposed to have type CHAR or INT or TAB\n"); 237 yyerror("Error print, supposed to have type CHAR or INT or TAB");
239 } 238 }
240} 239}
241 240
@@ -270,8 +269,8 @@ int gen_assign(const char ident[], Scope scope) {
270 int g_addr = glo_get_addr(ident); 269 int g_addr = glo_get_addr(ident);
271 270
272 if (is_read_only(ident, scope)) { 271 if (is_read_only(ident, scope)) {
273 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", ident, lineno); 272 yyerror("Symbol is read only");
274 exit(1); 273 return loc_lookup(ident);
275 } 274 }
276 275
277 switch (scope) { 276 switch (scope) {
@@ -296,20 +295,26 @@ int gen_assign_tab(const char ident[], Scope scope) {
296 int g_addr = glo_get_addr(ident); 295 int g_addr = glo_get_addr(ident);
297 296
298 if (is_read_only(ident, scope)) { 297 if (is_read_only(ident, scope)) {
299 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", ident, lineno); 298 yyerror("Symbol is read only");
300 exit(1); 299 return loc_lookup(ident);
301 } 300 }
302 301
303 switch (scope) { 302 switch (scope) {
304 case GLOBAL: 303 case GLOBAL:
305 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); 304 fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov "
305 "rax,globals\n add rax,rcx\npop QWORD [rax + %d] ;%s\n",
306 g_addr, ident);
306 return glo_lookup(ident); 307 return glo_lookup(ident);
307 case LOCAL: 308 case LOCAL:
308 if (l_addr != -1) { 309 if (l_addr != -1) {
309 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); 310 fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov "
311 "rax,rbp\nsub rax,rcx\npop QWORD [rax - %d] ;%s\n",
312 l_addr, ident);
310 return loc_lookup(ident); 313 return loc_lookup(ident);
311 } else { 314 } else {
312 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); 315 fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov "
316 "rax,globals\n add rax,rcx\npop QWORD [rax + %d] ;%s\n",
317 g_addr, ident);
313 return glo_lookup(ident); 318 return glo_lookup(ident);
314 } 319 }
315 default: 320 default:
@@ -318,8 +323,8 @@ int gen_assign_tab(const char ident[], Scope scope) {
318} 323}
319 324
320void gen_or(int left, int right, int idx) { 325void gen_or(int left, int right, int idx) {
321 check_expected_types(left, INT,TAB); 326 check_expected_types(left, INT, TAB);
322 check_expected_types(right, INT,TAB); 327 check_expected_types(right, INT, TAB);
323 328
324 fprintf(output, ";a OR c\n"); 329 fprintf(output, ";a OR c\n");
325 fprintf(output, "pop rax\n"); 330 fprintf(output, "pop rax\n");
@@ -336,8 +341,8 @@ void gen_or(int left, int right, int idx) {
336} 341}
337 342
338void gen_and(int left, int right, int idx) { 343void gen_and(int left, int right, int idx) {
339 check_expected_types(left, INT,TAB); 344 check_expected_types(left, INT, TAB);
340 check_expected_types(right, INT,TAB); 345 check_expected_types(right, INT, TAB);
341 346
342 fprintf(output, ";a AND c\n"); 347 fprintf(output, ";a AND c\n");
343 fprintf(output, "pop rax\n"); 348 fprintf(output, "pop rax\n");
@@ -354,8 +359,8 @@ void gen_and(int left, int right, int idx) {
354} 359}
355 360
356void gen_eq(const char op[], int left, int right, int idx) { 361void gen_eq(const char op[], int left, int right, int idx) {
357 check_expected_types(left, INT,TAB); 362 check_expected_types(left, INT, TAB);
358 check_expected_types(right, INT,TAB); 363 check_expected_types(right, INT, TAB);
359 364
360 fprintf(output, ";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n"); 365 fprintf(output, ";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n");
361 366
@@ -371,8 +376,8 @@ void gen_eq(const char op[], int left, int right, int idx) {
371} 376}
372 377
373void gen_order(const char op[], int left, int right, int idx) { 378void gen_order(const char op[], int left, int right, int idx) {
374 check_expected_types(left, INT,TAB); 379 check_expected_types(left, INT, TAB);
375 check_expected_types(right, INT,TAB); 380 check_expected_types(right, INT, TAB);
376 381
377 fprintf(output, ";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n"); 382 fprintf(output, ";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n");
378 383
@@ -392,8 +397,8 @@ void gen_order(const char op[], int left, int right, int idx) {
392} 397}
393 398
394void gen_addsub(char op, int left, int right) { 399void gen_addsub(char op, int left, int right) {
395 check_expected_types(left, INT,TAB); 400 check_expected_types(left, INT, TAB);
396 check_expected_types(right, INT,TAB); 401 check_expected_types(right, INT, TAB);
397 402
398 switch (op) { 403 switch (op) {
399 case '+': 404 case '+':
@@ -408,8 +413,8 @@ void gen_addsub(char op, int left, int right) {
408} 413}
409 414
410void gen_divstar(char op, int left, int right) { 415void gen_divstar(char op, int left, int right) {
411 check_expected_types(left, INT,TAB); 416 check_expected_types(left, INT, TAB);
412 check_expected_types(right, INT,TAB); 417 check_expected_types(right, INT, TAB);
413 418
414 switch (op) { 419 switch (op) {
415 case '*': 420 case '*':
@@ -426,7 +431,7 @@ void gen_divstar(char op, int left, int right) {
426} 431}
427 432
428int gen_signed_expr(char op, int type) { 433int gen_signed_expr(char op, int type) {
429 check_expected_types(type, INT,TAB); 434 check_expected_types(type, INT, TAB);
430 switch (op) { 435 switch (op) {
431 case '+': 436 case '+':
432 fprintf(output, ";+F\n"); 437 fprintf(output, ";+F\n");
@@ -442,7 +447,7 @@ int gen_signed_expr(char op, int type) {
442} 447}
443 448
444int gen_negate_expr(int type) { 449int gen_negate_expr(int type) {
445 check_expected_types(type, INT,TAB); 450 check_expected_types(type, INT, TAB);