diff options
author | pacien | 2018-05-07 14:44:11 +0200 |
---|---|---|
committer | pacien | 2018-05-07 14:44:11 +0200 |
commit | 008d12251620366c3972c8884a33c63ddf4843ba (patch) | |
tree | 2f6b974e36742ec1048bcc0a72ea03f3d5f45d47 | |
parent | 91468b81ccad51eb3f8c0fbc90270a893ff040a9 (diff) | |
download | tpc-compiler-008d12251620366c3972c8884a33c63ddf4843ba.tar.gz |
Extract generator functions (partial commit pt2)
-rw-r--r-- | src/generator.c | 161 | ||||
-rw-r--r-- | src/generator.h | 22 | ||||
-rw-r--r-- | src/tpc.y | 137 |
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 | ||
10 | void prologue() { | 10 | // ----- GLOBAL FUNCTIONS ----- |
11 | |||
12 | void 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 | ||
30 | void const_declaration() { | 32 | void 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 | ||
40 | void declaration(const char name[], int type, Scope scope) { | 42 | void 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 | |||
57 | void 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 | |||
68 | void gen_print() { | ||
69 | printf("pop rax\n"); | ||
70 | printf("call print\n"); | ||
71 | } | ||
72 | |||
73 | // ----- CONDITIONAL BRANCHING ------ | ||
74 | |||
75 | void gen_if_label(int idx) { | ||
76 | printf(".end_if%d:\n", idx); | ||
77 | printf(";ENDIF\n\n"); | ||
78 | } | ||
79 | |||
80 | void 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 | |||
87 | void gen_if_end(int idx) { | ||
88 | printf("jmp .end_ifelse%d\n", idx); | ||
89 | printf(".end_if%d:\n", idx); | ||
90 | } | ||
91 | |||
92 | void gen_ifelse_end(int idx) { | ||
93 | printf(".end_ifelse%d:\n", idx); | ||
94 | printf("ENDIF\n\n"); | ||
95 | } | ||
96 | |||
97 | // ----- OPERATORS ----- | ||
98 | |||
99 | void gen_assign(int ident, Scope scope) { | ||
100 | // TODO: what's "$$" and how do we extract it? | ||
101 | } | ||
102 | |||
103 | void 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 | |||
121 | void 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 | |||
139 | void 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 | |||
155 | void 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 | |||
175 | void 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 | |||
191 | void 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 | ||
14 | void prologue(); | 14 | void gen_prologue(); |
15 | void const_declaration(); | 15 | void gen_const_declaration(); |
16 | void declaration(const char name[], int type, Scope scope); | 16 | void gen_declaration(const char name[], int type, Scope scope); |
17 | |||
18 | void gen_read(const char name[], Scope scope); | ||
19 | void gen_print(); | ||
20 | |||
21 | void gen_if_label(int idx); | ||
22 | void gen_if_start(int idx); | ||
23 | void gen_if_end(int idx); | ||
24 | void gen_ifelse_end(int idx); | ||
25 | |||
26 | void gen_assign(int ident, Scope scope); | ||
27 | void gen_or(int left, int right, int idx); | ||
28 | void gen_and(int left, int right, int idx); | ||
29 | void gen_eq(const char op[], int left, int right, int idx); | ||
30 | void gen_order(const char op[], int left, int right, int idx); | ||
31 | void gen_addsub(char op, int left, int right); | ||
32 | void gen_divstar(char op, int left, int right); | ||
17 | 33 | ||
18 | #endif | 34 | #endif |
@@ -49,8 +49,8 @@ static int num_if = 0; | |||
49 | %precedence ELSE | 49 | %precedence ELSE |
50 | 50 | ||
51 | %% | 51 | %% |
52 | Prog: { prologue(); } | 52 | Prog: { gen_prologue(); } |
53 | DeclConsts DeclVars DeclFoncts { const_declaration(); } | 53 | DeclConsts DeclVars DeclFoncts { gen_const_declaration(); } |
54 | ; | 54 | ; |
55 | DeclConsts: | 55 | DeclConsts: |
56 | DeclConsts CONST ListConst ';' | 56 | DeclConsts CONST ListConst ';' |
@@ -73,8 +73,8 @@ DeclVars: | |||
73 | | | 73 | | |
74 | ; | 74 | ; |
75 | Declarateurs: | 75 | Declarateurs: |
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 | ; |
79 | Declarateur: | 79 | Declarateur: |
80 | IDENT | 80 | IDENT |
@@ -97,39 +97,34 @@ Parametres: | |||
97 | | ListTypVar | 97 | | ListTypVar |
98 | ; | 98 | ; |
99 | ListTypVar: | 99 | ListTypVar: |