addressType evaluateUnop(void) { int op; addressType arg; nextByte(op); arg = evaluateExpression(); switch(intOp(op)) { case UNARY_MINUS: return(-arg); case LOGICAL_NOT: return(!arg); case BITWISE_NOT: return(~arg); case HI_BYTE: return((arg & 0xFF00) >> 8); case LO_BYTE: return(arg & 0xFF); } }
/* * This is a template method, and is also non-virtual. It doesn't want to be override. * Hook point is * virtual float floatOp(float, float) * virtual int intOp(int, int) */ Literal *BinaryExpression::evaluate() { // if subExpr_ is a var_ref or funcall_call, test would fail. Literal* lLit = 0; Literal* rLit = 0; try { lLit = lhs_->evaluate(); // recursive call rLit = rhs_->evaluate(); // recursive call } catch (std::runtime_error& e) { delete lLit; // if lLit success and rLit failed, leak occurs. Intercept here for avoid leak. throw; // cleanup done, continue issue error. } if (dynamic_cast<FloatLiteral*>(lLit)) { FloatLiteral* l = dynamic_cast<FloatLiteral*>(lLit); if (FloatLiteral* r = dynamic_cast<FloatLiteral*>(rLit)) { FloatLiteral* res = new FloatLiteral( floatOp(l->getValue() , r->getValue()) ); delete l; delete r; return res; } if (IntLiteral* r = dynamic_cast<IntLiteral*>(rLit)) { FloatLiteral* res = new FloatLiteral( floatOp(l->getValue() , r->getValue()) ); delete l; delete r; return res; } } else { IntLiteral* l = dynamic_cast<IntLiteral*>(lLit); if (FloatLiteral* r = dynamic_cast<FloatLiteral*>(rLit)) { FloatLiteral* res = new FloatLiteral( floatOp(l->getValue() , r->getValue()) ); delete l; delete r; return res; } if (IntLiteral* r = dynamic_cast<IntLiteral*>(rLit)) { IntLiteral* res = new IntLiteral( intOp(l->getValue() , r->getValue()) ); delete l; delete r; return res; } } throw std::runtime_error("BinaryExpression::evaluate: unknown error"); }
addressType evaluatePreop(void) { int op; symbolType *target; nextByte(op); target = getSymbol(); switch (intOp(op)) { case INCREMENT: return(++target->symbolValue); case DECREMENT: return(--target->symbolValue); } }
addressType evaluateBinop(void) { int op; symbolType *leftSymbol; addressType left; addressType right; nextByte(op); if (intOp(op) == ASSIGN) { leftSymbol = getSymbol(); } else { left = evaluateExpression(); } right = evaluateExpression(); switch (intOp(op)) { case ASSIGN: leftSymbol->symbolValue = right; return(right); case LOGICAL_OR: return(left || right); case LOGICAL_XOR: return((left && !right) || (!left && right)); case LOGICAL_AND: return(left && right); case BITWISE_OR: return(left | right); case BITWISE_XOR: return(left ^ right); case BITWISE_AND: return(left & right); case EQUAL_TO: return(left == right); case NOT_EQUAL_TO: return(left != right); case LESS_THAN: return(left < right); case LESS_THAN_OR_EQUAL_TO: return(left <= right); case GREATER_THAN: return(left > right); case GREATER_THAN_OR_EQUAL_TO: return(left >= right); case LEFT_SHIFT: return(left << right); case RIGHT_SHIFT: return(left >> right); case ADD: return(left + right); case SUB: return(left - right); case MUL: return(left * right); case DIV: return(left / right); case MOD: return(left % right); } }