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