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