aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/ok_sample.tpc8
-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
7 files changed, 155 insertions, 53 deletions
diff --git a/res/ok_sample.tpc b/res/ok_sample.tpc
index 7b56e7f..e27e86a 100644
--- a/res/ok_sample.tpc
+++ b/res/ok_sample.tpc
@@ -6,19 +6,17 @@
6 6
7const special = 'b'; 7const special = 'b';
8 8
9caractere funky_func(entier arg) { 9entier funky_func(entier arg) {
10 return !arg; 10 return !arg;
11} 11}
12 12
13void main(void) { 13void main(void) {
14 caractere ret; 14 entier ret;
15 ret = 1 + funky_func(0) * 2; 15 ret = 1 + funky_func(0) * 2;
16 16
17 while (ret) { 17 while (ret) {
18 readc(ret); 18 reade(ret);
19 print(ret); 19 print(ret);
20
21 if (ret == special) print('!');
22 } 20 }
23} 21}
24 22
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