diff options
-rw-r--r-- | res/test_read.tpc | 15 | ||||
-rw-r--r-- | src/generator.c | 164 | ||||
-rw-r--r-- | src/generator.h | 7 | ||||
-rw-r--r-- | src/symbol_table.c | 2 | ||||
-rw-r--r-- | src/tpc.y | 10 |
5 files changed, 152 insertions, 46 deletions
diff --git a/res/test_read.tpc b/res/test_read.tpc new file mode 100644 index 0000000..a201223 --- /dev/null +++ b/res/test_read.tpc | |||
@@ -0,0 +1,15 @@ | |||
1 | /* test-table-symboles.tpc */ | ||
2 | |||
3 | /* Test file for simplified translator of a declaration of variables in C */ | ||
4 | entier r1,b,s,c,r2 ; | ||
5 | caractere letter, digit, punct; | ||
6 | |||
7 | void calcul(void) { | ||
8 | caractere r1; | ||
9 | readc(r1); | ||
10 | print(r1); | ||
11 | } | ||
12 | |||
13 | entier main(void) { | ||
14 | calcul(); | ||
15 | } | ||
diff --git a/src/generator.c b/src/generator.c index d44bbd1..0e79c07 100644 --- a/src/generator.c +++ b/src/generator.c | |||
@@ -9,23 +9,67 @@ | |||
9 | // ----- GLOBAL FUNCTIONS ----- | 9 | // ----- GLOBAL FUNCTIONS ----- |
10 | 10 | ||
11 | void gen_prologue() { | 11 | void gen_prologue() { |
12 | fprintf(output, "extern printf\n"); | 12 | fprintf(output, "extern printf\nextern scanf\n"); |
13 | fprintf(output, "section .data\n"); | 13 | fprintf(output, "section .data\n"); |
14 | fprintf(output, "format_int db \"%%d\",10,0\n\n"); | 14 | fprintf(output, "format_int db \"%%d\",10,0\n"); |
15 | fprintf(output, "format_char db \"%%c\",10,0\n"); | ||
16 | fprintf(output, "format_int_in: db \"%%d\", 0\n"); | ||
17 | fprintf(output, "format_char_in: db \"%%c\", 0\n\n"); | ||
15 | fprintf(output, "section .bss\n"); | 18 | fprintf(output, "section .bss\n"); |
16 | } | 19 | } |
17 | void gen_prologue_continue(int *bss_done){ | 20 | void gen_prologue_continue(int *bss_done) { |
18 | if (*bss_done == 0){ | 21 | if (*bss_done == 0) { |
19 | fprintf(output, "globals: resq %d\n", nb_globals); | 22 | fprintf(output, "globals: resq %d\n", nb_globals); |
20 | fprintf(output, "section .text\n\nglobal _start\n"); | 23 | fprintf(output, "section .text\n\nglobal _start\n"); |
21 | fprintf(output, "\nprint: ;print needs an argument in rax\n"); | 24 | fprintf(output, "\nprinte: ;print needs an argument in rax\n"); |
22 | fprintf(output, "push rbp\n"); | 25 | fprintf(output, "push rbp\n"); |
23 | fprintf(output, "mov rbp, rsp\n"); | 26 | fprintf(output, "mov rbp, rsp\n"); |
24 | fprintf(output, "push rsi\n"); | 27 | fprintf(output, "push rsi\n"); |
28 | fprintf(output, "push rdi\n"); | ||
25 | fprintf(output, "mov rsi, rax\n"); | 29 | fprintf(output, "mov rsi, rax\n"); |
26 | fprintf(output, "mov rdi, format_int\n"); | 30 | fprintf(output, "mov rdi, format_int\n"); |
27 | fprintf(output, "mov rax, 0\n"); | 31 | fprintf(output, "mov rax, 0\n"); |
28 | fprintf(output, "call printf WRT ..plt\n"); | 32 | fprintf(output, "call printf WRT ..plt\n"); |
33 | fprintf(output, "pop rdi\n"); | ||
34 | fprintf(output, "pop rsi\n"); | ||
35 | fprintf(output, "pop rbp\n"); | ||
36 | fprintf(output, "ret\n"); | ||
37 | fprintf(output, "\nprintc: ;print needs an argument in rax\n"); | ||
38 | fprintf(output, "push rbp\n"); | ||
39 | fprintf(output, "mov rbp, rsp\n"); | ||
40 | fprintf(output, "push rsi\n"); | ||
41 | fprintf(output, "push rdi\n"); | ||
42 | fprintf(output, "mov rsi, rax\n"); | ||
43 | fprintf(output, "mov rdi, format_char\n"); | ||
44 | fprintf(output, "mov rax, 0\n"); | ||
45 | fprintf(output, "call printf WRT ..plt\n"); | ||
46 | fprintf(output, "pop rdi\n"); | ||
47 | fprintf(output, "pop rsi\n"); | ||
48 | fprintf(output, "pop rbp\n"); | ||
49 | fprintf(output, "ret\n"); | ||
50 | fprintf(output, "\nreade: ;read needs an adress in rax\n"); | ||
51 | fprintf(output, "push rbp\n"); | ||
52 | fprintf(output, "mov rbp, rsp\n"); | ||
53 | fprintf(output, "push rsi\n"); | ||
54 | fprintf(output, "push rdi\n"); | ||
55 | fprintf(output, "mov rsi, rax\n"); | ||
56 | fprintf(output, "mov rdi, format_int_in\n"); | ||
57 | fprintf(output, "mov rax, 0\n"); | ||
58 | fprintf(output, "call scanf\n"); | ||
59 | fprintf(output, "pop rdi\n"); | ||
60 | fprintf(output, "pop rsi\n"); | ||
61 | fprintf(output, "pop rbp\n"); | ||
62 | fprintf(output, "ret\n"); | ||
63 | fprintf(output, "\nreadc: ;read needs an adress in rax\n"); | ||
64 | fprintf(output, "push rbp\n"); | ||
65 | fprintf(output, "mov rbp, rsp\n"); | ||
66 | fprintf(output, "push rsi\n"); | ||
67 | fprintf(output, "push rdi\n"); | ||
68 | fprintf(output, "mov rsi, rax\n"); | ||
69 | fprintf(output, "mov rdi, format_char_in\n"); | ||
70 | fprintf(output, "mov rax, 0\n"); | ||
71 | fprintf(output, "call scanf\n"); | ||
72 | fprintf(output, "pop rdi\n"); | ||
29 | fprintf(output, "pop rsi\n"); | 73 | fprintf(output, "pop rsi\n"); |
30 | fprintf(output, "pop rbp\n"); | 74 | fprintf(output, "pop rbp\n"); |
31 | fprintf(output, "ret\n"); | 75 | fprintf(output, "ret\n"); |
@@ -47,17 +91,18 @@ void gen_const_declaration() { | |||
47 | fun_display_table(); | 91 | fun_display_table(); |
48 | } | 92 | } |
49 | 93 | ||
50 | void gen_function_declaration(const char name[], int return_type, int nb_param){ | 94 | void gen_function_declaration(const char name[], int return_type, |
51 | fun_add(name,return_type,nb_param); | 95 | int nb_param) { |
52 | fprintf(output, "\n%s:\npush rbp\nmov rbp,rsp\n",name); | 96 | fun_add(name, return_type, nb_param); |
97 | fprintf(output, "\n%s:\npush rbp\nmov rbp,rsp\n", name); | ||
53 | } | 98 | } |
54 | 99 | ||
55 | void gen_function_end_declaration(){ | 100 | void gen_function_end_declaration() { |
56 | fprintf(output, "mov rsp, rbp\npop rbp\nret\n"); | 101 | fprintf(output, "mov rsp, rbp\npop rbp\nret\n"); |
57 | } | 102 | } |
58 | int gen_function_call(const char name[], int nb_param){ | 103 | int gen_function_call(const char name[], int nb_param) { |
59 | fprintf(output,"call %s\n",name); | 104 | fprintf(output, "call %s\n", name); |
60 | return fun_lookup(name,nb_param); | 105 | return fun_lookup(name, nb_param); |
61 | } | 106 | } |
62 | 107 | ||
63 | void gen_declaration(const char name[], int type, Scope scope) { | 108 | void gen_declaration(const char name[], int type, Scope scope) { |
@@ -71,12 +116,10 @@ void gen_declaration(const char name[], int type, Scope scope) { | |||
71 | fprintf(output, "push 0\n"); | 116 | fprintf(output, "push 0\n"); |
72 | break; | 117 | break; |
73 | } | 118 | } |
74 | |||
75 | } | 119 | } |
76 | 120 | ||
77 | // ----- READ AND PRINT FUNCTIONS ----- | 121 | // Verifies that the variable exists |
78 | 122 | void gen_check(const char name[], Scope scope) { | |
79 | void gen_read(const char name[], Scope scope) { | ||
80 | switch (scope) { | 123 | switch (scope) { |
81 | case GLOBAL: | 124 | case GLOBAL: |
82 | glo_lookup(name); | 125 | glo_lookup(name); |
@@ -87,9 +130,50 @@ void gen_read(const char name[], Scope scope) { | |||
87 | } | 130 | } |
88 | } | 131 | } |
89 | 132 | ||
90 | void gen_print() { | 133 | // ----- READ AND PRINT FUNCTIONS ----- |
134 | void gen_reade(const char name[]) { | ||
135 | if (loc_lookup(name) != INT) { | ||
136 | fprintf(stderr, "Need to be a INT in the reade() function\n"); | ||
137 | return; | ||
138 | } | ||
139 | int l_addr = loc_get_addr(name); | ||
140 | int g_addr = glo_get_addr(name); | ||
141 | if (l_addr != -1) { | ||
142 | fprintf(output, "mov rax,rbp\nsub rax,%d\ncall reade\n", | ||
143 | loc_get_addr(name)); | ||
144 | return; | ||
145 | } | ||
146 | fprintf(output, "mov rax,globals\nadd rax,%d\ncall reade\n", g_addr); | ||
147 | } | ||
148 | |||
149 | void gen_readc(const char name[]) { | ||
150 | if (loc_lookup(name) != CHAR) { | ||
151 | fprintf(stderr, "Need to be a CHAR in the readc() function\n"); | ||
152 | return; | ||
153 | } | ||
154 | int l_addr = loc_get_addr(name); | ||
155 | int g_addr = glo_get_addr(name); | ||
156 | if (l_addr != -1) { | ||
157 | fprintf(output, "mov rax,rbp\nsub rax,%d\ncall readc\n", | ||
158 | loc_get_addr(name)); | ||
159 | return; | ||
160 | } | ||
161 | fprintf(output, "mov rax,globals\nadd rax,%d\ncall readc\n", g_addr); | ||
162 | } | ||
163 | |||
164 | void gen_print(int type) { | ||
165 | //check if the name exists in both tables | ||
91 | fprintf(output, "pop rax\n"); | 166 | fprintf(output, "pop rax\n"); |
92 | fprintf(output, "call print\n"); | 167 | switch(type){ |
168 | case INT: | ||
169 | fprintf(output, "call printe\n"); | ||
170 | break; | ||
171 | case CHAR: | ||
172 | fprintf(output, "call printc\n"); | ||
173 | break; | ||
174 | default: fprintf(stderr, "Error print, supposed to have type CHAR or INT"); | ||
175 | } | ||
176 | |||
93 | } | 177 | } |
94 | 178 | ||
95 | // ----- CONDITIONAL BRANCHING ------ | 179 | // ----- CONDITIONAL BRANCHING ------ |
@@ -119,20 +203,21 @@ void gen_ifelse_end(int idx) { | |||
119 | // ----- OPERATORS ----- | 203 | // ----- OPERATORS ----- |
120 | 204 | ||
121 | int gen_assign(const char ident[], Scope scope) { | 205 | int gen_assign(const char ident[], Scope scope) { |
206 | int l_addr = loc_get_addr(ident); | ||
122 | int g_addr = glo_get_addr(ident); | 207 | int g_addr = glo_get_addr(ident); |
123 | switch (scope) { | 208 | switch (scope) { |
124 | case GLOBAL: | 209 | case GLOBAL: |
125 | fprintf(output, "pop QWORD [globals + %d] ;%s\n", glo_get_addr(ident), ident); | 210 | fprintf(output, "pop QWORD [globals + %d] ;%s\n", g_addr, |
211 | ident); | ||
126 | return glo_lookup(ident); | 212 | return glo_lookup(ident); |
127 | case LOCAL: | 213 | case LOCAL: |
128 | if (g_addr == -1) { | 214 | if (l_addr != -1) { |
129 | fprintf(output, "pop QWORD [rbp - %d] ;%s\n", loc_get_addr(ident), ident); | 215 | fprintf(output, "pop QWORD [rbp - %d] ;%s\n", l_addr, ident); |
130 | return loc_lookup(ident); | 216 | return loc_lookup(ident); |
131 | } | 217 | } else { |
132 | else { | ||
133 | fprintf(output, "pop QWORD [globals + %d] ;%s\n", g_addr, ident); | 218 | fprintf(output, "pop QWORD [globals + %d] ;%s\n", g_addr, ident); |
134 | return glo_lookup(ident); | 219 | return glo_lookup(ident); |
135 | } | 220 | } |
136 | default: | 221 | default: |
137 | exit(1); | 222 | exit(1); |
138 | } | 223 | } |
@@ -187,7 +272,8 @@ void gen_eq(const char op[], int left, int right, int idx) { | |||
187 | else | 272 | else |
188 | exit(1); // TODO: error on unexpected op | 273 | exit(1); // TODO: error on unexpected op |
189 | 274 | ||
190 | fprintf(output, "push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, idx); | 275 | fprintf(output, "push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, |
276 | idx); | ||
191 | } | 277 | } |
192 | 278 | ||
193 | void gen_order(const char op[], int left, int right, int idx) { | 279 | void gen_order(const char op[], int left, int right, int idx) { |
@@ -200,14 +286,15 @@ void gen_order(const char op[], int left, int right, int idx) { | |||
200 | fprintf(output, "jl .true%d\n", idx); | 286 | fprintf(output, "jl .true%d\n", idx); |
201 | else if (!strcmp(op, "<=")) | 287 | else if (!strcmp(op, "<=")) |