1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004 Forgotten and the VBA development team
4
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or(at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 #include <string.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #include "../gba/GBA.h"
24 #include "../gba/elf.h"
25 #include "../common/Port.h"
26 #include "exprNode.h"
27
28 #ifndef __GNUC__
29 #define strdup _strdup
30 #endif
31
32 extern char *yytext;
33
34 #define debuggerReadMemory(addr) \
35 READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
36
37 const void *exprNodeCleanUpList[100];
38 int exprNodeCleanUpCount = 0;
39 Type exprNodeType = { 0, TYPE_base, "int", DW_ATE_signed, 4, 0, {0}, 0 };
40
exprNodeClean(const void * m)41 void exprNodeClean(const void *m)
42 {
43 exprNodeCleanUpList[exprNodeCleanUpCount++] = m;
44 }
45
exprNodeCleanUp()46 void exprNodeCleanUp()
47 {
48 for(int i = 0; i < exprNodeCleanUpCount; i++) {
49 free((void *)exprNodeCleanUpList[i]);
50 }
51 exprNodeCleanUpCount = 0;
52 }
53
exprNodeIdentifier()54 Node *exprNodeIdentifier()
55 {
56 Node *n = (Node *)calloc(1, sizeof(Node));
57 n->name = strdup(yytext);
58
59 exprNodeClean(n->name);
60 exprNodeClean(n);
61
62 n->print = exprNodeIdentifierPrint;
63 n->resolve = exprNodeIdentifierResolve;
64 return n;
65 }
66
exprNodeIdentifierResolve(Node * n,Function * f,CompileUnit * u)67 bool exprNodeIdentifierResolve(Node *n, Function *f, CompileUnit *u)
68 {
69 Object *o;
70 if(elfGetObject(n->name, f, u, &o)) {
71 n->type = o->type;
72 n->location = elfDecodeLocation(f, o->location, &n->locType);
73 return true;
74 } else {
75 printf("Object %s not found\n", n->name);
76 }
77 return false;
78 }
79
exprNodeIdentifierPrint(Node * n)80 void exprNodeIdentifierPrint(Node *n)
81 {
82 printf("%s", n->name);
83 }
84
exprNodeNumber()85 Node *exprNodeNumber()
86 {
87 Node *n = (Node *)calloc(1, sizeof(Node));
88
89 exprNodeClean(n);
90 n->location = atoi(yytext);
91 n->type = &exprNodeType;
92 n->locType = LOCATION_value;
93 n->print = exprNodeNumberPrint;
94 n->resolve = exprNodeNumberResolve;
95 return n;
96 }
97
exprNodeNumberResolve(Node * n,Function * f,CompileUnit * u)98 bool exprNodeNumberResolve(Node *n, Function *f, CompileUnit *u)
99 {
100 return true;
101 }
102
exprNodeNumberPrint(Node * n)103 void exprNodeNumberPrint(Node *n)
104 {
105 printf("%d", n->location);
106 }
107
exprNodeStar(Node * exp)108 Node *exprNodeStar(Node *exp)
109 {
110 Node *n = (Node *)calloc(1, sizeof(Node));
111 exprNodeClean(n);
112
113 n->expression = exp;
114
115 n->print = exprNodeStarPrint;
116 n->resolve = exprNodeStarResolve;
117 return n;
118 }
119
exprNodeStarResolve(Node * n,Function * f,CompileUnit * u)120 bool exprNodeStarResolve(Node *n, Function *f, CompileUnit *u)
121 {
122 if(n->expression->resolve(n->expression, f, u)) {
123 if(n->expression->type->type == TYPE_pointer) {
124 n->location = n->expression->location;
125 if(n->expression->locType == LOCATION_memory) {
126 n->location = debuggerReadMemory(n->location);
127 } else if(n->expression->locType == LOCATION_register) {
128 n->location = reg[n->expression->location].I;
129 } else {
130 n->location = n->expression->location;
131 }
132 n->type = n->expression->type->pointer;
133 n->locType = LOCATION_memory;
134 return true;
135 } else {
136 printf("Object is not of pointer type\n");
137 }
138 }
139 return false;
140 }
141
exprNodeStarPrint(Node * n)142 void exprNodeStarPrint(Node *n)
143 {
144 printf("*");
145 n->expression->print(n->expression);
146 }
147
exprNodeDot(Node * exp,Node * ident)148 Node *exprNodeDot(Node *exp, Node *ident)
149 {
150 Node *n = (Node *)calloc(1, sizeof(Node));
151 exprNodeClean(n);
152
153 n->expression = exp;
154 n->name = ident->name;
155
156 n->print = exprNodeDotPrint;
157 n->resolve = exprNodeDotResolve;
158 return n;
159 }
160
exprNodeDotResolve(Node * n,Function * f,CompileUnit * u)161 bool exprNodeDotResolve(Node *n, Function *f, CompileUnit *u)
162 {
163 if(n->expression->resolve(n->expression, f, u)) {
164 TypeEnum tt = n->expression->type->type;
165
166 if(tt == TYPE_struct ||
167 tt == TYPE_union) {
168 u32 loc = n->expression->location;
169 Type *t = n->expression->type;
170 int count = t->structure->memberCount;
171 int i = 0;
172 while(i < count) {
173 Member *m = &t->structure->members[i];
174 if(strcmp(m->name, n->name) == 0) {
175 // found member
176 n->type = m->type;
177 if(tt == TYPE_struct) {
178 n->location = elfDecodeLocation(f, m->location, &n->locType,
179 loc);
180 n->objLocation = loc;
181 } else {
182 n->location = loc;
183 n->locType = n->expression->locType;
184 n->objLocation = loc;
185 }
186 n->member = m;
187 return true;
188 }
189 i++;
190 }
191 printf("Member %s not found\n", n->name);
192 } else {
193 printf("Object is not of structure type\n");
194 }
195 }
196 return false;
197 }
198
exprNodeDotPrint(Node * n)199 void exprNodeDotPrint(Node *n)
200 {
201 n->expression->print(n->expression);
202 printf(".%s", n->name);
203 }
204
exprNodeArrow(Node * exp,Node * ident)205 Node *exprNodeArrow(Node *exp, Node *ident)
206 {
207 Node *n = (Node *)calloc(1, sizeof(Node));
208 exprNodeClean(n);
209
210 n->expression = exp;
211 n->name = ident->name;
212
213 n->print = exprNodeArrowPrint;
214 n->resolve = exprNodeArrowResolve;
215 return n;
216 }
217
exprNodeArrowResolve(Node * n,Function * f,CompileUnit * u)218 bool exprNodeArrowResolve(Node *n, Function *f, CompileUnit *u)
219 {
220 if(n->expression->resolve(n->expression, f, u)) {
221 TypeEnum tt = n->expression->type->type;
222 if(tt != TYPE_pointer) {
223 printf("Object not of pointer type\n");
224 return false;
225 }
226 tt = n->expression->type->pointer->type;
227
228 if(tt == TYPE_struct ||
229 tt == TYPE_union) {
230 u32 loc = debuggerReadMemory(n->expression->location);
231 Type *t = n->expression->type->pointer;
232 int count = t->structure->memberCount;
233 int i = 0;
234 while(i < count) {
235 Member *m = &t->structure->members[i];
236 if(strcmp(m->name, n->name) == 0) {
237 // found member
238 n->type = m->type;
239 if(tt == TYPE_struct) {
240 n->location = elfDecodeLocation(f, m->location, &n->locType,
241 loc);
242 n->objLocation = loc;
243 } else {
244 n->location = loc;
245 n->objLocation = loc;
246 }
247 n->locType = LOCATION_memory;
248 n->member = m;
249 return true;
250 }
251 i++;
252 }
253 printf("Member %s not found\n", n->name);
254 } else {
255 printf("Object is not of structure type\n");
256 }
257 }
258 return false;
259 }
260
exprNodeArrowPrint(Node * n)261 void exprNodeArrowPrint(Node *n)
262 {
263 n->expression->print(n->expression);
264 printf("->%s", n->name);
265 }
266
exprNodeAddr(Node * exp)267 Node *exprNodeAddr(Node *exp)
268 {
269 Node *n = (Node *)calloc(1, sizeof(Node));
270 exprNodeClean(n);
271
272 n->expression = exp;
273
274 n->print = exprNodeAddrPrint;
275 n->resolve = exprNodeAddrResolve;
276 return n;
277 }
278
exprNodeAddrResolve(Node * n,Function * f,CompileUnit * u)279 bool exprNodeAddrResolve(Node *n, Function *f, CompileUnit *u)
280 {
281 if(n->expression->resolve(n->expression, f, u)) {
282 if(n->expression->locType == LOCATION_memory) {
283 n->location = n->expression->location;
284 n->locType = LOCATION_value;
285 n->type = &exprNodeType;
286 } else if(n->expression->locType == LOCATION_register) {
287 printf("Value is in register %d\n", n->expression->location);
288 } else {
289 printf("Direct value is %d\n", n->location);
290 }
291 return true;
292 }
293 return false;
294 }
295
exprNodeAddrPrint(Node * n)296 void exprNodeAddrPrint(Node *n)
297 {
298 printf("*");
299 n->expression->print(n->expression);
300 }
301
exprNodeSizeof(Node * exp)302 Node *exprNodeSizeof(Node *exp)
303 {
304 Node *n = (Node *)calloc(1, sizeof(Node));
305 exprNodeClean(n);
306
307 n->expression = exp;
308
309 n->print = exprNodeSizeofPrint;
310 n->resolve = exprNodeSizeofResolve;
311 return n;
312 }
313
exprNodeSizeofResolve(Node * n,Function * f,CompileUnit * u)314 bool exprNodeSizeofResolve(Node *n, Function *f, CompileUnit *u)
315 {
316 if(n->expression->resolve(n->expression, f, u)) {
317 n->location = n->expression->type->size;
318 n->locType = LOCATION_value;
319 n->type = &exprNodeType;
320 return true;
321 }
322 return false;
323 }
324
exprNodeSizeofPrint(Node * n)325 void exprNodeSizeofPrint(Node *n)
326 {
327 printf("sizeof(");
328 n->expression->print(n->expression);
329 printf(")");
330 }
331
exprNodeArray(Node * exp,Node * number)332 Node *exprNodeArray(Node *exp, Node *number)
333 {
334 Node *n = (Node *)calloc(1, sizeof(Node));
335 exprNodeClean(n);
336
337 n->expression = exp;
338 n->value = number->location;
339
340 n->print = exprNodeArrayPrint;
341 n->resolve = exprNodeArrayResolve;
342 return n;
343 }
344
exprNodeGetSize(Array * a,int index)345 int exprNodeGetSize(Array *a, int index)
346 {
347 index++;
348 if(index == a->maxBounds) {
349 return a->type->size;
350 } else {
351 int size = a->bounds[a->maxBounds-1] * a->type->size;
352
353 for(int i = index; i < a->maxBounds-1; i++) {
354 size *= a->bounds[i];
355 }
356 return size;
357 }
358 }
359
exprNodeArrayResolve(Node * n,Function * f,CompileUnit * u)360 bool exprNodeArrayResolve(Node *n, Function *f, CompileUnit *u)
361 {
362 if(n->expression->resolve(n->expression, f, u)) {
363 TypeEnum tt = n->expression->type->type;
364 if(tt != TYPE_array &&
365 tt != TYPE_pointer) {
366 printf("Object not of array or pointer type\n");
367 return false;
368 }
369
370 if(tt == TYPE_array) {
371 Array *a = n->expression->type->array;
372
373 u32 loc = n->expression->location;
374 Type *t = a->type;
375 if(a->maxBounds > 1) {
376 int index = n->expression->index;
377
378 if(index == a->maxBounds) {
379 printf("Too many indices for array\n");
380 return false;
381 }
382
383 if((index+1) < a->maxBounds) {
384 n->type = n->expression->type;
385 n->index = index+1;
386 n->locType = LOCATION_memory;
387 n->location = n->expression->location +
388 n->value * exprNodeGetSize(a, index);
389 return true;
390 }
391 }
392 n->type = t;
393 n->location = loc + n->value * t->size;
394 n->locType = LOCATION_memory;
395 } else {
396 Type *t = n->expression->type->pointer;
397 u32 loc = n->expression->location;
398 if(n->expression->locType == LOCATION_register)
399 loc = reg[loc].I;
400 else
401 loc = debuggerReadMemory(loc);
402 n->type = t;
403 n->location = loc + n->value * t->size;
404 n->locType = LOCATION_memory;
405 }
406 return true;
407 }
408 return false;
409 }
410
exprNodeArrayPrint(Node * n)411 void exprNodeArrayPrint(Node *n)
412 {
413 n->expression->print(n->expression);
414 printf("[%d]", n->value);
415 }
416