diff options
Diffstat (limited to 'src/generator.c')
-rw-r--r-- | src/generator.c | 81 |
1 files changed, 46 insertions, 35 deletions
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 | 7 | void yyerror(char *); | |
8 | // ----- GLOBAL FUNCTIONS ----- | 8 | // ----- GLOBAL FUNCTIONS ----- |
9 | 9 | ||
10 | void gen_prologue() { | 10 | void 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 | ||
125 | void gen_function_return(Type expect, Type actual) { | 124 | void 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 ----- |
184 | void gen_reade(const char name[], Scope scope) { | 183 | void 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 | ||
204 | void gen_readc(const char name[], Scope scope) { | 203 | void 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 | ||
320 | void gen_or(int left, int right, int idx) { | 325 | void 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 | ||
338 | void gen_and(int left, int right, int idx) { | 343 | void 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 | ||
356 | void gen_eq(const char op[], int left, int right, int idx) { | 361 | void 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 | ||
373 | void gen_order(const char op[], int left, int right, int idx) { | 378 | void 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 | ||
394 | void gen_addsub(char op, int left, int right) { | 399 | void 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 | ||
410 | void gen_divstar(char op, int left, int right) { | 415 | void 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 | ||
428 | int gen_signed_expr(char op, int type) { | 433 | int 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 | ||
444 | int gen_negate_expr(int type) { | 449 | int gen_negate_expr(int type) { |
445 | check_expected_types(type, INT,TAB); | 450 | check_expected_types(type, INT, TAB); |
446 | fprintf(output, ";!F\npop rax\nxor rax,1\npush rax\n"); | 451 | fprintf(output, ";!F\npop rax\nxor rax,1\npush rax\n"); |
447 | return type; | 452 | return type; |
448 | } | 453 | } |
@@ -475,14 +480,20 @@ int gen_value_tab(const char ident[], Scope scope) { | |||
475 | int g_addr = glo_get_addr(ident); | 480 | int g_addr = glo_get_addr(ident); |
476 | switch (scope) { | 481 | switch (scope) { |
477 | case GLOBAL: | 482 | case GLOBAL: |
478 | fprintf(output, "pop rcx ;offset\nimul rcx,8\nmov rax,globals\n add rax,rcx\npush QWORD [rax + %d] ;%s\n", g_addr, ident); | 483 | fprintf(output, "pop rcx ;offset\nimul rcx,8\nmov rax,globals\n add " |
484 | "rax,rcx\npush QWORD [rax + %d] ;%s\n", | ||
485 | g_addr, ident); | ||
479 | return glo_lookup(ident); | 486 | return glo_lookup(ident); |
480 | case LOCAL: | 487 | case LOCAL: |
481 | if (l_addr != -1) { | 488 | if (l_addr != -1) { |
482 | fprintf(output, "pop rcx ;offset\nimul rcx,8\nmov rax,rbp\nsub rax,rcx\npush QWORD [rax - %d] ;%s\n", l_addr, ident); |