aboutsummaryrefslogtreecommitdiff
path: root/src/generator.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/generator.c')
-rw-r--r--src/generator.c171
1 files changed, 85 insertions, 86 deletions
diff --git a/src/generator.c b/src/generator.c
index 88f32d7..8329aee 100644
--- a/src/generator.c
+++ b/src/generator.c
@@ -4,41 +4,40 @@
4 */ 4 */
5 5
6#include "generator.h" 6#include "generator.h"
7#include <stdio.h>
8#include "symbol_table.h" 7#include "symbol_table.h"
9 8
10// ----- GLOBAL FUNCTIONS ----- 9// ----- GLOBAL FUNCTIONS -----
11 10
12void gen_prologue() { 11void gen_prologue() {
13 printf("extern printf\n"); 12 fprintf(output, "extern printf\n");
14 printf("section .data\n"); 13 fprintf(output, "section .data\n");
15 printf("format_int db \"%%d\",10,0\n\n"); 14 fprintf(output, "format_int db \"%%d\",10,0\n\n");
16 printf("section .bss\n"); 15 fprintf(output, "section .bss\n");
17} 16}
18void gen_prologue_continue(){ 17void gen_prologue_continue(){
19 printf("globals: resq %d\n", nb_globals); 18 fprintf(output, "globals: resq %d\n", nb_globals);
20 printf("section .text\n\nglobal _start\n"); 19 fprintf(output, "section .text\n\nglobal _start\n");
21 printf("print: ;print needs an argument in rax\n"); 20 fprintf(output, "print: ;print needs an argument in rax\n");
22 printf("push rbp\n"); 21 fprintf(output, "push rbp\n");
23 printf("mov rbp, rsp\n"); 22 fprintf(output, "mov rbp, rsp\n");
24 printf("push rsi\n"); 23 fprintf(output, "push rsi\n");
25 printf("mov rsi, rax\n"); 24 fprintf(output, "mov rsi, rax\n");
26 printf("mov rdi, format_int\n"); 25 fprintf(output, "mov rdi, format_int\n");
27 printf("mov rax, 0\n"); 26 fprintf(output, "mov rax, 0\n");
28 printf("call printf WRT ..plt\n"); 27 fprintf(output, "call printf WRT ..plt\n");
29 printf("pop rsi\n"); 28 fprintf(output, "pop rsi\n");
30 printf("pop rbp\n"); 29 fprintf(output, "pop rbp\n");
31 printf("ret\n"); 30 fprintf(output, "ret\n");
32 printf("\n_start:\n"); 31 fprintf(output, "\n_start:\n");
33 printf("push rbp\nmov rbp, rsp\n\n"); 32 fprintf(output, "push rbp\nmov rbp, rsp\n\n");
34} 33}
35void gen_const_declaration() { 34void gen_const_declaration() {
36 printf("mov rax,60 \n"); 35 fprintf(output, "mov rax,60 \n");
37 printf("mov rdi,0 \n"); 36 fprintf(output, "mov rdi,0 \n");
38 printf("syscall \n"); 37 fprintf(output, "syscall \n");
39 printf(";global table\n"); 38 fprintf(output, ";global table\n");
40 glo_display_table(); 39 glo_display_table();
41 printf(";local table\n"); 40 fprintf(output, ";local table\n");
42 loc_display_table(); 41 loc_display_table();
43} 42}
44 43
@@ -50,7 +49,7 @@ void gen_declaration(const char name[], int type, Scope scope) {
50 break; 49 break;
51 case LOCAL: 50 case LOCAL:
52 loc_addVar(name, type); 51 loc_addVar(name, type);
53 printf("push 0\n"); 52 fprintf(output, "push 0\n");
54 break; 53 break;
55 } 54 }
56 55
@@ -70,32 +69,32 @@ void gen_read(const char name[], Scope scope) {
70} 69}
71 70
72void gen_print() { 71void gen_print() {
73 printf("pop rax\n"); 72 fprintf(output, "pop rax\n");
74 printf("call print\n"); 73 fprintf(output, "call print\n");
75} 74}
76 75
77// ----- CONDITIONAL BRANCHING ------ 76// ----- CONDITIONAL BRANCHING ------
78 77
79void gen_if_label(int idx) { 78void gen_if_label(int idx) {
80 printf(".end_if%d:\n", idx); 79 fprintf(output, ".end_if%d:\n", idx);
81 printf(";ENDIF\n\n"); 80 fprintf(output, ";ENDIF\n\n");
82} 81}
83 82
84void gen_if_start(int idx) { 83void gen_if_start(int idx) {
85 printf("\n;BEGINIF\n"); 84 fprintf(output, "\n;BEGINIF\n");
86 printf("pop rax\n"); 85 fprintf(output, "pop rax\n");
87 printf("cmp rax,0\n"); 86 fprintf(output, "cmp rax,0\n");
88 printf("jz .end_if%d\n", idx); 87 fprintf(output, "jz .end_if%d\n", idx);
89} 88}
90 89
91void gen_if_end(int idx) { 90void gen_if_end(int idx) {
92 printf("jmp .end_ifelse%d\n", idx); 91 fprintf(output, "jmp .end_ifelse%d\n", idx);
93 printf(".end_if%d:\n", idx); 92 fprintf(output, ".end_if%d:\n", idx);
94} 93}
95 94
96void gen_ifelse_end(int idx) { 95void gen_ifelse_end(int idx) {
97 printf(".end_ifelse%d:\n", idx); 96 fprintf(output, ".end_ifelse%d:\n", idx);
98 printf("ENDIF\n\n"); 97 fprintf(output, "ENDIF\n\n");
99} 98}
100 99
101// ----- OPERATORS ----- 100// ----- OPERATORS -----
@@ -105,10 +104,10 @@ int gen_assign(const char ident[], Scope scope) {
105 104
106 switch (scope) { 105 switch (scope) {
107 case GLOBAL: 106 case GLOBAL:
108 printf(instr_fmt, glo_get_addr(ident), ident); 107 fprintf(output, instr_fmt, glo_get_addr(ident), ident);
109 return glo_lookup(ident); 108 return glo_lookup(ident);
110 case LOCAL: 109 case LOCAL:
111 printf(instr_fmt, loc_get_addr(ident), ident); 110 fprintf(output, instr_fmt, loc_get_addr(ident), ident);
112 return loc_lookup(ident); 111 return loc_lookup(ident);
113 default: 112 default:
114 exit(1); 113 exit(1);
@@ -119,72 +118,72 @@ void gen_or(int left, int right, int idx) {
119 check_expected_type(left, INT); 118 check_expected_type(left, INT);
120 check_expected_type(right, INT); 119 check_expected_type(right, INT);
121 120
122 printf(";a OR c\n"); 121 fprintf(output, ";a OR c\n");
123 printf("pop rax\n"); 122 fprintf(output, "pop rax\n");
124 printf("cmp rax,1\n"); 123 fprintf(output, "cmp rax,1\n");
125 printf("je .true%d\n", idx); 124 fprintf(output, "je .true%d\n", idx);
126 printf("pop rcx\n"); 125 fprintf(output, "pop rcx\n");
127 printf("cmp rcx,1\n"); 126 fprintf(output, "cmp rcx,1\n");
128 printf("jz .true%d\n", idx); 127 fprintf(output, "jz .true%d\n", idx);
129 printf("push 0\n"); 128 fprintf(output, "push 0\n");
130 printf("jmp .false%d\n", idx); 129 fprintf(output, "jmp .false%d\n", idx);
131 printf(".true%d:\n", idx); 130 fprintf(output, ".true%d:\n", idx);
132 printf("push 1\n"); 131 fprintf(output, "push 1\n");
133 printf(".false%d:", idx); 132 fprintf(output, ".false%d:", idx);
134} 133}
135 134
136void gen_and(int left, int right, int idx) { 135void gen_and(int left, int right, int idx) {
137 check_expected_type(left, INT); 136 check_expected_type(left, INT);
138 check_expected_type(right, INT); 137 check_expected_type(right, INT);
139 138
140 printf(";a AND c\n"); 139 fprintf(output, ";a AND c\n");
141 printf("pop rax\n"); 140 fprintf(output, "pop rax\n");
142 printf("cmp rax,0\n"); 141 fprintf(output, "cmp rax,0\n");
143 printf("jz .false%d\n", idx); 142 fprintf(output, "jz .false%d\n", idx);
144 printf("pop rcx\n"); 143 fprintf(output, "pop rcx\n");
145 printf("cmp rcx,0\n"); 144 fprintf(output, "cmp rcx,0\n");
146 printf("jz .false%d\n", idx); 145 fprintf(output, "jz .false%d\n", idx);
147 printf("push 1\n"); 146 fprintf(output, "push 1\n");
148 printf("jmp .true%d\n", idx); 147 fprintf(output, "jmp .true%d\n", idx);
149 printf(".false%d:\n", idx); 148 fprintf(output, ".false%d:\n", idx);
150 printf("push 0\n"); 149 fprintf(output, "push 0\n");
151 printf(".true%d:", idx); 150 fprintf(output, ".true%d:", idx);
152} 151}
153 152
154void gen_eq(const char op[], int left, int right, int idx) { 153void gen_eq(const char op[], int left, int right, int idx) {
155 check_expected_type(left, INT); 154 check_expected_type(left, INT);
156 check_expected_type(right, INT); 155 check_expected_type(right, INT);
157 156
158 printf(";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n"); 157 fprintf(output, ";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n");
159 158
160 if (!strcmp(op, "==")) 159 if (!strcmp(op, "=="))
161 printf("je .true%d\n", idx); 160 fprintf(output, "je .true%d\n", idx);
162 else if (!strcmp(op, "!=")) 161 else if (!strcmp(op, "!="))
163 printf("jne .true%d\n", idx); 162 fprintf(output, "jne .true%d\n", idx);
164 else 163 else
165 exit(1); // TODO: error on unexpected op 164 exit(1); // TODO: error on unexpected op
166 165
167 printf("push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, idx); 166 fprintf(output, "push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, idx);
168} 167}
169 168
170void gen_order(const char op[], int left, int right, int idx) { 169void gen_order(const char op[], int left, int right, int idx) {
171 check_expected_type(left, INT); 170 check_expected_type(left, INT);
172 check_expected_type(right, INT); 171 check_expected_type(right, INT);
173 172
174 printf(";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n"); 173 fprintf(output, ";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n");
175 174
176 if (!strcmp(op, "<")) 175 if (!strcmp(op, "<"))
177 printf("jl .true%d\n", idx); 176 fprintf(output, "jl .true%d\n", idx);
178 else if (!strcmp(op, "<=")) 177 else if (!strcmp(op, "<="))
179 printf("jle .true%d\n", idx); 178 fprintf(output, "jle .true%d\n", idx);
180 else if(!strcmp(op, ">")) 179 else if(!strcmp(op, ">"))
181 printf("jg .true%d\n", idx); 180 fprintf(output, "jg .true%d\n", idx);
182 else if(!strcmp(op, "<=")) 181 else if(!strcmp(op, "<="))
183 printf("jge .true%d\n", idx); 182 fprintf(output, "jge .true%d\n", idx);
184 else 183 else
185 exit(1); // TODO: error on unexpected op 184 exit(1); // TODO: error on unexpected op
186 185
187 printf("push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, idx); 186 fprintf(output, "push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:", idx, idx, idx);