Mercurial > vba-clojure
view src/sdl/exprNode.cpp @ 135:eb6ba88088d3
Wrote a more efficient input-number-assembly program; 91 oc -> 60 oc.
author | Dylan Holmes <ocsenave@gmail.com> |
---|---|
date | Sun, 18 Mar 2012 05:13:19 -0500 |
parents | f9f4f1b99eed |
children |
line wrap: on
line source
1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.2 // Copyright (C) 1999-2003 Forgotten3 // Copyright (C) 2004 Forgotten and the VBA development team5 // This program is free software; you can redistribute it and/or modify6 // it under the terms of the GNU General Public License as published by7 // 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 of12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 // GNU General Public License for more details.14 //15 // You should have received a copy of the GNU General Public License16 // 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 member172 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 member234 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 else397 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 }