aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpacien2018-06-06 14:36:30 +0200
committerpacien2018-06-06 14:36:30 +0200
commit69ccd36180efa1f8f90a4214f8fa5e143ff37c38 (patch)
tree4dfb8282c71c8f55ec526afc33cb100d6ceaadc5
parent58e0712bb4f624e02bffc877bf39f5fd45acc2e4 (diff)
parent901e95ebf54575d24e533383fabfc5e9d916bf39 (diff)
downloadtpc-compiler-69ccd36180efa1f8f90a4214f8fa5e143ff37c38.tar.gz
Merge branch 'master' of https://github.com/pacien/upem-compil-tpc
-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 b75f7a8..1b11b67 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 @@ static int gen_assign_simple(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 @@ static 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:
@@ -325,8 +330,8 @@ int gen_assign(const char ident[], Scope scope) {
325} 330}
326 331
327void gen_or(int left, int right, int idx) { 332void gen_or(int left, int right, int idx) {
328 check_expected_types(left, INT,TAB); 333 check_expected_types(left, INT, TAB);
329 check_expected_types(right, INT,TAB); 334 check_expected_types(right, INT, TAB);
330 335
331 fprintf(output, ";a OR c\n"); 336 fprintf(output, ";a OR c\n");
332 fprintf(output, "pop rax\n"); 337 fprintf(output, "pop rax\n");
@@ -343,8 +348,8 @@ void gen_or(int left, int right, int idx) {
343} 348}
344 349
345void gen_and(int left, int right, int idx) { 350void gen_and(int left, int right, int idx) {
346 check_expected_types(left, INT,TAB); 351 check_expected_types(left, INT, TAB);
347 check_expected_types(right, INT,TAB); 352 check_expected_types(right, INT, TAB);
348 353
349 fprintf(output, ";a AND c\n"); 354 fprintf(output, ";a AND c\n");
350 fprintf(output, "pop rax\n"); 355 fprintf(output, "pop rax\n");
@@ -361,8 +366,8 @@ void gen_and(int left, int right, int idx) {
361} 366}
362 367
363void gen_eq(const char op[], int left, int right, int idx) { 368void gen_eq(const char op[], int left, int right, int idx) {
364 check_expected_types(left, INT,TAB); 369 check_expected_types(left, INT, TAB);
365 check_expected_types(right, INT,TAB); 370 check_expected_types(right, INT, TAB);
366 371
367 fprintf(output, ";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n"); 372 fprintf(output, ";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n");
368 373
@@ -378,8 +383,8 @@ void gen_eq(const char op[], int left, int right, int idx) {
378} 383}
379 384
380void gen_order(const char op[], int left, int right, int idx) { 385void gen_order(const char op[], int left, int right, int idx) {
381 check_expected_types(left, INT,TAB); 386 check_expected_types(left, INT, TAB);
382 check_expected_types(right, INT,TAB); 387 check_expected_types(right, INT, TAB);
383 388
384 fprintf(output, ";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n"); 389 fprintf(output, ";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n");
385 390
@@ -399,8 +404,8 @@ void gen_order(const char op[], int left, int right, int idx) {
399} 404}
400 405
401void gen_addsub(char op, int left, int right) { 406void gen_addsub(char op, int left, int right) {
402 check_expected_types(left, INT,TAB); 407 check_expected_types(left, INT, TAB);
403 check_expected_types(right, INT,TAB); 408 check_expected_types(right, INT, TAB);
404 409
405 switch (op) { 410 switch (op) {
406 case '+': 411 case '+':
@@ -415,8 +420,8 @@ void gen_addsub(char op, int left, int right) {
415} 420}
416 421
417void gen_divstar(char op, int left, int right) { 422void gen_divstar(char op, int left, int right) {
418 check_expected_types(left, INT,TAB); 423 check_expected_types(left, INT, TAB);
419 check_expected_types(right, INT,TAB); 424 check_expected_types(right, INT, TAB);
420 425
421 switch (op) { 426 switch (op) {
422 case '*': 427 case '*':
@@ -433,7 +438,7 @@ void gen_divstar(char op, int left, int right) {
433} 438}
434 439
435int gen_signed_expr(char op, int type) { 440int gen_signed_expr(char op, int type) {
436 check_expected_types(type, INT,TAB); 441 check_expected_types(type, INT, TAB);
437 switch (op) { 442 switch (op) {
438 case '+': 443 case '+':
439 fprintf(output, ";+F\n"); 444 fprintf(output, ";+F\n");
@@ -449,7 +454,7 @@ int gen_signed_expr(char op, int type) {
449}