Пример #1
0
ExprValue Expression::getPropertyValue(const std::string& propertyName) {
    auto callback = properties_.find(propertyName);
    if (callback == properties_.end()) {
        throw EvaluateException(str(boost::format("Property callback not set for property '%s'") % propertyName));
    }
    return callback->second();
}
Пример #2
0
void OpApply::Apply(Expression *expression, Calculator *calculator, int32 recursions)
{
	if(expression->LeafCount() != 2)
		throw EvaluateException("Apply expects 2 operands.");
	// If second operand is Atom, return that Atom. Otherwise replace head of second operand
	// by first operand.
	if(!expression->Leaf(1)->IsAtom())
	{
		delete expression->Leaf(1)->Head();
		expression->Leaf(1)->Head(expression->Leaf(0));
	}
	expression->Leaves().erase(expression->Leaves().begin());
	expression->AssignLeaf(0);
	expression->Evaluate(calculator, recursions);
}
Пример #3
0
void OpMap::Apply(Expression *expression, Calculator *calculator, int32 recursions)
{
	if(expression->LeafCount() != 2)
		throw EvaluateException("Map expects 2 operands.");
	Expression *head = expression->Leaf(0);
	Expression *list = expression->Leaf(1);
	for(ExprVector::iterator leaf = list->Leaves().begin(); leaf != list->Leaves().end(); ++leaf)
	{
		ExprPtr operation(new Expression());
		operation->Head(head->Clone());
		operation->AppendLeaf(*leaf);
		*leaf = operation.release();
	}
	expression->AssignLeaf(1);
	expression->Evaluate(calculator, recursions);
}
Пример #4
0
ExprValue Expression::calcTree(const ExprNodePtr& tree) {
    switch (tree->operationType) {
    case  OP_VARIABLE:
        return getPropertyValue(boost::get<std::string>(tree->value));
    case OP_VALUE:
        return tree->value;
    case OP_PLUS:
        try {
            return boost::get<ExprInteger>(calcTree(tree->left)) + boost::get<ExprInteger>(calcTree(tree->right));
        } catch (boost::bad_get&) {
            throw EvaluateException("Invalid argument for operator '+'");
        }
    case OP_MINUS:
        try {
            return boost::get<ExprInteger>(calcTree(tree->left)) - boost::get<ExprInteger>(calcTree(tree->right));
        } catch (boost::bad_get&) {
            throw EvaluateException("Invalid argument for operator '-'");
        }
    case OP_MULTIPLY:
        try {
            return boost::get<ExprInteger>(calcTree(tree->left)) * boost::get<ExprInteger>(calcTree(tree->right));
        } catch (boost::bad_get&) {
            throw EvaluateException("Invalid argument for operator '*'");
        }
    case OP_DIVIDE:
        try {
            return boost::get<ExprInteger>(calcTree(tree->left)) * boost::get<ExprInteger>(calcTree(tree->right));
        } catch (boost::bad_get&) {
            throw EvaluateException("Invalid argument for operator '*'");
        }
    case OP_CONTAINS:
        return operationContains(tree);
    case OP_LESS:
    case OP_LESSOREQUAL:
    case OP_GREATER:
    case OP_GREATEROREQUAL:
        return operationCompare(tree);
    case OP_EQUAL:
        return operationEquals(tree);
    case OP_NOTEQUAL:
        return operationNotEquals(tree);
    case OP_UMINUS:
        try {
            return -boost::get<ExprInteger>(calcTree(tree->left));
        } catch (boost::bad_get&) {
            throw EvaluateException("Invalid argument for unary minus operator");
        }
    case OP_NOT:
        return operationIsNot(tree);
        /*try {
            return !boost::get<bool>(calcTree(tree->left));
        } catch (boost::bad_get&) {
            throw EvaluateException("Invalid argument for 'not' operator");
        }*/
    case OP_OR:
    case OP_AND:
        return operationLogical(tree);
    case OP_IS:
        return operationIs(tree);
    case OP_FUNCTIONCALL:
        {
        ExprValue left = calcTree(tree->left);
        return runtimeInfo_->callFunction(tree, left);
        }
    default:
        throw ParserException(str(boost::format("Unknown operation %d") % static_cast<int>(tree->operationType)), 0);
    }
}
Пример #5
0
 bool operator()(const T &, const U &) const
 {
     throw EvaluateException("Cannot compare different types");
 }