14#define VM_CASE_UNARY(OP) case op_ ## OP: \
15 stack.back() = stack.back()._ ## OP(); \
20#define VISITOR_UNARY(OP) else if (x.operator_ == #OP) code.push_back(op_ ## OP)
25 template <
class T_func>
26 void bin_op( std::vector<StackElement> &stack, T_func a_func) {
27 assert( stack.size() >= 2);
28 std::vector<ExpressionParsing::StackElement>::iterator last_elm = stack.end()-1;
29 std::vector<ExpressionParsing::StackElement>::iterator second_last_elm = stack.end()-2;
30 a_func(*second_last_elm, *last_elm);
34 StackElement VirtualMachine::execute(
const EventContext& ctx, std::vector<StackElement>
const& code)
const
36 std::vector<StackElement> stack;
37 stack.reserve(m_stackSize);
39 std::vector<StackElement>::const_iterator pc = code.begin();
41 while (pc != code.end())
44 switch ((pc++)->asInt())
47 stack.back() = -std::move(stack.back());
51 stack.back() = !std::move(stack.back());
93 stack.emplace_back(
pc->valueFromProxy(ctx));
96 stack.emplace_back(*pc);
103 if (stack.size()!=1){
104 throw std::runtime_error(
"ExpressionEvaluation: Virtual machine finished in undefined state. Is expression valid?");
111 void Compiler::operator()(
unsigned int n)
113 code.push_back(op_val);
116 void Compiler::operator()(
bool n)
118 code.push_back(op_val);
119 code.push_back((
int)n);
121 void Compiler::operator()(
double n)
123 code.push_back(op_val);
126 void Compiler::operator()(
const std::string &n)
130 code.push_back(op_val);
132 if (n ==
"pi")
code.push_back(3.14159265359);
133 else if (n ==
"e")
code.push_back(2.71828182846);
134 else if (n ==
"kBigNumber")
code.push_back(1234567890);
135 else if (n ==
"kLeinGrossNummer")
code.push_back(123456789);
136 else if (
units->isKnownUnit(n))
code.push_back(
units->unitValue(n));
142 boost::apply_visitor(*
this,
x.operand_);
143 if (
x.operator_ ==
"&&")
code.push_back(op_and);
144 else if (
x.operator_ ==
"||")
code.push_back(op_or);
145 else if (
x.operator_ ==
"==")
code.push_back(op_eq);
146 else if (
x.operator_ ==
"!=")
code.push_back(op_neq);
147 else if (
x.operator_ ==
">")
code.push_back(op_gt);
148 else if (
x.operator_ ==
">=")
code.push_back(op_gte);
149 else if (
x.operator_ ==
"<")
code.push_back(op_lt);
150 else if (
x.operator_ ==
"<=")
code.push_back(op_lte);
151 else if (
x.operator_ ==
"+")
code.push_back(op_add);
152 else if (
x.operator_ ==
"-")
code.push_back(op_sub);
153 else if (
x.operator_ ==
"**")
code.push_back(op_pow);
154 else if (
x.operator_ ==
"*")
code.push_back(op_mul);
155 else if (
x.operator_ ==
"/")
code.push_back(op_div);
156 else BOOST_ASSERT(0);
161 boost::apply_visitor(*
this,
x.operand_);
162 if (
x.operator_ ==
"-")
code.push_back(op_neg);
163 else if (
x.operator_ ==
"!")
code.push_back(op_not);
183 else if (
x.operator_ ==
"+") ;
184 else BOOST_ASSERT(0);
189 boost::apply_visitor(*
this,
x.first);
#define VM_CASE_UNARY(OP)
#define VISITOR_UNARY(OP)
Class describing a single element in a text expression.
int count(std::string s, const std::string ®x)
count how many occurances of a regx are in a string
Namespace holding all the expression evaluation code.
void bin_op(std::vector< StackElement > &stack, T_func a_func)