diff options
Diffstat (limited to 'src/generator.c')
-rw-r--r-- | src/generator.c | 171 |
1 files changed, 85 insertions, 86 deletions
diff --git a/src/generator.c b/src/generator.c index 88f32d7..8329aee 100644 --- a/src/generator.c +++ b/src/generator.c | |||
@@ -4,41 +4,40 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "generator.h" | 6 | #include "generator.h" |
7 | #include <stdio.h> | ||
8 | #include "symbol_table.h" | 7 | #include "symbol_table.h" |
9 | 8 | ||
10 | // ----- GLOBAL FUNCTIONS ----- | 9 | // ----- GLOBAL FUNCTIONS ----- |
11 | 10 | ||
12 | void gen_prologue() { | 11 | void gen_prologue() { |
13 | printf("extern printf\n"); | 12 | fprintf(output, "extern printf\n"); |
14 | printf("section .data\n"); | 13 | fprintf(output, "section .data\n"); |
15 | printf("format_int db \"%%d\",10,0\n\n"); | 14 | fprintf(output, "format_int db \"%%d\",10,0\n\n"); |
16 | printf("section .bss\n"); | 15 | fprintf(output, "section .bss\n"); |
17 | } | 16 | } |
18 | void gen_prologue_continue(){ | 17 | void gen_prologue_continue(){ |
19 | printf("globals: resq %d\n", nb_globals); | 18 | fprintf(output, "globals: resq %d\n", nb_globals); |
20 | printf("section .text\n\nglobal _start\n"); | 19 | fprintf(output, "section .text\n\nglobal _start\n"); |
21 | printf("print: ;print needs an argument in rax\n"); | 20 | fprintf(output, "print: ;print needs an argument in rax\n"); |
22 | printf("push rbp\n"); | 21 | fprintf(output, "push rbp\n"); |
23 | printf("mov rbp, rsp\n"); | 22 | fprintf(output, "mov rbp, rsp\n"); |
24 | printf("push rsi\n"); | 23 | fprintf(output, "push rsi\n"); |
25 | printf("mov rsi, rax\n"); | 24 | fprintf(output, "mov rsi, rax\n"); |
26 | printf("mov rdi, format_int\n"); | 25 | fprintf(output, "mov rdi, format_int\n"); |
27 | printf("mov rax, 0\n"); | 26 | fprintf(output, "mov rax, 0\n"); |
28 | printf("call printf WRT ..plt\n"); | 27 | fprintf(output, "call printf WRT ..plt\n"); |
29 | printf("pop rsi\n"); | 28 | fprintf(output, "pop rsi\n"); |
30 | printf("pop rbp\n"); | 29 | fprintf(output, "pop rbp\n"); |
31 | printf("ret\n"); | 30 | fprintf(output, "ret\n"); |
32 | printf("\n_start:\n"); | 31 | fprintf(output, "\n_start:\n"); |
33 | printf("push rbp\nmov rbp, rsp\n\n"); | 32 | fprintf(output, "push rbp\nmov rbp, rsp\n\n"); |
34 | } | 33 | } |
35 | void gen_const_declaration() { | 34 | void gen_const_declaration() { |
36 | printf("mov rax,60 \n"); | 35 | fprintf(output, "mov rax,60 \n"); |
37 | printf("mov rdi,0 \n"); | 36 | fprintf(output, "mov rdi,0 \n"); |
38 | printf("syscall \n"); | 37 | fprintf(output, "syscall \n"); |
39 | printf(";global table\n"); | 38 | fprintf(output, ";global table\n"); |
40 | glo_display_table(); | 39 | glo_display_table(); |
41 | printf(";local table\n"); | 40 | fprintf(output, ";local table\n"); |
42 | loc_display_table(); | 41 | loc_display_table(); |
43 | } | 42 | } |
44 | 43 | ||
@@ -50,7 +49,7 @@ void gen_declaration(const char name[], int type, Scope scope) { | |||
50 | break; | 49 | break; |
51 | case LOCAL: | 50 | case LOCAL: |
52 | loc_addVar(name, type); | 51 | loc_addVar(name, type); |
53 | printf("push 0\n"); | 52 | fprintf(output, "push 0\n"); |
54 | break; | 53 | break; |
55 | } | 54 | } |
56 | 55 | ||
@@ -70,32 +69,32 @@ void gen_read(const char name[], Scope scope) { | |||
70 | } | 69 | } |
71 | 70 | ||
72 | void gen_print() { | 71 | void gen_print() { |
73 | printf("pop rax\n"); | 72 | fprintf(output, "pop rax\n"); |
74 | printf("call print\n"); | 73 | fprintf(output, "call print\n"); |
75 | } | 74 | } |
76 | 75 | ||
77 | // ----- CONDITIONAL BRANCHING ------ | 76 | // ----- CONDITIONAL BRANCHING ------ |
78 | 77 | ||
79 | void gen_if_label(int idx) { | 78 | void gen_if_label(int idx) { |
80 | printf(".end_if%d:\n", idx); | 79 | fprintf(output, ".end_if%d:\n", idx); |
81 | printf(";ENDIF\n\n"); | 80 | fprintf(output, ";ENDIF\n\n"); |
82 | } | 81 | } |
83 | 82 | ||
84 | void gen_if_start(int idx) { | 83 | void gen_if_start(int idx) { |
85 | printf("\n;BEGINIF\n"); | 84 | fprintf(output, "\n;BEGINIF\n"); |
86 | printf("pop rax\n"); | 85 | fprintf(output, "pop rax\n"); |
87 | printf("cmp rax,0\n"); | 86 | fprintf(output, "cmp rax,0\n"); |
88 | printf("jz .end_if%d\n", idx); | 87 | fprintf(output, "jz .end_if%d\n", idx); |
89 | } | 88 | } |
90 | 89 | ||
91 | void gen_if_end(int idx) { | 90 | void gen_if_end(int idx) { |
92 | printf("jmp .end_ifelse%d\n", idx); | 91 | fprintf(output, "jmp .end_ifelse%d\n", idx); |
93 | printf(".end_if%d:\n", idx); | 92 | fprintf(output, ".end_if%d:\n", idx); |
94 | } | 93 | } |
95 | 94 | ||
96 | void gen_ifelse_end(int idx) { | 95 | void gen_ifelse_end(int idx) { |
97 | printf(".end_ifelse%d:\n", idx); | 96 | fprintf(output, ".end_ifelse%d:\n", idx); |
98 | printf("ENDIF\n\n"); | 97 | fprintf(output, "ENDIF\n\n"); |
99 | } | 98 | } |
100 | 99 | ||
101 | // ----- OPERATORS ----- | 100 | // ----- OPERATORS ----- |
@@ -105,10 +104,10 @@ int gen_assign(const char ident[], Scope scope) { | |||
105 | 104 | ||
106 | switch (scope) { | 105 | switch (scope) { |
107 | case GLOBAL: | 106 | case GLOBAL: |
108 | printf(instr_fmt, glo_get_addr(ident), ident); | 107 | fprintf(output, instr_fmt, glo_get_addr(ident), ident); |
109 | return glo_lookup(ident); | 108 | return glo_lookup(ident); |
110 | case LOCAL: | 109 | case LOCAL: |
111 | printf(instr_fmt, loc_get_addr(ident), ident); | 110 | fprintf(output, instr_fmt, loc_get_addr(ident), ident); |
112 | return loc_lookup(ident); | 111 | return loc_lookup(ident); |
113 | default: | 112 | default: |
114 | exit(1); | 113 | exit(1); |
@@ -119,72 +118,72 @@ void gen_or(int left, int right, int idx) { | |||
119 | check_expected_type(left, INT); | 118 | check_expected_type(left, INT); |
120 | check_expected_type(right, INT); | 119 | check_expected_type(right, INT); |
121 | 120 | ||
122 | printf(";a OR c\n"); | 121 | fprintf(output, ";a OR c\n"); |
123 | printf("pop rax\n"); | 122 | fprintf(output, "pop rax\n"); |
124 | printf("cmp rax,1\n"); | 123 | fprintf(output, "cmp rax,1\n"); |
125 | printf("je .true%d\n", idx); | 124 | fprintf(output, "je .true%d\n", idx); |
126 | printf("pop rcx\n"); | 125 | fprintf(output, "pop rcx\n"); |
127 | printf("cmp rcx,1\n"); | 126 | fprintf(output, "cmp rcx,1\n"); |
128 | printf("jz .true%d\n", idx); | 127 | fprintf(output, "jz .true%d\n", idx); |
129 | printf("push 0\n"); | 128 | fprintf(output, "push 0\n"); |
130 | printf("jmp .false%d\n", idx); | 129 | fprintf(output, "jmp .false%d\n", idx); |
131 | printf(".true%d:\n", idx); | 130 | fprintf(output, ".true%d:\n", idx); |
132 | printf("push 1\n"); | 131 | fprintf(output, "push 1\n"); |
133 | printf(".false%d:", idx); | 132 | fprintf(output, ".false%d:", idx); |
134 | } | 133 | } |
135 | 134 | ||
136 | void gen_and(int left, int right, int idx) { | 135 | void gen_and(int left, int right, int idx) { |
137 | check_expected_type(left, INT); | 136 | check_expected_type(left, INT); |
138 | check_expected_type(right, INT); | 137 | check_expected_type(right, INT); |
139 | 138 | ||
140 | printf(";a AND c\n"); | 139 | fprintf(output, ";a AND c\n"); |
141 | printf("pop rax\n"); | 140 | fprintf(output, "pop rax\n"); |
142 | printf("cmp rax,0\n"); | 141 | fprintf(output, "cmp rax,0\n"); |
143 | printf("jz .false%d\n", idx); | 142 | fprintf(output, "jz .false%d\n", idx); |
144 | printf("pop rcx\n"); | 143 | fprintf(output, "pop rcx\n"); |
145 | printf("cmp rcx,0\n"); | 144 | fprintf(output, "cmp rcx,0\n"); |
146 | printf("jz .false%d\n", idx); | 145 | fprintf(output, "jz .false%d\n", idx); |
147 | printf("push 1\n"); | 146 | fprintf(output, "push 1\n"); |
148 | printf("jmp .true%d\n", idx); | 147 | fprintf(output, "jmp .true%d\n", idx); |
149 | printf(".false%d:\n", idx); | 148 | fprintf(output, ".false%d:\n", idx); |
150 | printf("push 0\n"); | 149 | fprintf(output, "push 0\n"); |
151 | printf(".true%d:", idx); | 150 | fprintf(output, ".true%d:", idx); |
152 | } | 151 | } |
153 | 152 | ||
154 | void gen_eq(const char op[], int left, int right, int idx) { | 153 | void gen_eq(const char op[], int left, int right, int idx) { |
155 | check_expected_type(left, INT); | 154 | check_expected_type(left, INT); |
156 | check_expected_type(right, INT); | 155 | check_expected_type(right, INT); |
157 | 156 | ||
158 | printf(";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n"); | 157 | fprintf(output, ";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n"); |
159 | 158 | ||
160 | if (!strcmp(op, "==")) | 159 | if (!strcmp(op, "==")) |
161 | printf("je .true%d\n", idx); | 160 | fprintf(output, "je .true%d\n", idx); |
162 | else if (!strcmp(op, "!=")) | 161 | else if (!strcmp(op, "!=")) |
163 | printf("jne .true%d\n", idx); | 162 | fprintf(output, "jne .true%d\n", idx); |
164 | else | 163 | else |
165 | exit(1); // TODO: error on unexpected op | 164 | exit(1); // TODO: error on unexpected op |
166 | 165 | ||
167 | printf("push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, idx); | 166 | fprintf(output, "push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, idx); |
168 | } | 167 | } |
169 | 168 | ||
170 | void gen_order(const char op[], int left, int right, int idx) { | 169 | void gen_order(const char op[], int left, int right, int idx) { |
171 | check_expected_type(left, INT); | 170 | check_expected_type(left, INT); |
172 | check_expected_type(right, INT); | 171 | check_expected_type(right, INT); |
173 | 172 | ||
174 | printf(";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n"); | 173 | fprintf(output, ";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n"); |
175 | 174 | ||
176 | if (!strcmp(op, "<")) | 175 | if (!strcmp(op, "<")) |
177 | printf("jl .true%d\n", idx); | 176 | fprintf(output, "jl .true%d\n", idx); |
178 | else if (!strcmp(op, "<=")) | 177 | else if (!strcmp(op, "<=")) |
179 | printf("jle .true%d\n", idx); | 178 | fprintf(output, "jle .true%d\n", idx); |
180 | else if(!strcmp(op, ">")) | 179 | else if(!strcmp(op, ">")) |
181 | printf("jg .true%d\n", idx); | 180 | fprintf(output, "jg .true%d\n", idx); |
182 | else if(!strcmp(op, "<=")) | 181 | else if(!strcmp(op, "<=")) |
183 | printf("jge .true%d\n", idx); | 182 | fprintf(output, "jge .true%d\n", idx); |
184 | else | 183 | else |
185 | exit(1); // TODO: error on unexpected op | 184 | exit(1); // TODO: error on unexpected op |
186 | 185 | ||
187 | printf("push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, idx); | 186 | fprintf(output, "push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, idx); |