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