view src/sdl/exprNode.cpp @ 574:be6f46094ad0

implemented video-memory pointer logic.
author Robert McIntyre <rlm@mit.edu>
date Sat, 01 Sep 2012 04:05:51 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004 Forgotten and the VBA development team
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.
19 #include <string.h>
20 #include <stdio.h>
21 #include <stdlib.h>
23 #include "Port.h"
24 #include "gba/GBAGlobals.h"
25 #include "gba/elf.h"
26 #include "exprNode.h"
28 extern char *yytext;
30 #define debuggerReadMemory(addr) \
31 READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
33 void *exprNodeCleanUpList[100];
34 int exprNodeCleanUpCount = 0;
35 Type exprNodeType = { 0, TYPE_base, "int", DW_ATE_signed, 4, 0, {0}, 0 };
37 void exprNodeClean(void *m)
38 {
39 exprNodeCleanUpList[exprNodeCleanUpCount++] = m;
40 }
42 void exprNodeCleanUp()
43 {
44 for(int i = 0; i < exprNodeCleanUpCount; i++) {
45 free(exprNodeCleanUpList[i]);
46 }
47 exprNodeCleanUpCount = 0;
48 }
50 Node *exprNodeIdentifier()
51 {
52 Node *n = (Node *)calloc(1, sizeof(Node));
53 n->name = strdup(yytext);
55 exprNodeClean(n->name);
56 exprNodeClean(n);
58 n->print = exprNodeIdentifierPrint;
59 n->resolve = exprNodeIdentifierResolve;
60 return n;
61 }
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 }
76 void exprNodeIdentifierPrint(Node *n)
77 {
78 printf("%s", n->name);
79 }
81 Node *exprNodeNumber()
82 {
83 Node *n = (Node *)calloc(1, sizeof(Node));
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 }
94 bool exprNodeNumberResolve(Node *n, Function *f, CompileUnit *u)
95 {
96 return true;
97 }
99 void exprNodeNumberPrint(Node *n)
100 {
101 printf("%d", n->location);
102 }
104 Node *exprNodeStar(Node *exp)
105 {
106 Node *n = (Node *)calloc(1, sizeof(Node));
107 exprNodeClean(n);
109 n->expression = exp;
111 n->print = exprNodeStarPrint;
112 n->resolve = exprNodeStarResolve;
113 return n;
114 }
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 }
138 void exprNodeStarPrint(Node *n)
139 {
140 printf("*");
141 n->expression->print(n->expression);
142 }
144 Node *exprNodeDot(Node *exp, Node *ident)
145 {
146 Node *n = (Node *)calloc(1, sizeof(Node));
147 exprNodeClean(n);
149 n->expression = exp;
150 n->name = ident->name;
152 n->print = exprNodeDotPrint;
153 n->resolve = exprNodeDotResolve;
154 return n;
155 }
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;
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 }
195 void exprNodeDotPrint(Node *n)
196 {
197 n->expression->print(n->expression);
198 printf(".%s", n->name);
199 }
201 Node *exprNodeArrow(Node *exp, Node *ident)
202 {
203 Node *n = (Node *)calloc(1, sizeof(Node));
204 exprNodeClean(n);
206 n->expression = exp;
207 n->name = ident->name;
209 n->print = exprNodeArrowPrint;
210 n->resolve = exprNodeArrowResolve;
211 return n;
212 }
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;
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 }
257 void exprNodeArrowPrint(Node *n)
258 {
259 n->expression->print(n->expression);
260 printf("->%s", n->name);
261 }
263 Node *exprNodeAddr(Node *exp)
264 {
265 Node *n = (Node *)calloc(1, sizeof(Node));
266 exprNodeClean(n);
268 n->expression = exp;
270 n->print = exprNodeAddrPrint;
271 n->resolve = exprNodeAddrResolve;
272 return n;
273 }
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 }
292 void exprNodeAddrPrint(Node *n)
293 {
294 printf("*");
295 n->expression->print(n->expression);
296 }
298 Node *exprNodeSizeof(Node *exp)
299 {
300 Node *n = (Node *)calloc(1, sizeof(Node));
301 exprNodeClean(n);
303 n->expression = exp;
305 n->print = exprNodeSizeofPrint;
306 n->resolve = exprNodeSizeofResolve;
307 return n;
308 }
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 }
321 void exprNodeSizeofPrint(Node *n)
322 {
323 printf("sizeof(");
324 n->expression->print(n->expression);
325 printf(")");
326 }
328 Node *exprNodeArray(Node *exp, Node *number)
329 {
330 Node *n = (Node *)calloc(1, sizeof(Node));
331 exprNodeClean(n);
333 n->expression = exp;
334 n->value = number->location;
336 n->print = exprNodeArrayPrint;
337 n->resolve = exprNodeArrayResolve;
338 return n;
339 }
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;
349 for(int i = index; i < a->maxBounds-1; i++) {
350 size *= a->bounds[i];
351 }
352 return size;
353 }
354 }
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 }
366 if(tt == TYPE_array) {
367 Array *a = n->expression->type->array;
369 u32 loc = n->expression->location;
370 Type *t = a->type;
371 if(a->maxBounds > 1) {
372 int index = n->expression->index;
374 if(index == a->maxBounds) {
375 printf("Too many indices for array\n");
376 return false;
377 }
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 }
407 void exprNodeArrayPrint(Node *n)
408 {
409 n->expression->print(n->expression);
410 printf("[%d]", n->value);
411 }