aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/test_array.tpc10
-rw-r--r--src/generator.c146
-rw-r--r--src/generator.h5
-rw-r--r--src/symbol_table.c10
-rw-r--r--src/symbol_table.h6
-rw-r--r--src/tpc.y23
6 files changed, 152 insertions, 48 deletions
diff --git a/res/test_array.tpc b/res/test_array.tpc
new file mode 100644
index 0000000..a968c22
--- /dev/null
+++ b/res/test_array.tpc
@@ -0,0 +1,10 @@
1entier tab[5];
2
3entier main(void) {
4 tab[1]=3;
5 tab[2]=22;
6 print(tab[2]+tab[1]);
7 print(tab[1]);
8 print(tab[2]);
9 return 0;
10}
diff --git a/src/generator.c b/src/generator.c
index ab3777c..5c51d3b 100644
--- a/src/generator.c
+++ b/src/generator.c
@@ -13,7 +13,8 @@ void gen_prologue() {
13} 13}
14 14
15void gen_prologue_continue(int *bss_done) { 15void gen_prologue_continue(int *bss_done) {
16 if (*bss_done != 0) return; 16 if (*bss_done != 0)
17 return;
17 18
18 fprintf(output, "format_int db \"%%d\",10,0\n"); 19 fprintf(output, "format_int db \"%%d\",10,0\n");
19 fprintf(output, "format_char db \"%%c\",10,0\n"); 20 fprintf(output, "format_char db \"%%c\",10,0\n");
@@ -112,9 +113,10 @@ Type gen_function_declaration(const char name[], int return_type) {
112 return return_type; 113 return return_type;
113} 114}
114 115
115void gen_function_end_declaration(const char name[], int return_type, int nb_param) { 116void gen_function_end_declaration(const char name[], int return_type,
117 int nb_param) {
116 fun_add(name, return_type, nb_param); 118 fun_add(name, return_type, nb_param);
117 fprintf(output, "mov rax,-1\nmov rsp, rbp\npop rbp\nret\n"); 119 fprintf(output, "mov rax,-1\nmov rsp, rbp\npop rbp\nret\n");
118} 120}
119 121
120void gen_function_return(Type expect, Type actual) { 122void gen_function_return(Type expect, Type actual) {
@@ -122,14 +124,16 @@ void gen_function_return(Type expect, Type actual) {
122 fprintf(stderr, "Return type mismatch at line %d.", lineno); 124 fprintf(stderr, "Return type mismatch at line %d.", lineno);
123 exit(1); 125 exit(1);
124 } 126 }
125 if (actual != VOID_T) fprintf(output, "pop rax\n"); 127 if (actual != VOID_T)
128 fprintf(output, "pop rax\n");
126 fprintf(output, "mov rsp, rbp\npop rbp\nret\n"); 129 fprintf(output, "mov rsp, rbp\npop rbp\nret\n");
127} 130}
128 131
129Type gen_function_call(const char name[], int nb_param) { 132Type gen_function_call(const char name[], int nb_param) {
130 Type return_type = fun_lookup(name, nb_param); 133 Type return_type = fun_lookup(name, nb_param);
131 fprintf(output, "call %s\n", name); 134 fprintf(output, "call %s\n", name);
132 if (return_type != VOID_T) fprintf(output, "push rax\n"); 135 if (return_type != VOID_T)
136 fprintf(output, "push rax\n");
133 return return_type; 137 return return_type;
134} 138}
135 139
@@ -146,6 +150,21 @@ void gen_declaration(const char name[], int type, Scope scope) {
146 } 150 }
147} 151}
148 152
153void gen_tab_declaration(const char name[], Scope scope, int size) {
154 switch (scope) {
155 case GLOBAL:
156 glo_addVar(name, TAB);
157 nb_globals = nb_globals + size;
158 break;
159 case LOCAL:
160 loc_addVar(name, TAB);
161 for (int i = 0; i < size; ++i) {
162 fprintf(output, "push 0\n");
163 }
164 break;
165 }
166}
167
149// Verifies that the variable exists 168// Verifies that the variable exists
150void gen_check(const char name[], Scope scope) { 169void gen_check(const char name[], Scope scope) {
151 switch (scope) { 170 switch (scope) {
@@ -161,8 +180,8 @@ void gen_check(const char name[], Scope scope) {
161// ----- READ AND PRINT FUNCTIONS ----- 180// ----- READ AND PRINT FUNCTIONS -----
162void gen_reade(const char name[], Scope scope) { 181void gen_reade(const char name[], Scope scope) {
163 if (is_read_only(name, scope)) { 182 if (is_read_only(name, scope)) {
164 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, lineno); 183 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, lineno);
165 exit(1); 184 exit(1);
166 } 185 }
167 186
168 if (loc_lookup(name) != INT) { 187 if (loc_lookup(name) != INT) {
@@ -181,8 +200,8 @@ void gen_reade(const char name[], Scope scope) {
181 200
182void gen_readc(const char name[], Scope scope) { 201void gen_readc(const char name[], Scope scope) {
183 if (is_read_only(name, scope)) { 202 if (is_read_only(name, scope)) {
184 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, lineno); 203 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, lineno);
185 exit(1); 204 exit(1);
186 } 205 }
187 206
188 if (loc_lookup(name) != CHAR) { 207 if (loc_lookup(name) != CHAR) {
@@ -200,18 +219,21 @@ void gen_readc(const char name[], Scope scope) {
200} 219}
201 220
202void gen_print(int type) { 221void gen_print(int type) {
203 //check if the name exists in both tables 222 // check if the name exists in both tables
204 fprintf(output, "pop rax\n"); 223 fprintf(output, "pop rax\n");
205 switch(type){ 224 switch (type) {
206 case INT: 225 case INT:
207 fprintf(output, "call printe\n"); 226 fprintf(output, "call printe\n");
227 break;
228 case CHAR:
229 fprintf(output, "call printc\n");
208 break; 230 break;
209 case CHAR: 231 case TAB:
210 fprintf(output, "call printc\n"); 232 fprintf(output, "call printe\n");
211 break; 233 break;
212 default: fprintf(stderr, "Error print, supposed to have type CHAR or INT\n"); 234 default:
235 fprintf(stderr, "Error print, supposed to have type CHAR or INT or TAB\n");
213 } 236 }
214
215} 237}
216 238
217// ----- CONDITIONAL BRANCHING ------ 239// ----- CONDITIONAL BRANCHING ------
@@ -245,14 +267,13 @@ int gen_assign(const char ident[], Scope scope) {
245 int g_addr = glo_get_addr(ident); 267 int g_addr = glo_get_addr(ident);
246 268
247 if (is_read_only(ident, scope)) { 269 if (is_read_only(ident, scope)) {
248 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", ident, lineno); 270 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", ident, lineno);
249 exit(1); 271 exit(1);
250 } 272 }
251 273
252 switch (scope) { 274 switch (scope) {
253 case GLOBAL: 275 case GLOBAL:
254 fprintf(output, "pop QWORD [globals + %d] ;%s\n", g_addr, 276 fprintf(output, "pop QWORD [globals + %d] ;%s\n", g_addr, ident);
255 ident);
256 return glo_lookup(ident); 277 return glo_lookup(ident);
257 case LOCAL: 278 case LOCAL:
258 if (l_addr != -1) { 279 if (l_addr != -1) {
@@ -267,9 +288,35 @@ int gen_assign(const char ident[], Scope scope) {
267 } 288 }
268} 289}
269 290
291int gen_assign_tab(const char ident[], Scope scope) {
292 int l_addr = loc_get_addr(ident);
293 int g_addr = glo_get_addr(ident);
294
295 if (is_read_only(ident, scope)) {
296 fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", ident, lineno);
297 exit(1);
298 }
299
300 switch (scope) {
301 case GLOBAL:
302 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);
303 return glo_lookup(ident);
304 case LOCAL:
305 if (l_addr != -1) {
306 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);
307 return loc_lookup(ident);
308 } else {
309 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);
310 return glo_lookup(ident);
311 }
312 default:
313 exit(1);
314 }
315}
316
270void gen_or(int left, int right, int idx) { 317void gen_or(int left, int right, int idx) {
271 check_expected_type(left, INT); 318 check_expected_types(left, INT,TAB);
272 check_expected_type(right, INT); 319 check_expected_types(right, INT,TAB);
273 320
274 fprintf(output, ";a OR c\n"); 321 fprintf(output, ";a OR c\n");
275 fprintf(output, "pop rax\n"); 322 fprintf(output, "pop rax\n");
@@ -286,8 +333,8 @@ void gen_or(int left, int right, int idx) {
286} 333}
287 334
288void gen_and(int left, int right, int idx) { 335void gen_and(int left, int right, int idx) {
289 check_expected_type(left, INT); 336 check_expected_types(left, INT,TAB);
290 check_expected_type(right, INT); 337 check_expected_types(right, INT,TAB);
291 338
292 fprintf(output, ";a AND c\n"); 339 fprintf(output, ";a AND c\n");
293 fprintf(output, "pop rax\n"); 340 fprintf(output, "pop rax\n");
@@ -304,8 +351,8 @@ void gen_and(int left, int right, int idx) {
304} 351}
305 352
306void gen_eq(const char op[], int left, int right, int idx) { 353void gen_eq(const char op[], int left, int right, int idx) {
307 check_expected_type(left, INT); 354 check_expected_types(left, INT,TAB);
308 check_expected_type(right, INT); 355 check_expected_types(right, INT,TAB);
309 356
310 fprintf(output, ";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n"); 357 fprintf(output, ";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n");
311 358
@@ -316,13 +363,13 @@ void gen_eq(const char op[], int left, int right, int idx) {
316 else 363 else
317 exit(1); // TODO: error on unexpected op 364 exit(1); // TODO: error on unexpected op
318 365
319 fprintf(output, "push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:\n", idx, idx, 366 fprintf(output, "push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:\n", idx,
320 idx); 367 idx, idx);
321} 368}
322 369
323void gen_order(const char op[], int left, int right, int idx) { 370void gen_order(const char op[], int left, int right, int idx) {
324 check_expected_type(left, INT); 371 check_expected_types(left, INT,TAB);
325 check_expected_type(right, INT); 372 check_expected_types(right, INT,TAB);
326 373