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(std::vector<StackElement>
const& code)
const
36 std::vector<StackElement> stack;
37 stack.reserve(m_stackSize);
40 std::vector<StackElement>::const_iterator pc = code.begin();
42 while (pc != code.end())
44 if (stack.size() > max_stack_size) max_stack_size = stack.size();
46 switch (pc[-1].asInt())
49 stack.back() = -std::move(stack.back());
53 stack.back() = !std::move(stack.back());
95 stack.emplace_back(
pc->valueFromProxy());
98 stack.emplace_back(*pc);
105 if (stack.size()!=1){
106 throw std::runtime_error(
"ExpressionEvaluation: Virtual machine finished in undefined state. Is expression valid?");
116 void Compiler::operator()(
unsigned int n)
118 code.push_back(op_val);
121 void Compiler::operator()(
bool n)
123 code.push_back(op_val);
124 code.push_back((
int)n);
126 void Compiler::operator()(
double n)
128 code.push_back(op_val);
131 void Compiler::operator()(
const std::string &n)
135 code.push_back(op_val);
137 if (n ==
"pi")
code.push_back(3.14159265359);
138 else if (n ==
"e")
code.push_back(2.71828182846);
139 else if (n ==
"kBigNumber")
code.push_back(1234567890);
140 else if (n ==
"kLeinGrossNummer")
code.push_back(123456789);
141 else if (
units->isKnownUnit(n))
code.push_back(
units->unitValue(n));
147 boost::apply_visitor(*
this,
x.operand_);
148 if (
x.operator_ ==
"&&")
code.push_back(op_and);
149 else if (
x.operator_ ==
"||")
code.push_back(op_or);
150 else if (
x.operator_ ==
"==")
code.push_back(op_eq);
151 else if (
x.operator_ ==
"!=")
code.push_back(op_neq);
152 else if (
x.operator_ ==
">")
code.push_back(op_gt);
153 else if (
x.operator_ ==
">=")
code.push_back(op_gte);
154 else if (
x.operator_ ==
"<")
code.push_back(op_lt);
155 else if (
x.operator_ ==
"<=")
code.push_back(op_lte);
156 else if (
x.operator_ ==
"+")
code.push_back(op_add);
157 else if (
x.operator_ ==
"-")
code.push_back(op_sub);
158 else if (
x.operator_ ==
"**")
code.push_back(op_pow);
159 else if (
x.operator_ ==
"*")
code.push_back(op_mul);
160 else if (
x.operator_ ==
"/")
code.push_back(op_div);
161 else BOOST_ASSERT(0);
166 boost::apply_visitor(*
this,
x.operand_);
167 if (
x.operator_ ==
"-")
code.push_back(op_neg);
168 else if (
x.operator_ ==
"!")
code.push_back(op_not);
188 else if (
x.operator_ ==
"+") ;
189 else BOOST_ASSERT(0);
194 boost::apply_visitor(*
this,
x.first);
#define VM_CASE_UNARY(OP)
#define VISITOR_UNARY(OP)
std::atomic< std::size_t > g_maxStackSize
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)
void * StackElement
One element of a stack trace.