Object* checkDeclaredLValueIdent(char* name) { Object* obj = lookupObject(name); Scope* scope; if (obj == NULL){ error(ERR_UNDECLARED_IDENT,currentToken->lineNo, currentToken->colNo); } switch (obj->kind) { case OBJ_VARIABLE: case OBJ_PARAMETER: break; case OBJ_FUNCTION: scope = symtab->currentScope; while ((scope != NULL) && (scope != obj->funcAttrs->scope)){ scope = scope->outer; } if (scope == NULL){ error(ERR_INVALID_IDENT,currentToken->lineNo, currentToken->colNo); } break; default:{ error(ERR_INVALID_IDENT,currentToken->lineNo, currentToken->colNo); } } return obj; }
Object* checkDeclaredIdent(char* name) { Object* obj = lookupObject(name); if (obj == NULL) { error(ERR_UNDECLARED_IDENT,currentToken->lineNo, currentToken->colNo); } return obj; }
ConstantValue* compileConstant2(void) { // TODO: create and return a constant value ConstantValue* constValue = NULL; switch (lookAhead->tokenType) { case TK_NUMBER: eat(TK_NUMBER); constValue = makeIntConstant(currentToken->value); break; case TK_IDENT: eat(TK_IDENT); Object * obj = lookupObject(currentToken->string); if (obj == NULL) error(ERR_UNDECLARED_CONSTANT, currentToken->lineNo, currentToken->colNo); else if (obj->kind != OBJ_CONSTANT) error(ERR_INVALID_CONSTANT, currentToken->lineNo, currentToken->colNo); constValue = duplicateConstantValue(obj->constAttrs->value); break; default: error(ERR_INVALID_CONSTANT, lookAhead->lineNo, lookAhead->colNo); break; } return constValue; }
void Bat::pickupObject(int newObject, Sync* sync) { // If the bat grabs something that a player is carrying, the bat gets it // This allows the bat to take something being carried for (int ctr=0; ctr<board->getNumPlayers(); ++ctr) { BALL* nextBall = board->getPlayer(ctr); if (newObject == nextBall->linkedObject) { // Now player has nothing nextBall->linkedObject = OBJECT_NONE; } } // A NULL sync indicates this was initiated by a sync message and does not need to be rebroadcast if (sync != NULL) { if (linkedObject == OBJECT_NONE) { BatPickupAction* action = new BatPickupAction(newObject, 8, 0, OBJECT_NONE, 0, 0, 0); sync->BroadcastAction(action); } else { OBJECT* dropObject = lookupObject(linkedObject); BatPickupAction* action = new BatPickupAction(newObject, 8, 0, linkedObject, dropObject->room, dropObject->x, dropObject->y); sync->BroadcastAction(action); } } // Pick it up linkedObject = newObject; linkedObjectX = 8; linkedObjectY = 0; // Reset the timer batFedUpTimer = 0; }
ConstantValue* compileUnsignedConstant(void) { // TODO: create and return an unsigned constant value ConstantValue* constValue = NULL; switch (lookAhead->tokenType) { case TK_NUMBER: eat(TK_NUMBER); constValue = makeIntConstant(currentToken->value); break; case TK_IDENT: eat(TK_IDENT); Object* obj = lookupObject(currentToken->string); if (obj == NULL) { error(ERR_UNDECLARED_CONSTANT, currentToken->lineNo, currentToken->colNo); } else if (obj->kind != OBJ_CONSTANT) { error(ERR_INVALID_CONSTANT, currentToken->lineNo, currentToken->colNo); } constValue = (ConstantValue*) malloc(sizeof(ConstantValue)); *constValue = *(obj->constAttrs->value); break; case TK_CHAR: eat(TK_CHAR); constValue = makeCharConstant(currentToken->string[0]); break; default: error(ERR_INVALID_CONSTANT, lookAhead->lineNo, lookAhead->colNo); break; } return constValue; }
ConstantValue* compileUnsignedConstant(void) { // TODO: create and return an unsigned constant value ConstantValue* constValue; Object* obj; switch (lookAhead->tokenType) { case TK_NUMBER: eat(TK_NUMBER); constValue = makeIntConstant(currentToken->value); break; case TK_IDENT: eat(TK_IDENT); obj = lookupObject(currentToken->string); constValue = duplicateConstantValue(obj->constAttrs->value); break; case TK_CHAR: eat(TK_CHAR); constValue = makeCharConstant(currentToken->string[0]); break; default: error(ERR_INVALID_CONSTANT, lookAhead->lineNo, lookAhead->colNo); break; } return constValue; }
void Bat::handleAction(RemoteAction *action, BALL* objectBall) { if (action->typeCode == BatMoveAction::CODE) { // If we are in the same room as the bat and are closer to it than the reporting player, // then we ignore reports and trust our internal state. // Otherwise, use the reported state. BatMoveAction* nextMove = (BatMoveAction*)action; if ((room != objectBall->room) || (objectBall->distanceTo(x, y) > nextMove->distance)) { room = nextMove->room; x = nextMove->posx; y = nextMove->posy; movementX = nextMove->velx; movementY = nextMove->vely; } } else if (action->typeCode == BatPickupAction::CODE) { BatPickupAction* nextPickup = (BatPickupAction*)action; if (nextPickup->dropObject != OBJECT_NONE) { OBJECT* droppedObject = lookupObject(nextPickup->dropObject); droppedObject->x = nextPickup->dropX; droppedObject->y = nextPickup->dropY; } pickupObject(nextPickup->pickupObject, NULL); } }
Object* checkDeclaredConstant(char* name) { Object* obj = lookupObject(name); if (obj == NULL) error(ERR_UNDECLARED_CONSTANT,currentToken->lineNo, currentToken->colNo); if (obj->kind != OBJ_CONSTANT) error(ERR_INVALID_CONSTANT,currentToken->lineNo, currentToken->colNo); return obj; }
Object* checkDeclaredProcedure(char* name) { Object* obj = lookupObject(name); if (obj == NULL) error(ERR_UNDECLARED_PROCEDURE,currentToken->lineNo, currentToken->colNo); else if (obj->kind != OBJ_PROCEDURE) error(ERR_INVALID_PROCEDURE,currentToken->lineNo, currentToken->colNo); return obj; }
Object* checkDeclaredFunction(char* name) { Object* obj = lookupObject(name); if (obj == NULL) error(ERR_UNDECLARED_FUNCTION,currentToken->lineNo, currentToken->colNo); else if (obj->kind != OBJ_FUNCTION) error(ERR_INVALID_FUNCTION,currentToken->lineNo, currentToken->colNo); return obj; }
Object* checkDeclaredVariable(char* name) { Object* obj = lookupObject(name); if (obj == NULL) error(ERR_UNDECLARED_VARIABLE,currentToken->lineNo, currentToken->colNo); else if (obj->kind != OBJ_VARIABLE) error(ERR_INVALID_VARIABLE,currentToken->lineNo, currentToken->colNo); return obj; }
Object* checkDeclaredType(char* name) { Object* obj = lookupObject(name); if (obj == NULL) error(ERR_UNDECLARED_TYPE,currentToken->lineNo, currentToken->colNo); if (obj->kind != OBJ_TYPE) error(ERR_INVALID_TYPE,currentToken->lineNo, currentToken->colNo); return obj; }
Type* compileType(void) { // TODO: create and return a type Type* type = NULL; switch (lookAhead->tokenType) { case KW_INTEGER: eat(KW_INTEGER); type = (Type*) malloc(sizeof(Type)); type->typeClass = TP_INT; break; case KW_CHAR: eat(KW_CHAR); type = (Type*) malloc(sizeof(Type)); type->typeClass = TP_CHAR; break; case KW_ARRAY: type = (Type*) malloc(sizeof(Type)); type->typeClass = TP_ARRAY; eat(KW_ARRAY); eat(SB_LSEL); eat(TK_NUMBER); type->arraySize = currentToken->value; eat(SB_RSEL); eat(KW_OF); type->elementType = compileType(); break; case TK_IDENT: eat(TK_IDENT); Object* obj = lookupObject(currentToken->string); if (obj == NULL) { error(ERR_UNDECLARED_TYPE, currentToken->lineNo, currentToken->colNo); } else if (obj->kind != OBJ_TYPE) { error(ERR_INVALID_TYPE, currentToken->lineNo, currentToken->colNo); } type = duplicateType(obj->typeAttrs->actualType); break; default: error(ERR_INVALID_TYPE, lookAhead->lineNo, lookAhead->colNo); break; } return type; }
Object* checkDeclaredLValueIdent(char* name) { Object* obj = lookupObject(name); if (obj == NULL) error(ERR_UNDECLARED_IDENT,currentToken->lineNo, currentToken->colNo); switch (obj->kind) { case OBJ_VARIABLE: case OBJ_PARAMETER: break; case OBJ_FUNCTION: if (obj != symtab->currentScope->owner) error(ERR_INVALID_IDENT,currentToken->lineNo, currentToken->colNo); break; default: error(ERR_INVALID_IDENT,currentToken->lineNo, currentToken->colNo); } return obj; }
Type* compileType(void) { // TODO: create and return a type Type* type; Type* elementType; int arraySize; Object* obj; switch (lookAhead->tokenType) { case KW_INTEGER: eat(KW_INTEGER); type = makeIntType(); break; case KW_CHAR: eat(KW_CHAR); type = makeCharType(); break; case KW_ARRAY: eat(KW_ARRAY); eat(SB_LSEL); eat(TK_NUMBER); arraySize = currentToken->value; eat(SB_RSEL); eat(KW_OF); elementType = compileType(); type = makeArrayType(arraySize, elementType); break; case TK_IDENT: eat(TK_IDENT); obj = lookupObject(currentToken->string); type = duplicateType(obj->typeAttrs->actualType); break; default: error(ERR_INVALID_TYPE, lookAhead->lineNo, lookAhead->colNo); break; } return type; }
void Bat::moveOneTurn(Sync* sync, BALL* objectBall) { static int flapTimer = 0; if (++flapTimer >= 0x04) { state = (state == 0) ? 1 : 0; flapTimer = 0; } if ((linkedObject != OBJECT_NONE) && (batFedUpTimer < MAX_FEDUP)) ++batFedUpTimer; if (batFedUpTimer >= 0xff) { // Get the bat's current extents int batX, batY, batW, batH; CalcSpriteExtents(&batX, &batY, &batW, &batH); // Enlarge the bat extent by 7 pixels for the proximity checks below // (doing the bat once is faster than doing each object and the results are the same) batX-=7; batY+=7; batW+=7*2; batH+=7*2; // Go through the bat's object matrix const int* matrixP = batMatrix; do { // Get the object it is seeking const OBJECT* seekObject = lookupObject(*matrixP); if ((seekObject->room == room) && (linkedObject != *matrixP)) { int seekX = seekObject->x; int seekY = seekObject->y; // Set the movement int newMoveX = 0; int newMoveY = 0; // horizontal axis if (x < seekX) { newMoveX = BAT_SPEED; } else if (x > seekX) { newMoveX = -BAT_SPEED; } // vertical axis if (y < seekY) { newMoveY = BAT_SPEED; } else if (y > seekY) { newMoveY = -BAT_SPEED; } bool sendMessage = ((newMoveX != movementX) || (newMoveY != movementY)); movementX = newMoveX; movementY = newMoveY; if (sendMessage) { broadcastMoveAction(sync, objectBall); } // If the bat is within 7 pixels of the seek object it can pick the object up // The bat extents have already been expanded by 7 pixels above, so a simple // rectangle intersection test is good enought here int objX, objY, objW, objH; seekObject->CalcSpriteExtents(&objX, &objY, &objW, &objH); if (Board::HitTestRects(batX, batY, batW, batH, objX, objY, objW, objH)) { // Hit something we want pickupObject(*matrixP, sync); } // break since we found something break; } } while (*(++matrixP)); } }