diff options
Diffstat (limited to 'src/generator.c')
-rw-r--r-- | src/generator.c | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/src/generator.c b/src/generator.c index 8329aee..c038b7f 100644 --- a/src/generator.c +++ b/src/generator.c | |||
@@ -14,27 +14,30 @@ void gen_prologue() { | |||
14 | fprintf(output, "format_int db \"%%d\",10,0\n\n"); | 14 | fprintf(output, "format_int db \"%%d\",10,0\n\n"); |
15 | fprintf(output, "section .bss\n"); | 15 | fprintf(output, "section .bss\n"); |
16 | } | 16 | } |
17 | void gen_prologue_continue(){ | 17 | void gen_prologue_continue(int *bss_done){ |
18 | fprintf(output, "globals: resq %d\n", nb_globals); | 18 | if (*bss_done == 0){ |
19 | fprintf(output, "section .text\n\nglobal _start\n"); | 19 | fprintf(output, "globals: resq %d\n", nb_globals); |
20 | fprintf(output, "print: ;print needs an argument in rax\n"); | 20 | fprintf(output, "section .text\n\nglobal _start\n"); |
21 | fprintf(output, "push rbp\n"); | 21 | fprintf(output, "print: ;print needs an argument in rax\n"); |
22 | fprintf(output, "mov rbp, rsp\n"); | 22 | fprintf(output, "push rbp\n"); |
23 | fprintf(output, "push rsi\n"); | 23 | fprintf(output, "mov rbp, rsp\n"); |
24 | fprintf(output, "mov rsi, rax\n"); | 24 | fprintf(output, "push rsi\n"); |
25 | fprintf(output, "mov rdi, format_int\n"); | 25 | fprintf(output, "mov rsi, rax\n"); |
26 | fprintf(output, "mov rax, 0\n"); | 26 | fprintf(output, "mov rdi, format_int\n"); |
27 | fprintf(output, "call printf WRT ..plt\n"); | 27 | fprintf(output, "mov rax, 0\n"); |
28 | fprintf(output, "pop rsi\n"); | 28 | fprintf(output, "call printf WRT ..plt\n"); |
29 | fprintf(output, "pop rbp\n"); | 29 | fprintf(output, "pop rsi\n"); |
30 | fprintf(output, "ret\n"); | 30 | fprintf(output, "pop rbp\n"); |
31 | fprintf(output, "\n_start:\n"); | 31 | fprintf(output, "ret\n"); |
32 | fprintf(output, "push rbp\nmov rbp, rsp\n\n"); | 32 | fprintf(output, "\n_start:\n"); |
33 | fprintf(output, "push rbp\nmov rbp, rsp\n\n"); | ||
34 | *bss_done = 1; | ||
35 | } | ||
33 | } | 36 | } |
34 | void gen_const_declaration() { | 37 | void gen_const_declaration() { |
35 | fprintf(output, "mov rax,60 \n"); | 38 | fprintf(output, "mov rax,60 \n"); |
36 | fprintf(output, "mov rdi,0 \n"); | 39 | fprintf(output, "mov rdi,0 \n"); |
37 | fprintf(output, "syscall \n"); | 40 | fprintf(output, "syscall \n\n"); |
38 | fprintf(output, ";global table\n"); | 41 | fprintf(output, ";global table\n"); |
39 | glo_display_table(); | 42 | glo_display_table(); |
40 | fprintf(output, ";local table\n"); | 43 | fprintf(output, ";local table\n"); |
@@ -100,15 +103,20 @@ void gen_ifelse_end(int idx) { | |||
100 | // ----- OPERATORS ----- | 103 | // ----- OPERATORS ----- |
101 | 104 | ||
102 | int gen_assign(const char ident[], Scope scope) { | 105 | int gen_assign(const char ident[], Scope scope) { |
103 | const char instr_fmt[] = "pop QWORD [rbp - %d] ;%s\n"; | 106 | int g_addr = glo_get_addr(ident); |
104 | |||
105 | switch (scope) { | 107 | switch (scope) { |
106 | case GLOBAL: | 108 | case GLOBAL: |
107 | fprintf(output, instr_fmt, glo_get_addr(ident), ident); | 109 | fprintf(output, "pop QWORD [globals + %d] ;%s\n", glo_get_addr(ident), ident); |
108 | return glo_lookup(ident); | 110 | return glo_lookup(ident); |
109 | case LOCAL: | 111 | case LOCAL: |
110 | fprintf(output, instr_fmt, loc_get_addr(ident), ident); | 112 | if (g_addr == -1) { |
111 | return loc_lookup(ident); | 113 | fprintf(output, "pop QWORD [rbp - %d] ;%s\n", loc_get_addr(ident), ident); |
114 | return loc_lookup(ident); | ||
115 | } | ||
116 | else { | ||
117 | fprintf(output, "pop QWORD [globals + %d] ;%s\n", g_addr, ident); | ||
118 | return glo_lookup(ident); | ||
119 | } | ||
112 | default: | 120 | default: |
113 | exit(1); | 121 | exit(1); |
114 | } | 122 | } |
@@ -241,13 +249,20 @@ int gen_negate_expr(int type) { | |||
241 | } | 249 | } |
242 | 250 | ||
243 | int gen_value(const char ident[], Scope scope) { | 251 | int gen_value(const char ident[], Scope scope) { |
252 | int g_addr = glo_get_addr(ident); | ||
244 | switch (scope) { | 253 | switch (scope) { |
245 | case GLOBAL: | 254 | case GLOBAL: |
246 | fprintf(output, "push QWORD [rbp - %d] ;%s\n", glo_get_addr(ident), ident); | 255 | fprintf(output, "push QWORD [globals + %d] ;%s\n", glo_get_addr(ident), ident); |
247 | return glo_lookup(ident); | 256 | return glo_lookup(ident); |
248 | case LOCAL: | 257 | case LOCAL: |
249 | fprintf(output, "push QWORD [rbp - %d] ;%s\n", loc_get_addr(ident), ident); | 258 | if (g_addr == -1) { |
250 | return loc_lookup(ident); | 259 | fprintf(output, "push QWORD [rbp - %d] ;%s\n", loc_get_addr(ident), ident); |
260 | return loc_lookup(ident); | ||
261 | } | ||
262 | else { | ||
263 | fprintf(output, "push QWORD [globals + %d] ;%s\n", g_addr, ident); | ||
264 | return glo_lookup(ident); | ||
265 | } | ||
251 | default: | 266 | default: |
252 | exit(1); | 267 | exit(1); |
253 | } | 268 | } |