diff options
Diffstat (limited to 'src/tpc.y')
-rw-r--r-- | src/tpc.y | 137 |
1 files changed, 37 insertions, 100 deletions
@@ -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: |
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 { gen_declaration($<ident>2, $<type>1, scope); } |
102 | ; | 102 | ; |
103 | Corps: | 103 | Corps: |
104 | '{' DeclConsts DeclVars SuiteInstr '}' | 104 | '{' DeclConsts DeclVars SuiteInstr '}' |
105 | ; | 105 | ; |
106 | SuiteInstr: | 106 | SuiteInstr: |
107 | SuiteInstr Instr | 107 | SuiteInstr Instr |
108 | | ; | 108 | | |
109 | Instr: | ||
110 | Exp ';' | ||
111 | | ';' | ||
112 | | RETURN Exp ';' | ||
113 | | RETURN ';' | ||
114 | | READE '(' IDENT ')' ';' { | ||
115 | if(scope == GLOBAL) glo_lookup($<ident>3); | ||
116 | else loc_lookup($<ident>3); | ||
117 | } | ||
118 | | READC '(' IDENT ')' ';' { | ||
119 | if(scope == GLOBAL) glo_lookup($<ident>3); | ||
120 | else loc_lookup($<ident>3); | ||
121 | } | ||
122 | | PRINT '(' Exp ')' ';' {printf("pop rax\ncall print\n");} | ||
123 | | IF '(' Exp IfHandling')' Instr {printf(".end_if%d:\n;ENDIF\n\n",$<num>4);} | ||
124 | | IF '(' Exp IfHandling')' Instr ELSE IfEndHandling Instr IfElseEndHandling | ||
125 | | WHILE '(' Exp ')' Instr | ||
126 | | '{' SuiteInstr '}' | ||
127 | ; | 109 | ; |
128 | IfHandling: {printf("\n;BEGINIF\npop rax\ncmp rax,0\njz .end_if%d\n",$<num>$ = num_if++);}; | 110 | Instr: |
129 | IfEndHandling: {printf("jmp .end_ifelse%d\n.end_if%d:\n",$<num>-3,$<num>-3);}; | 111 | Exp ';' |
130 | IfElseEndHandling: {printf(".end_ifelse%d:\n;ENDIF\n\n",$<num>-5);}; | 112 | | ';' |
113 | | RETURN Exp ';' | ||
114 | | RETURN ';' | ||
115 | | READE '(' IDENT ')' ';' { gen_read($<ident>3, scope); } | ||
116 | | READC '(' IDENT ')' ';' { gen_read($<ident>3, scope); } | ||
117 | | PRINT '(' Exp ')' ';' { gen_print();} | ||
118 | | IF '(' Exp IfHandling')' Instr { gen_if_label($<num>4); } | ||
119 | | IF '(' Exp IfHandling')' Instr ELSE IfEndHandling Instr IfElseEndHandling | ||
120 | | WHILE '(' Exp ')' Instr | ||
121 | | '{' SuiteInstr '}' | ||
122 | ; | ||
123 | IfHandling: { gen_if_start($<num>$ = num_if++); }; | ||
124 | IfEndHandling: { gen_if_end($<num>-3); }; | ||
125 | IfElseEndHandling: { gen_ifelse_end($<num>-5); }; | ||
131 | Exp: | 126 | Exp: |
132 | LValue '=' Exp { | 127 | LValue '=' Exp { /* TODO: extract this into func */ |
133 | if(scope == GLOBAL){ | 128 | if(scope == GLOBAL){ |
134 | $$ = glo_lookup($<ident>1); | 129 | $$ = glo_lookup($<ident>1); |
135 | printf("pop QWORD [rbp - %d] ;%s\n",glo_get_addr($<ident>1),$<ident>1); | 130 | printf("pop QWORD [rbp - %d] ;%s\n",glo_get_addr($<ident>1),$<ident>1); |
@@ -139,89 +134,31 @@ Exp: | |||
139 | printf("pop QWORD [rbp - %d] ;%s\n",loc_get_addr($<ident>1),$<ident>1); | 134 | printf("pop QWORD [rbp - %d] ;%s\n",loc_get_addr($<ident>1),$<ident>1); |
140 | } | 135 | } |
141 | } | 136 | } |
142 | | EB | 137 | | EB |
143 | ; | 138 | ; |
144 | EB: | 139 | EB: |
145 | EB OR TB { | 140 | EB OR TB { gen_or($1, $3, num_label++); } |
146 | check_expected_type($1,INT);check_expected_type($3,INT); | 141 | | TB |
147 | printf(";a OR c\npop rax\n"); | ||
148 | printf("cmp rax,1\nje .true%d\npop rcx\ncmp rcx,1\njz .true%d\npush 0\njmp .false%d\n",num_label,num_label,num_label); | ||
149 | printf(".true%d:\npush 1\n.false%d:",num_label,num_label); | ||
150 | num_label++; | ||
151 | } | ||
152 | | TB | ||
153 | ; | 142 | ; |
154 | TB: | 143 | TB: |
155 | TB AND FB { | 144 | TB AND FB { gen_and($1, $3, num_label++); } |
156 | check_expected_type($1,INT);check_expected_type($3,INT); | 145 | | FB |
157 | printf(";a AND c\npop rax\n"); | ||
158 | printf("cmp rax,0\njz .false%d\npop rcx\ncmp rcx,0\njz .false%d\npush 1\njmp .true%d\n",num_label,num_label,num_label); | ||
159 | printf(".false%d:\npush 0\n.true%d:",num_label,num_label); | ||
160 | num_label++; | ||
161 | } | ||
162 | | FB | ||
163 | ; | 146 | ; |
164 | FB: | 147 | FB: |
165 | FB EQ M { | 148 | FB EQ M { gen_eq($2, $1, $3, num_label++); } |
166 | check_expected_type($1,INT);check_expected_type($3,INT); | 149 | | M |
167 | printf(";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n"); | ||
168 | if(!strcmp($2,"==")){ | ||
169 | printf("je .true%d\n",num_label); | ||
170 | }else{ | ||
171 | printf("jne .true%d\n",num_label); | ||
172 | } | ||
173 | printf("push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:",num_label,num_label,num_label); | ||
174 | num_label++; | ||
175 | } | ||
176 | | M | ||
177 | ; | 150 | ; |
178 | M: | 151 | M: |
179 | M ORDER E { | 152 | M ORDER E { gen_order($2, $1, $3, num_label++); } |
180 | check_expected_type($1,INT);check_expected_type($3,INT); | ||
181 | printf(";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n"); | ||
182 | if(!strcmp($2,"<")){ | ||
183 | printf("jl .true%d\n",num_label); | ||
184 | }else if(!strcmp($2,"<=")){ | ||
185 | printf("jle .true%d\n",num_label); | ||
186 | }else if(!strcmp($2,">")){ | ||
187 | printf("jg .true%d\n",num_label); | ||
188 | }else{ | ||
189 | printf("jge .true%d\n",num_label); | ||
190 | } | ||
191 | printf("push 0\njmp .false%d\n.true%d:\npush 1\n.false%d:",num_label,num_label,num_label); | ||
192 | num_label++; | ||
193 | } | ||
194 | | E | 153 | | E |
195 | ; | 154 | ; |
196 | E: | 155 | E: |
197 | E ADDSUB T { | 156 | E ADDSUB T { gen_addsub($2, $1, $3); } |
198 | check_expected_type($1,INT);check_expected_type($3,INT); | 157 | | T |
199 | if($2 == '+'){ | ||
200 | printf(";E + T\npop rcx\npop rax\nadd rax,rcx\npush rax\n"); | ||
201 | } | ||
202 | else{ | ||
203 | printf(";E - T\npop rcx\npop rax\nsub rax,rcx\npush rax\n"); | ||
204 | } | ||
205 | } | ||
206 | | T | ||
207 | ; | 158 | ; |
208 | T: | 159 | T: |
209 | T DIVSTAR F { | 160 | T DIVSTAR F { gen_divstar($2, $1, $3); } |
210 | check_expected_type($1,INT);check_expected_type($3,INT); | 161 | | F |
211 | if($2 == '*'){ | ||
212 | printf(";E * T\npop rax\npop rcx\nimul rax,rcx\npush rax\n"); | ||
213 | } | ||
214 | else{ | ||
215 | printf(";E / T\npop rax\npop rcx\nxor rdx,rdx\nidiv rcx\n"); | ||
216 | if ($2 == '/'){ | ||
217 | printf("push rax\n"); | ||
218 | } | ||
219 | else{ | ||
220 | printf("push rdx\n"); | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | | F | ||
225 | ; | 162 | ; |
226 | F: | 163 | F: |
227 | ADDSUB F {$$ = $2;//on fait remonter le type | 164 | ADDSUB F {$$ = $2;//on fait remonter le type |