aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/generator.c161
-rw-r--r--src/generator.h22
-rw-r--r--src/tpc.y137
3 files changed, 214 insertions, 106 deletions
diff --git a/src/generator.c b/src/generator.c
index a7a7c72..004e559 100644
--- a/src/generator.c
+++ b/src/generator.c
@@ -7,7 +7,9 @@
7#include <stdio.h> 7#include <stdio.h>
8#include "symbol_table.h" 8#include "symbol_table.h"
9 9
10void prologue() { 10// ----- GLOBAL FUNCTIONS -----
11
12void gen_prologue() {
11 printf("extern printf\n"); 13 printf("extern printf\n");
12 printf("section .data\n"); 14 printf("section .data\n");
13 printf("format_int db \"%%d\",10,0\n\n"); 15 printf("format_int db \"%%d\",10,0\n\n");
@@ -27,7 +29,7 @@ void prologue() {
27 printf("push rbp\nmov rbp, rsp\n\n"); 29 printf("push rbp\nmov rbp, rsp\n\n");
28} 30}
29 31
30void const_declaration() { 32void gen_const_declaration() {
31 printf("mov rax,60 \n"); 33 printf("mov rax,60 \n");
32 printf("mov rdi,0 \n"); 34 printf("mov rdi,0 \n");
33 printf("syscall \n"); 35 printf("syscall \n");
@@ -37,7 +39,7 @@ void const_declaration() {
37 loc_display_table(); 39 loc_display_table();
38} 40}
39 41
40void declaration(const char name[], int type, Scope scope) { 42void gen_declaration(const char name[], int type, Scope scope) {
41 switch (scope) { 43 switch (scope) {
42 case GLOBAL: 44 case GLOBAL:
43 glo_addVar(name, type); 45 glo_addVar(name, type);
@@ -50,4 +52,157 @@ void declaration(const char name[], int type, Scope scope) {
50 printf("push 0\n"); 52 printf("push 0\n");
51} 53}
52 54
55// ----- READ AND PRINT FUNCTIONS -----
56
57void gen_read(const char name[], Scope scope) {
58 switch (scope) {
59 case GLOBAL:
60 glo_lookup(name);
61 break;
62 case LOCAL:
63 loc_lookup(name);
64 break;
65 }
66}
67
68void gen_print() {
69 printf("pop rax\n");
70 printf("call print\n");
71}
72
73// ----- CONDITIONAL BRANCHING ------
74
75void gen_if_label(int idx) {
76 printf(".end_if%d:\n", idx);
77 printf(";ENDIF\n\n");
78}
79
80void gen_if_start(int idx) {
81 printf("\n;BEGINIF\n");
82 printf("pop rax\n");
83 printf("cmp rax,0\n");
84 printf("jz .end_if%d\n", idx);
85}
86
87void gen_if_end(int idx) {
88 printf("jmp .end_ifelse%d\n", idx);
89 printf(".end_if%d:\n", idx);
90}
91
92void gen_ifelse_end(int idx) {
93 printf(".end_ifelse%d:\n", idx);
94 printf("ENDIF\n\n");
95}
96
97// ----- OPERATORS -----
98
99void gen_assign(int ident, Scope scope) {
100 // TODO: what's "$$" and how do we extract it?
101}
102
103void gen_or(int left, int right, int idx) {
104 check_expected_type(left, INT);
105 check_expected_type(right, INT);
106
107 printf(";a OR c\n");
108 printf("pop rax\n");
109 printf("cmp rax,1\n");
110 printf("je .true%d\n", idx);
111 printf("pop rcx\n");
112 printf("cmp rcx,1\n");
113 printf("jz .true%d\n", idx);
114 printf("push 0\n");
115 printf("jmp .false%d\n", idx);
116 printf(".true%d:\n", idx);
117 printf("push 1\n");
118 printf(".false%d:", idx);
119}
120
121void gen_and(int left, int right, int idx) {
122 check_expected_type(left, INT);
123 check_expected_type(right, INT);
124
125 printf(";a AND c\n");
126 printf("pop rax\n");
127 printf("cmp rax,0\n");
128 printf("jz .false%d\n", idx);
129 printf("pop rcx\n");
130 printf("cmp rcx,0\n");
131 printf("jz .false%d\n", idx);
132 printf("push 1\n");
133 printf("jmp .true%d\n", idx);
134 printf(".false%d:\n", idx);
135 printf("push 0\n");
136 printf(".true%d:", idx);
137}
138
139void gen_eq(const char op[], int left, int right, int idx) {
140 check_expected_type(left, INT);
141 check_expected_type(right, INT);
142
143 printf(";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n");
144
145 if (!strcmp(op, "=="))
146 printf("je .true%d\n", idx);
147 else if (!strcmp(op, "!="))
148 printf("jne .true%d\n", idx);
149 else
150 exit(1); // TODO: error on unexpected op
151
152 printf("push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, idx);
153}
154
155void gen_order(const char op[], int left, int right, int idx) {
156 check_expected_type(left, INT);
157 check_expected_type(right, INT);
158
159 printf(";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n");
160
161 if (!strcmp(op, "<"))
162 printf("jl .true%d\n", idx);
163 else if (!strcmp(op, "<="))
164 printf("jle .true%d\n", idx);
165 else if(!strcmp(op, ">"))
166 printf("jg .true%d\n", idx);
167 else if(!strcmp(op, "<="))
168 printf("jge .true%d\n", idx);
169 else
170 exit(1); // TODO: error on unexpected op
171
172 printf("push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, idx);
173}
174
175void gen_addsub(char op, int left, int right) {
176 check_expected_type(left, INT);
177 check_expected_type(right, INT);
178
179 switch (op) {
180 case '+':
181 printf(";E + T\npop rcx\npop rax\nadd rax,rcx\npush rax\n");
182 break;
183 case '-':
184 printf(";E - T\npop rcx\npop rax\nsub rax,rcx\npush rax\n");
185 break;
186 default:
187 exit(1);
188 }
189}
190
191void gen_divstar(char op, int left, int right) {
192 check_expected_type(left, INT);
193 check_expected_type(right, INT);
194
195 switch (op) {
196 case '*':
197 printf(";E * T\npop rax\npop rcx\nimul rax,rcx\npush rax\n");
198 break;
199 case '/':
200 case '%':
201 printf(";E / T\npop rax\npop rcx\nxor rdx,rdx\nidiv rcx\n");
202 printf("push %s\n", op == '/' ? "rax" : "rdx");
203 break;
204 default:
205 exit(1);
206 }
207}
53 208
diff --git a/src/generator.h b/src/generator.h
index 53acdef..17ea662 100644
--- a/src/generator.h
+++ b/src/generator.h
@@ -11,8 +11,24 @@ typedef enum scope {
11 LOCAL 11 LOCAL
12} Scope; 12} Scope;
13 13
14void prologue(); 14void gen_prologue();
15void const_declaration(); 15void gen_const_declaration();
16void declaration(const char name[], int type, Scope scope); 16void gen_declaration(const char name[], int type, Scope scope);
17
18void gen_read(const char name[], Scope scope);
19void gen_print();
20
21void gen_if_label(int idx);
22void gen_if_start(int idx);
23void gen_if_end(int idx);
24void gen_ifelse_end(int idx);
25
26void gen_assign(int ident, Scope scope);
27void gen_or(int left, int right, int idx);
28void gen_and(int left, int right, int idx);
29void gen_eq(const char op[], int left, int right, int idx);
30void gen_order(const char op[], int left, int right, int idx);
31void gen_addsub(char op, int left, int right);
32void gen_divstar(char op, int left, int right);
17 33
18#endif 34#endif
diff --git a/src/tpc.y b/src/tpc.y
index 14f3488..12ff20d 100644
--- a/src/tpc.y
+++ b/src/tpc.y
@@ -49,8 +49,8 @@ static int num_if = 0;
49%precedence ELSE 49%precedence ELSE
50 50
51%% 51%%
52Prog: { prologue(); } 52Prog: { gen_prologue(); }
53 DeclConsts DeclVars DeclFoncts { const_declaration(); } 53 DeclConsts DeclVars DeclFoncts { gen_const_declaration(); }
54 ; 54 ;
55DeclConsts: 55DeclConsts:
56 DeclConsts CONST ListConst ';' 56 DeclConsts CONST ListConst ';'
@@ -73,8 +73,8 @@ DeclVars:
73 | 73 |
74 ; 74 ;
75Declarateurs: 75Declarateurs:
76 Declarateurs ',' Declarateur { declaration($<ident>3, $<type>0, scope); } 76 Declarateurs ',' Declarateur { gen_declaration($<ident>3, $<type>0, scope); }
77 | Declarateur { declaration($<ident>1, $<type>0, scope); } 77 | Declarateur { gen_declaration($<ident>1, $<type>0, scope); }
78 ; 78 ;
79Declarateur: 79Declarateur:
80 IDENT 80 IDENT
@@ -97,39 +97,34 @@ Parametres:
97 | ListTypVar 97 | ListTypVar
98 ; 98 ;
99ListTypVar: 99ListTypVar:
100 ListTypVar ',' TYPE IDENT { declaration($<ident>4, $<type>3, scope); } 100 ListTypVar ',' TYPE IDENT { gen_declaration($<ident>4, $<type>3, scope); }
101 | TYPE IDENT { declaration($<ident>2, $<type>1, scope); } 101 | TYPE IDENT {