include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
add_library(config SHARED
- aexpression.cpp applyrule.cpp avalue.cpp base-type.conf base-type.cpp
+ aexpression.cpp applyrule.cpp base-type.conf base-type.cpp
configcompilercontext.cpp configcompiler.cpp configerror.cpp configitembuilder.cpp
configitem.cpp ${FLEX_config_lexer_OUTPUTS} ${BISON_config_parser_OUTPUTS}
configtype.cpp debuginfo.cpp expression.cpp expressionlist.cpp typerule.cpp typerulelist.cpp
#include "base/serializer.h"
#include "base/context.h"
#include "base/scriptfunction.h"
+#include "base/scriptvariable.h"
#include <boost/foreach.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/exception/errinfo_nested_exception.hpp>
using namespace icinga;
-AExpression::AExpression(AOperator op, const AValue& operand1, const DebugInfo& di)
+AExpression::AExpression(OpCallback op, const Value& operand1, const DebugInfo& di)
: m_Operator(op), m_Operand1(operand1), m_DebugInfo(di)
+{ }
+
+AExpression::AExpression(OpCallback op, const Value& operand1, const Value& operand2, const DebugInfo& di)
+ : m_Operator(op), m_Operand1(operand1), m_Operand2(operand2), m_DebugInfo(di)
+{ }
+
+Value AExpression::Evaluate(const Dictionary::Ptr& locals) const
{
- ASSERT(op == AEReturn);
+ try {
+ return (this->*m_Operator)(locals);
+ } catch (const std::exception& ex) {
+ if (boost::get_error_info<boost::errinfo_nested_exception>(ex))
+ throw;
+ else
+ BOOST_THROW_EXCEPTION(ConfigError("Error while evaluating expression.") << boost::errinfo_nested_exception(boost::current_exception()) << errinfo_debuginfo(m_DebugInfo));
+ }
}
-AExpression::AExpression(AOperator op, const AValue& operand1, const AValue& operand2, const DebugInfo& di)
- : m_Operator(op), m_Operand1(operand1), m_Operand2(operand2), m_DebugInfo(di)
+Value AExpression::EvaluateOperand1(const Dictionary::Ptr& locals) const
{
- ASSERT(op == AEAdd || op == AENegate || op == AESubtract || op == AEMultiply || op == AEDivide ||
- op == AEBinaryAnd || op == AEBinaryOr || op == AEShiftLeft || op == AEShiftRight ||
- op == AEEqual || op == AENotEqual || op == AEIn || op == AENotIn ||
- op == AELogicalAnd || op == AELogicalOr || op == AEFunctionCall);
+ return static_cast<AExpression::Ptr>(m_Operand1)->Evaluate(locals);
}
-Value AExpression::Evaluate(const Dictionary::Ptr& locals) const
+Value AExpression::EvaluateOperand2(const Dictionary::Ptr& locals) const
+{
+ return static_cast<AExpression::Ptr>(m_Operand2)->Evaluate(locals);
+}
+
+Value AExpression::OpLiteral(const Dictionary::Ptr& locals) const
+{
+ return m_Operand1;
+}
+
+Value AExpression::OpVariable(const Dictionary::Ptr& locals) const
+{
+ if (locals && locals->Contains(m_Operand1))
+ return locals->Get(m_Operand1);
+ else
+ return ScriptVariable::Get(m_Operand1);
+}
+
+Value AExpression::OpNegate(const Dictionary::Ptr& locals) const
+{
+ return ~(long)EvaluateOperand1(locals);
+}
+
+Value AExpression::OpAdd(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) + EvaluateOperand2(locals);
+}
+
+Value AExpression::OpSubtract(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) - EvaluateOperand2(locals);
+}
+
+Value AExpression::OpMultiply(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) * EvaluateOperand2(locals);
+}
+
+Value AExpression::OpDivide(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) / EvaluateOperand2(locals);
+}
+
+Value AExpression::OpBinaryAnd(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) & EvaluateOperand2(locals);
+}
+
+Value AExpression::OpBinaryOr(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) | EvaluateOperand2(locals);
+}
+
+Value AExpression::OpShiftLeft(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) << EvaluateOperand2(locals);
+}
+
+Value AExpression::OpShiftRight(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) >> EvaluateOperand2(locals);
+}
+
+Value AExpression::OpEqual(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) == EvaluateOperand2(locals);
+}
+
+Value AExpression::OpNotEqual(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) != EvaluateOperand2(locals);
+}
+
+Value AExpression::OpLessThan(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) < EvaluateOperand2(locals);
+}
+
+Value AExpression::OpGreaterThan(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) > EvaluateOperand2(locals);
+}
+
+Value AExpression::OpLessThanOrEqual(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) <= EvaluateOperand2(locals);
+}
+
+Value AExpression::OpGreaterThanOrEqual(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals) >= EvaluateOperand2(locals);
+}
+
+Value AExpression::OpIn(const Dictionary::Ptr& locals) const
{
- Value left, right;
- Array::Ptr arr, arr2;
- bool found;
- String funcName;
- ScriptFunction::Ptr func;
+ Value right = EvaluateOperand1(locals);
+
+ if (!right.IsObjectType<Array>())
+ BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonSerialize(right)));
+
+ Value left = EvaluateOperand2(locals);
+
+ Array::Ptr arr = right;
+ bool found = false;
+ BOOST_FOREACH(const Value& value, arr) {
+ if (value == left) {
+ found = true;
+ break;
+ }
+ }
+
+ return found;
+}
+
+Value AExpression::OpNotIn(const Dictionary::Ptr& locals) const
+{
+ return !OpIn(locals);
+}
+
+Value AExpression::OpLogicalAnd(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals).ToBool() && EvaluateOperand2(locals).ToBool();
+}
+
+Value AExpression::OpLogicalOr(const Dictionary::Ptr& locals) const
+{
+ return EvaluateOperand1(locals).ToBool() || EvaluateOperand2(locals).ToBool();
+}
+
+Value AExpression::OpFunctionCall(const Dictionary::Ptr& locals) const
+{
+ String funcName = m_Operand1;
+ ScriptFunction::Ptr func = ScriptFunctionRegistry::GetInstance()->GetItem(funcName);
+
+ if (!func)
+ BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist."));
+
+ Array::Ptr arr = EvaluateOperand2(locals);
std::vector<Value> arguments;
+ BOOST_FOREACH(const AExpression::Ptr& aexpr, arr) {
+ arguments.push_back(aexpr->Evaluate(locals));
+ }
- left = m_Operand1.Evaluate(locals);
- right = m_Operand2.Evaluate(locals);
+ return func->Invoke(arguments);
+}
- std::ostringstream msgbuf;
- msgbuf << "Evaluating AExpression " << m_DebugInfo << "; left=" << JsonSerialize(left) << "; right=" << JsonSerialize(right);
- CONTEXT(msgbuf.str());
+Value AExpression::OpArray(const Dictionary::Ptr& locals) const
+{
+ Array::Ptr arr = m_Operand1;
+ Array::Ptr result = make_shared<Array>();
- try {
- switch (m_Operator) {
- case AEReturn:
- return left;
- case AENegate:
- return ~(long)left;
- case AEAdd:
- return left + right;
- case AESubtract:
- return left - right;
- case AEMultiply:
- return left * right;
- case AEDivide:
- return left / right;
- case AEBinaryAnd:
- return left & right;
- case AEBinaryOr:
- return left | right;
- case AEShiftLeft:
- return left << right;
- case AEShiftRight:
- return left >> right;
- case AEEqual:
- return left == right;
- case AENotEqual:
- return left != right;
- case AELessThan:
- return left < right;
- case AEGreaterThan:
- return left > right;
- case AELessThanOrEqual:
- return left <= right;
- case AEGreaterThanOrEqual:
- return left >= right;
- case AEIn:
- if (!right.IsObjectType<Array>())
- BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonSerialize(right)));
-
- arr = right;
- found = false;
- BOOST_FOREACH(const Value& value, arr) {
- if (value == left) {
- found = true;
- break;
- }
- }
-
- return found;
- case AENotIn:
- if (!right.IsObjectType<Array>())
- BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonSerialize(right)));
-
- arr = right;
- found = false;
- BOOST_FOREACH(const Value& value, arr) {
- if (value == left) {
- found = true;
- break;
- }
- }
-
- return !found;
- case AELogicalAnd:
- return left.ToBool() && right.ToBool();
- case AELogicalOr:
- return left.ToBool() || right.ToBool();
- case AEFunctionCall:
- funcName = left;
- func = ScriptFunctionRegistry::GetInstance()->GetItem(funcName);
-
- if (!func)
- BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist."));
-
- arr = right;
- BOOST_FOREACH(const AExpression::Ptr& aexpr, arr) {
- arguments.push_back(aexpr->Evaluate(locals));
- }
-
- return func->Invoke(arguments);
- case AEArray:
- arr = left;
- arr2 = make_shared<Array>();
-
- if (arr) {
- BOOST_FOREACH(const AExpression::Ptr& aexpr, arr) {
- arr2->Add(aexpr->Evaluate(locals));
- }
- }
-
- return arr2;
- default:
- ASSERT(!"Invalid operator.");
+ if (arr) {
+ BOOST_FOREACH(const AExpression::Ptr& aexpr, arr) {
+ result->Add(aexpr->Evaluate(locals));
}
- } catch (const std::exception& ex) {
- if (boost::get_error_info<boost::errinfo_nested_exception>(ex))
- throw;
- else
- BOOST_THROW_EXCEPTION(ConfigError("Error while evaluating expression.") << boost::errinfo_nested_exception(boost::current_exception()) << errinfo_debuginfo(m_DebugInfo));
}
+
+ return result;
}
#define AEXPRESSION_H
#include "config/i2-config.h"
-#include "config/avalue.h"
#include "config/debuginfo.h"
#include "base/dictionary.h"
namespace icinga
{
-/**
- * @ingroup config
- */
-enum AOperator
-{
- AEReturn,
- AENegate,
- AEAdd,
- AESubtract,
- AEMultiply,
- AEDivide,
- AEBinaryAnd,
- AEBinaryOr,
- AEShiftLeft,
- AEShiftRight,
- AEEqual,
- AENotEqual,
- AEIn,
- AENotIn,
- AELogicalAnd,
- AELogicalOr,
- AEFunctionCall,
- AEArray,
- AELessThan,
- AEGreaterThan,
- AELessThanOrEqual,
- AEGreaterThanOrEqual
-};
-
/**
* @ingroup config
*/
{
public:
DECLARE_PTR_TYPEDEFS(AExpression);
+
+ typedef Value (AExpression::*OpCallback)(const Dictionary::Ptr&) const;
- AExpression(AOperator op, const AValue& operand1, const DebugInfo& di);
- AExpression(AOperator op, const AValue& operand1, const AValue& operand2, const DebugInfo& di);
+ AExpression(OpCallback op, const Value& operand1, const DebugInfo& di);
+ AExpression(OpCallback op, const Value& operand1, const Value& operand2, const DebugInfo& di);
Value Evaluate(const Dictionary::Ptr& locals) const;
+ Value OpLiteral(const Dictionary::Ptr& locals) const;
+ Value OpVariable(const Dictionary::Ptr& locals) const;
+ Value OpNegate(const Dictionary::Ptr& locals) const;
+ Value OpAdd(const Dictionary::Ptr& locals) const;
+ Value OpSubtract(const Dictionary::Ptr& locals) const;
+ Value OpMultiply(const Dictionary::Ptr& locals) const;
+ Value OpDivide(const Dictionary::Ptr& locals) const;
+ Value OpBinaryAnd(const Dictionary::Ptr& locals) const;
+ Value OpBinaryOr(const Dictionary::Ptr& locals) const;
+ Value OpShiftLeft(const Dictionary::Ptr& locals) const;
+ Value OpShiftRight(const Dictionary::Ptr& locals) const;
+ Value OpEqual(const Dictionary::Ptr& locals) const;
+ Value OpNotEqual(const Dictionary::Ptr& locals) const;
+ Value OpLessThan(const Dictionary::Ptr& locals) const;
+ Value OpGreaterThan(const Dictionary::Ptr& locals) const;
+ Value OpLessThanOrEqual(const Dictionary::Ptr& locals) const;
+ Value OpGreaterThanOrEqual(const Dictionary::Ptr& locals) const;
+ Value OpIn(const Dictionary::Ptr& locals) const;
+ Value OpNotIn(const Dictionary::Ptr& locals) const;
+ Value OpLogicalAnd(const Dictionary::Ptr& locals) const;
+ Value OpLogicalOr(const Dictionary::Ptr& locals) const;
+ Value OpFunctionCall(const Dictionary::Ptr& locals) const;
+ Value OpArray(const Dictionary::Ptr& locals) const;
+
private:
- AOperator m_Operator;
- AValue m_Operand1;
- AValue m_Operand2;
+ OpCallback m_Operator;
+ Value m_Operand1;
+ Value m_Operand2;
DebugInfo m_DebugInfo;
+
+ Value EvaluateOperand1(const Dictionary::Ptr& locals) const;
+ Value EvaluateOperand2(const Dictionary::Ptr& locals) const;
};
}
aexpression: T_STRING
{
- $$ = new Value(make_shared<AExpression>(AEReturn, AValue(ATSimple, $1), @1));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpLiteral, $1, @1));
free($1);
}
| T_NUMBER
{
- $$ = new Value(make_shared<AExpression>(AEReturn, AValue(ATSimple, $1), @1));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpLiteral, $1, @1));
}
| T_NULL
{
- $$ = new Value(make_shared<AExpression>(AEReturn, AValue(ATSimple, Empty), @1));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpLiteral, Empty, @1));
}
| T_IDENTIFIER '(' array_items ')'
{
Array::Ptr arguments = Array::Ptr($3);
- $$ = new Value(make_shared<AExpression>(AEFunctionCall, AValue(ATSimple, $1), AValue(ATSimple, arguments), DebugInfoRange(@1, @4)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpFunctionCall, $1, make_shared<AExpression>(&AExpression::OpLiteral, arguments, @3), DebugInfoRange(@1, @4)));
free($1);
}
| T_IDENTIFIER
{
- $$ = new Value(make_shared<AExpression>(AEReturn, AValue(ATVariable, $1), @1));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpVariable, $1, @1));
free($1);
}
| '!' aexpression
{
- $$ = new Value(make_shared<AExpression>(AENegate, static_cast<AExpression::Ptr>(*$2), DebugInfoRange(@1, @2)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpNegate, static_cast<AExpression::Ptr>(*$2), DebugInfoRange(@1, @2)));
delete $2;
}
| '~' aexpression
{
- $$ = new Value(make_shared<AExpression>(AENegate, static_cast<AExpression::Ptr>(*$2), DebugInfoRange(@1, @2)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpNegate, static_cast<AExpression::Ptr>(*$2), DebugInfoRange(@1, @2)));
delete $2;
}
| '[' array_items ']'
{
- $$ = new Value(make_shared<AExpression>(AEArray, AValue(ATSimple, Array::Ptr($2)), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpArray, Array::Ptr($2), DebugInfoRange(@1, @3)));
}
| '(' aexpression ')'
{
}
| aexpression '+' aexpression
{
- $$ = new Value(make_shared<AExpression>(AEAdd, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpAdd, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression '-' aexpression
{
- $$ = new Value(make_shared<AExpression>(AESubtract, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpSubtract, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression '*' aexpression
{
- $$ = new Value(make_shared<AExpression>(AEMultiply, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpMultiply, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression '/' aexpression
{
- $$ = new Value(make_shared<AExpression>(AEDivide, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpDivide, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression '&' aexpression
{
- $$ = new Value(make_shared<AExpression>(AEBinaryAnd, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpBinaryAnd, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression '|' aexpression
{
- $$ = new Value(make_shared<AExpression>(AEBinaryOr, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @2)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpBinaryOr, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @2)));
delete $1;
delete $3;
}
| aexpression T_IN aexpression
{
- $$ = new Value(make_shared<AExpression>(AEIn, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpIn, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression T_NOT_IN aexpression
{
- $$ = new Value(make_shared<AExpression>(AENotIn, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpNotIn, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression T_LESS_THAN_OR_EQUAL aexpression
{
- $$ = new Value(make_shared<AExpression>(AELessThanOrEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpLessThanOrEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression T_GREATER_THAN_OR_EQUAL aexpression
{
- $$ = new Value(make_shared<AExpression>(AEGreaterThanOrEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpGreaterThanOrEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression '<' aexpression
{
- $$ = new Value(make_shared<AExpression>(AELessThan, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpLessThan, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression '>' aexpression
{
- $$ = new Value(make_shared<AExpression>(AEGreaterThan, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpGreaterThan, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression T_EQUAL aexpression
{
- $$ = new Value(make_shared<AExpression>(AEEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression T_NOT_EQUAL aexpression
{
- $$ = new Value(make_shared<AExpression>(AENotEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpNotEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression T_SHIFT_LEFT aexpression
{
- $$ = new Value(make_shared<AExpression>(AEShiftLeft, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpShiftLeft, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression T_SHIFT_RIGHT aexpression
{
- $$ = new Value(make_shared<AExpression>(AEShiftRight, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpShiftRight, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression T_LOGICAL_AND aexpression
{
- $$ = new Value(make_shared<AExpression>(AELogicalAnd, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpLogicalAnd, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
| aexpression T_LOGICAL_OR aexpression
{
- $$ = new Value(make_shared<AExpression>(AELogicalOr, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
+ $$ = new Value(make_shared<AExpression>(&AExpression::OpLogicalOr, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
delete $1;
delete $3;
}
arguments->Add(*$8);
delete $8;
- AExpression::Ptr aexpr = make_shared<AExpression>(AEFunctionCall, AValue(ATSimple, "bool"), AValue(ATSimple, arguments), @8);
+ AExpression::Ptr aexpr = make_shared<AExpression>(&AExpression::OpFunctionCall, "bool", make_shared<AExpression>(&AExpression::OpLiteral, arguments, @8), @8);
ApplyRule::AddRule($3, $4, $6, aexpr, DebugInfoRange(@1, @8));
}
Array::Ptr array;
switch (m_Operator) {
- case OperatorNop:
- /* Nothing to do here. */
-
- return;
-
case OperatorExecute:
if (!valueExprl)
BOOST_THROW_EXCEPTION(std::invalid_argument("Operand for OperatorExecute must be an ExpressionList."));
}
}
-void Expression::ExtractFiltered(const std::set<String>& keys, const shared_ptr<ExpressionList>& result) const
-{
- if (keys.find(m_Key) != keys.end()) {
- result->AddExpression(*this);
- } else if (m_Operator == OperatorExecute) {
- ExpressionList::Ptr exprl = m_Value;
- exprl->ExtractFiltered(keys, result);
- }
-}
-
-void Expression::ErasePath(const std::vector<String>& path)
-{
- ASSERT(!path.empty());
-
- if (path[0] == m_Key) {
- if (path.size() == 1) {
- m_Operator = OperatorNop;
- } else if (m_Value.IsObjectType<ExpressionList>()) {
- ExpressionList::Ptr exprl = m_Value;
-
- std::vector<String> sub_path(path.begin() + 1, path.end());
- exprl->ErasePath(sub_path);
- }
- } else if (m_Operator == OperatorExecute) {
- ExpressionList::Ptr exprl = m_Value;
- exprl->ErasePath(path);
- }
-}
-
void Expression::FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const
{
ASSERT(!path.empty());
*/
enum ExpressionOperator
{
- OperatorNop,
OperatorExecute,
OperatorSet,
OperatorPlus,
void Execute(const Dictionary::Ptr& dictionary) const;
void ExtractPath(const std::vector<String>& path, const shared_ptr<ExpressionList>& result) const;
- void ExtractFiltered(const std::set<String>& keys, const shared_ptr<ExpressionList>& result) const;
-
- void ErasePath(const std::vector<String>& path);
void FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const;
m_Expressions.push_back(expression);
}
-/**
- * Returns the number of items currently contained in the expression list.
- *
- * @returns The length of the list.
- */
-size_t ExpressionList::GetLength(void) const
-{
- return m_Expressions.size();
-}
-
/**
* Executes the expression list.
*
}
}
-void ExpressionList::ExtractFiltered(const std::set<String>& keys, const ExpressionList::Ptr& result) const
-{
- BOOST_FOREACH(const Expression& expression, m_Expressions) {
- expression.ExtractFiltered(keys, result);
- }
-}
-
-void ExpressionList::ErasePath(const std::vector<String>& path)
-{
- BOOST_FOREACH(Expression& expression, m_Expressions) {
- expression.ErasePath(path);
- }
-}
-
void ExpressionList::FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const
{
BOOST_FOREACH(const Expression& expression, m_Expressions) {
void Execute(const Dictionary::Ptr& dictionary) const;
- size_t GetLength(void) const;
-
void ExtractPath(const std::vector<String>& path, const ExpressionList::Ptr& result) const;
- void ExtractFiltered(const std::set<String>& keys, const ExpressionList::Ptr& result) const;
-
- void ErasePath(const std::vector<String>& path);
void FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const;