AnimExpression::OpCode AnimExpression::evaluate(const AnimVariantMap& map) const { std::stack<OpCode> stack; for (auto& opCode : _opCodes) { switch (opCode.type) { case OpCode::Identifier: case OpCode::Int: case OpCode::Float: case OpCode::Bool: stack.push(opCode); break; case OpCode::And: evalAnd(map, stack); break; case OpCode::Or: evalOr(map, stack); break; case OpCode::GreaterThan: evalGreaterThan(map, stack); break; case OpCode::GreaterThanEqual: evalGreaterThanEqual(map, stack); break; case OpCode::LessThan: evalLessThan(map, stack); break; case OpCode::LessThanEqual: evalLessThanEqual(map, stack); break; case OpCode::Equal: evalEqual(map, stack); break; case OpCode::NotEqual: evalNotEqual(map, stack); break; case OpCode::Not: evalNot(map, stack); break; case OpCode::Subtract: evalSubtract(map, stack); break; case OpCode::Add: evalAdd(map, stack); break; case OpCode::Multiply: evalMultiply(map, stack); break; case OpCode::Divide: evalDivide(map, stack); break; case OpCode::Modulus: evalModulus(map, stack); break; case OpCode::UnaryMinus: evalUnaryMinus(map, stack); break; } } return coerseToValue(map, stack.top()); }
ExpressionResult* evalNotEqual(const BSONObj& bson, BaseExpression* left, BaseExpression* right) { ExpressionResult* TempResult = evalEqual(bson, left, right); bool bresult = *TempResult; ExpressionResult* result = new ExpressionResult(!bresult); delete TempResult; return result; }
ExpressionResult* evalComparison(const BSONObj& bson, const FILTER_OPERATORS& oper, BaseExpression* left, BaseExpression* right) { ExpressionResult* valLeft = left->eval(bson); ExpressionResult* valRight= right->eval(bson); if (valLeft->type() != valRight->type()) { // ERROR types does not match delete valLeft; delete valRight; return new ExpressionResult(false); } bool resultGreather = false; // this will compare only greather than, and at the end will invert // based on the sign if ((valLeft->type() != ExpressionResult::RT_NULL) && (valRight->type() == ExpressionResult::RT_NULL)) { resultGreather = true; } else if (((valLeft->type() == ExpressionResult::RT_NULL) && (valRight->type() != ExpressionResult::RT_NULL))) { resultGreather = false; } else { switch (valLeft->type()) { case ExpressionResult::RT_INT: resultGreather = ((__int32)*valLeft > (__int32)*valRight); break; case ExpressionResult::RT_LONG: case ExpressionResult::RT_LONG64: resultGreather = ((__int64)*valLeft > (__int64)*valRight); break; case ExpressionResult::RT_DOUBLE: resultGreather = ((double)*valLeft > (double)*valRight); break; } } ExpressionResult* result = NULL; if ((!resultGreather && (oper == FO_GREATEREQUALTHAN)) || (resultGreather && (oper == FO_LESSEQUALTHAN))) { result = evalEqual(bson, left, right); } else { bool bres; if ((oper == FO_LESSTHAN) || (oper == FO_LESSEQUALTHAN)) { bres = !resultGreather; }else { bres = resultGreather; } result = new ExpressionResult(bres); } delete valLeft; delete valRight; return result; }
ExpressionResult* BinaryExpression::eval(const BSONObj& bson) { switch (_oper) { case FO_EQUALS: return evalEqual(bson, _left, _right); case FO_NOT_EQUALS: return evalNotEqual(bson, _left, _right); case FO_AND: case FO_OR: return evalAndOr(bson, _oper, _left, _right); case FO_LESSTHAN: case FO_LESSEQUALTHAN: case FO_GREATERTHAN: case FO_GREATEREQUALTHAN: return evalComparison(bson, _oper, _left, _right); } }