rlm@1: // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. rlm@1: // Copyright (C) 1999-2003 Forgotten rlm@1: // Copyright (C) 2004 Forgotten and the VBA development team rlm@1: rlm@1: // This program is free software; you can redistribute it and/or modify rlm@1: // it under the terms of the GNU General Public License as published by rlm@1: // the Free Software Foundation; either version 2, or(at your option) rlm@1: // any later version. rlm@1: // rlm@1: // This program is distributed in the hope that it will be useful, rlm@1: // but WITHOUT ANY WARRANTY; without even the implied warranty of rlm@1: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the rlm@1: // GNU General Public License for more details. rlm@1: // rlm@1: // You should have received a copy of the GNU General Public License rlm@1: // along with this program; if not, write to the Free Software Foundation, rlm@1: // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. rlm@1: rlm@1: #include rlm@1: #include rlm@1: #include rlm@1: rlm@1: #include "Port.h" rlm@1: #include "gba/GBAGlobals.h" rlm@1: #include "gba/elf.h" rlm@1: #include "exprNode.h" rlm@1: rlm@1: extern char *yytext; rlm@1: rlm@1: #define debuggerReadMemory(addr) \ rlm@1: READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) rlm@1: rlm@1: void *exprNodeCleanUpList[100]; rlm@1: int exprNodeCleanUpCount = 0; rlm@1: Type exprNodeType = { 0, TYPE_base, "int", DW_ATE_signed, 4, 0, {0}, 0 }; rlm@1: rlm@1: void exprNodeClean(void *m) rlm@1: { rlm@1: exprNodeCleanUpList[exprNodeCleanUpCount++] = m; rlm@1: } rlm@1: rlm@1: void exprNodeCleanUp() rlm@1: { rlm@1: for(int i = 0; i < exprNodeCleanUpCount; i++) { rlm@1: free(exprNodeCleanUpList[i]); rlm@1: } rlm@1: exprNodeCleanUpCount = 0; rlm@1: } rlm@1: rlm@1: Node *exprNodeIdentifier() rlm@1: { rlm@1: Node *n = (Node *)calloc(1, sizeof(Node)); rlm@1: n->name = strdup(yytext); rlm@1: rlm@1: exprNodeClean(n->name); rlm@1: exprNodeClean(n); rlm@1: rlm@1: n->print = exprNodeIdentifierPrint; rlm@1: n->resolve = exprNodeIdentifierResolve; rlm@1: return n; rlm@1: } rlm@1: rlm@1: bool exprNodeIdentifierResolve(Node *n, Function *f, CompileUnit *u) rlm@1: { rlm@1: Object *o; rlm@1: if(elfGetObject(n->name, f, u, &o)) { rlm@1: n->type = o->type; rlm@1: n->location = elfDecodeLocation(f, o->location, &n->locType); rlm@1: return true; rlm@1: } else { rlm@1: printf("Object %s not found\n", n->name); rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: void exprNodeIdentifierPrint(Node *n) rlm@1: { rlm@1: printf("%s", n->name); rlm@1: } rlm@1: rlm@1: Node *exprNodeNumber() rlm@1: { rlm@1: Node *n = (Node *)calloc(1, sizeof(Node)); rlm@1: rlm@1: exprNodeClean(n); rlm@1: n->location = atoi(yytext); rlm@1: n->type = &exprNodeType; rlm@1: n->locType = LOCATION_value; rlm@1: n->print = exprNodeNumberPrint; rlm@1: n->resolve = exprNodeNumberResolve; rlm@1: return n; rlm@1: } rlm@1: rlm@1: bool exprNodeNumberResolve(Node *n, Function *f, CompileUnit *u) rlm@1: { rlm@1: return true; rlm@1: } rlm@1: rlm@1: void exprNodeNumberPrint(Node *n) rlm@1: { rlm@1: printf("%d", n->location); rlm@1: } rlm@1: rlm@1: Node *exprNodeStar(Node *exp) rlm@1: { rlm@1: Node *n = (Node *)calloc(1, sizeof(Node)); rlm@1: exprNodeClean(n); rlm@1: rlm@1: n->expression = exp; rlm@1: rlm@1: n->print = exprNodeStarPrint; rlm@1: n->resolve = exprNodeStarResolve; rlm@1: return n; rlm@1: } rlm@1: rlm@1: bool exprNodeStarResolve(Node *n, Function *f, CompileUnit *u) rlm@1: { rlm@1: if(n->expression->resolve(n->expression, f, u)) { rlm@1: if(n->expression->type->type == TYPE_pointer) { rlm@1: n->location = n->expression->location; rlm@1: if(n->expression->locType == LOCATION_memory) { rlm@1: n->location = debuggerReadMemory(n->location); rlm@1: } else if(n->expression->locType == LOCATION_register) { rlm@1: n->location = reg[n->expression->location].I; rlm@1: } else { rlm@1: n->location = n->expression->location; rlm@1: } rlm@1: n->type = n->expression->type->pointer; rlm@1: n->locType = LOCATION_memory; rlm@1: return true; rlm@1: } else { rlm@1: printf("Object is not of pointer type\n"); rlm@1: } rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: void exprNodeStarPrint(Node *n) rlm@1: { rlm@1: printf("*"); rlm@1: n->expression->print(n->expression); rlm@1: } rlm@1: rlm@1: Node *exprNodeDot(Node *exp, Node *ident) rlm@1: { rlm@1: Node *n = (Node *)calloc(1, sizeof(Node)); rlm@1: exprNodeClean(n); rlm@1: rlm@1: n->expression = exp; rlm@1: n->name = ident->name; rlm@1: rlm@1: n->print = exprNodeDotPrint; rlm@1: n->resolve = exprNodeDotResolve; rlm@1: return n; rlm@1: } rlm@1: rlm@1: bool exprNodeDotResolve(Node *n, Function *f, CompileUnit *u) rlm@1: { rlm@1: if(n->expression->resolve(n->expression, f, u)) { rlm@1: TypeEnum tt = n->expression->type->type; rlm@1: rlm@1: if(tt == TYPE_struct || rlm@1: tt == TYPE_union) { rlm@1: u32 loc = n->expression->location; rlm@1: Type *t = n->expression->type; rlm@1: int count = t->structure->memberCount; rlm@1: int i = 0; rlm@1: while(i < count) { rlm@1: Member *m = &t->structure->members[i]; rlm@1: if(strcmp(m->name, n->name) == 0) { rlm@1: // found member rlm@1: n->type = m->type; rlm@1: if(tt == TYPE_struct) { rlm@1: n->location = elfDecodeLocation(f, m->location, &n->locType, rlm@1: loc); rlm@1: n->objLocation = loc; rlm@1: } else { rlm@1: n->location = loc; rlm@1: n->locType = n->expression->locType; rlm@1: n->objLocation = loc; rlm@1: } rlm@1: n->member = m; rlm@1: return true; rlm@1: } rlm@1: i++; rlm@1: } rlm@1: printf("Member %s not found\n", n->name); rlm@1: } else { rlm@1: printf("Object is not of structure type\n"); rlm@1: } rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: void exprNodeDotPrint(Node *n) rlm@1: { rlm@1: n->expression->print(n->expression); rlm@1: printf(".%s", n->name); rlm@1: } rlm@1: rlm@1: Node *exprNodeArrow(Node *exp, Node *ident) rlm@1: { rlm@1: Node *n = (Node *)calloc(1, sizeof(Node)); rlm@1: exprNodeClean(n); rlm@1: rlm@1: n->expression = exp; rlm@1: n->name = ident->name; rlm@1: rlm@1: n->print = exprNodeArrowPrint; rlm@1: n->resolve = exprNodeArrowResolve; rlm@1: return n; rlm@1: } rlm@1: rlm@1: bool exprNodeArrowResolve(Node *n, Function *f, CompileUnit *u) rlm@1: { rlm@1: if(n->expression->resolve(n->expression, f, u)) { rlm@1: TypeEnum tt = n->expression->type->type; rlm@1: if(tt != TYPE_pointer) { rlm@1: printf("Object not of pointer type\n"); rlm@1: return false; rlm@1: } rlm@1: tt = n->expression->type->pointer->type; rlm@1: rlm@1: if(tt == TYPE_struct || rlm@1: tt == TYPE_union) { rlm@1: u32 loc = debuggerReadMemory(n->expression->location); rlm@1: Type *t = n->expression->type->pointer; rlm@1: int count = t->structure->memberCount; rlm@1: int i = 0; rlm@1: while(i < count) { rlm@1: Member *m = &t->structure->members[i]; rlm@1: if(strcmp(m->name, n->name) == 0) { rlm@1: // found member rlm@1: n->type = m->type; rlm@1: if(tt == TYPE_struct) { rlm@1: n->location = elfDecodeLocation(f, m->location, &n->locType, rlm@1: loc); rlm@1: n->objLocation = loc; rlm@1: } else { rlm@1: n->location = loc; rlm@1: n->objLocation = loc; rlm@1: } rlm@1: n->locType = LOCATION_memory; rlm@1: n->member = m; rlm@1: return true; rlm@1: } rlm@1: i++; rlm@1: } rlm@1: printf("Member %s not found\n", n->name); rlm@1: } else { rlm@1: printf("Object is not of structure type\n"); rlm@1: } rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: void exprNodeArrowPrint(Node *n) rlm@1: { rlm@1: n->expression->print(n->expression); rlm@1: printf("->%s", n->name); rlm@1: } rlm@1: rlm@1: Node *exprNodeAddr(Node *exp) rlm@1: { rlm@1: Node *n = (Node *)calloc(1, sizeof(Node)); rlm@1: exprNodeClean(n); rlm@1: rlm@1: n->expression = exp; rlm@1: rlm@1: n->print = exprNodeAddrPrint; rlm@1: n->resolve = exprNodeAddrResolve; rlm@1: return n; rlm@1: } rlm@1: rlm@1: bool exprNodeAddrResolve(Node *n, Function *f, CompileUnit *u) rlm@1: { rlm@1: if(n->expression->resolve(n->expression, f, u)) { rlm@1: if(n->expression->locType == LOCATION_memory) { rlm@1: n->location = n->expression->location; rlm@1: n->locType = LOCATION_value; rlm@1: n->type = &exprNodeType; rlm@1: } else if(n->expression->locType == LOCATION_register) { rlm@1: printf("Value is in register %d\n", n->expression->location); rlm@1: } else { rlm@1: printf("Direct value is %d\n", n->location); rlm@1: } rlm@1: return true; rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: void exprNodeAddrPrint(Node *n) rlm@1: { rlm@1: printf("*"); rlm@1: n->expression->print(n->expression); rlm@1: } rlm@1: rlm@1: Node *exprNodeSizeof(Node *exp) rlm@1: { rlm@1: Node *n = (Node *)calloc(1, sizeof(Node)); rlm@1: exprNodeClean(n); rlm@1: rlm@1: n->expression = exp; rlm@1: rlm@1: n->print = exprNodeSizeofPrint; rlm@1: n->resolve = exprNodeSizeofResolve; rlm@1: return n; rlm@1: } rlm@1: rlm@1: bool exprNodeSizeofResolve(Node *n, Function *f, CompileUnit *u) rlm@1: { rlm@1: if(n->expression->resolve(n->expression, f, u)) { rlm@1: n->location = n->expression->type->size; rlm@1: n->locType = LOCATION_value; rlm@1: n->type = &exprNodeType; rlm@1: return true; rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: void exprNodeSizeofPrint(Node *n) rlm@1: { rlm@1: printf("sizeof("); rlm@1: n->expression->print(n->expression); rlm@1: printf(")"); rlm@1: } rlm@1: rlm@1: Node *exprNodeArray(Node *exp, Node *number) rlm@1: { rlm@1: Node *n = (Node *)calloc(1, sizeof(Node)); rlm@1: exprNodeClean(n); rlm@1: rlm@1: n->expression = exp; rlm@1: n->value = number->location; rlm@1: rlm@1: n->print = exprNodeArrayPrint; rlm@1: n->resolve = exprNodeArrayResolve; rlm@1: return n; rlm@1: } rlm@1: rlm@1: int exprNodeGetSize(Array *a, int index) rlm@1: { rlm@1: index++; rlm@1: if(index == a->maxBounds) { rlm@1: return a->type->size; rlm@1: } else { rlm@1: int size = a->bounds[a->maxBounds-1] * a->type->size; rlm@1: rlm@1: for(int i = index; i < a->maxBounds-1; i++) { rlm@1: size *= a->bounds[i]; rlm@1: } rlm@1: return size; rlm@1: } rlm@1: } rlm@1: rlm@1: bool exprNodeArrayResolve(Node *n, Function *f, CompileUnit *u) rlm@1: { rlm@1: if(n->expression->resolve(n->expression, f, u)) { rlm@1: TypeEnum tt = n->expression->type->type; rlm@1: if(tt != TYPE_array && rlm@1: tt != TYPE_pointer) { rlm@1: printf("Object not of array or pointer type\n"); rlm@1: return false; rlm@1: } rlm@1: rlm@1: if(tt == TYPE_array) { rlm@1: Array *a = n->expression->type->array; rlm@1: rlm@1: u32 loc = n->expression->location; rlm@1: Type *t = a->type; rlm@1: if(a->maxBounds > 1) { rlm@1: int index = n->expression->index; rlm@1: rlm@1: if(index == a->maxBounds) { rlm@1: printf("Too many indices for array\n"); rlm@1: return false; rlm@1: } rlm@1: rlm@1: if((index+1) < a->maxBounds) { rlm@1: n->type = n->expression->type; rlm@1: n->index = index+1; rlm@1: n->locType = LOCATION_memory; rlm@1: n->location = n->expression->location + rlm@1: n->value * exprNodeGetSize(a, index); rlm@1: return true; rlm@1: } rlm@1: } rlm@1: n->type = t; rlm@1: n->location = loc + n->value * t->size; rlm@1: n->locType = LOCATION_memory; rlm@1: } else { rlm@1: Type *t = n->expression->type->pointer; rlm@1: u32 loc = n->expression->location; rlm@1: if(n->expression->locType == LOCATION_register) rlm@1: loc = reg[loc].I; rlm@1: else rlm@1: loc = debuggerReadMemory(loc); rlm@1: n->type = t; rlm@1: n->location = loc + n->value * t->size; rlm@1: n->locType = LOCATION_memory; rlm@1: } rlm@1: return true; rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: void exprNodeArrayPrint(Node *n) rlm@1: { rlm@1: n->expression->print(n->expression); rlm@1: printf("[%d]", n->value); rlm@1: }