ATLAS Offline Software
Loading...
Searching...
No Matches
ParsingInternals.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6// ParsingInternals.cxx, (c) ATLAS Detector software
8// Author: Thomas Gillam (thomas.gillam@cern.ch)
9// ExpressionParsing library
11
12#include "ParsingInternals.h"
13
14#define VM_CASE_UNARY(OP) case op_ ## OP: \
15 stack.back() = stack.back()._ ## OP(); \
16 break
17
18
19
20#define VISITOR_UNARY(OP) else if (x.operator_ == #OP) code.push_back(op_ ## OP)
21
22
23
24namespace ExpressionParsing {
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);
31 stack.pop_back();
32 }
33
34 StackElement VirtualMachine::execute(const EventContext& ctx, std::vector<StackElement> const& code) const
35 {
36 std::vector<StackElement> stack;
37 stack.reserve(m_stackSize);
38
39 std::vector<StackElement>::const_iterator pc = code.begin();
40
41 while (pc != code.end())
42 {
43
44 switch ((pc++)->asInt())
45 {
46 case op_neg: {
47 stack.back() = -std::move(stack.back());
48 break;
49 }
50 case op_not:
51 stack.back() = !std::move(stack.back());
52 break;
53
54 VM_CASE_UNARY(sum);
56 VM_CASE_UNARY(abs);
57 VM_CASE_UNARY(sqrt);
58 VM_CASE_UNARY(cbrt);
59 VM_CASE_UNARY(sin);
60 VM_CASE_UNARY(cos);
61 VM_CASE_UNARY(tan);
62 VM_CASE_UNARY(asin);
63 VM_CASE_UNARY(acos);
64 VM_CASE_UNARY(atan);
65 VM_CASE_UNARY(sinh);
66 VM_CASE_UNARY(cosh);
67 VM_CASE_UNARY(tanh);
68 VM_CASE_UNARY(asinh);
69 VM_CASE_UNARY(acosh);
70 VM_CASE_UNARY(atanh);
71 VM_CASE_UNARY(log);
72 VM_CASE_UNARY(exp);
73
74 case op_and: bin_op(stack,[](StackElement &a, StackElement &b) { a=a._and(b); }); break;
75 case op_or: bin_op(stack,[](StackElement &a, StackElement &b) { a=a._or(b); }); break;
76 case op_eq: bin_op(stack,[](StackElement &a, StackElement &b) { a=a._eq(b); }); break;
77 case op_neq: bin_op(stack,[](StackElement &a, StackElement &b) { a=a._neq(b); }); break;
78 case op_gt: bin_op(stack,[](StackElement &a, StackElement &b) { a=a._gt(b); }); break;
79 case op_gte: bin_op(stack,[](StackElement &a, StackElement &b) { a=a._gte(b); }); break;
80 case op_lt: bin_op(stack,[](StackElement &a, StackElement &b) { a=a._lt(b); }); break;
81 case op_lte: bin_op(stack,[](StackElement &a, StackElement &b) { a=a._lte(b); }); break;
82
83 case op_add: bin_op(stack,[](StackElement &a, StackElement &b) { a += b; }); break;
84 case op_sub: bin_op(stack,[](StackElement &a, StackElement &b) { a -= b; }); break;
85
86 case op_pow: bin_op(stack,[](StackElement &a, StackElement &b) { a = a._pow(b); }); break;
87
88 case op_mul: bin_op(stack,[](StackElement &a, StackElement &b) { a *= b; }); break;
89 case op_div: bin_op(stack,[](StackElement &a, StackElement &b) { a /= b; }); break;
90
91 case op_val:
92 if (pc->isProxy()) {
93 stack.emplace_back(pc->valueFromProxy(ctx));
94 }
95 else {
96 stack.emplace_back(*pc);
97 }
98 ++pc;
99 break;
100 }
101 }
102
103 if (stack.size()!=1){
104 throw std::runtime_error("ExpressionEvaluation: Virtual machine finished in undefined state. Is expression valid?");
105 }
106 return stack.back();
107 }
108
109
110
111 void Compiler::operator()(unsigned int n)
112 {
113 code.push_back(op_val);
114 code.push_back(n);
115 }
116 void Compiler::operator()(bool n)
117 {
118 code.push_back(op_val);
119 code.push_back((int)n);
120 }
121 void Compiler::operator()(double n)
122 {
123 code.push_back(op_val);
124 code.push_back(n);
125 }
126 void Compiler::operator()(const std::string &n)
127 {
128 const IUnitInterpreter *units = m_unitInterpreter;
129
130 code.push_back(op_val);
131 // Intercept special values
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));
137 else code.push_back(StackElement(n, m_proxyLoader));
138 }
139
140 void Compiler::operator()(ast::operation const& x)
141 {
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);
157 }
158
159 void Compiler::operator()(ast::unaryexpr_ const& x)
160 {
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);
164 VISITOR_UNARY(sum);
166 VISITOR_UNARY(abs);
167 VISITOR_UNARY(sqrt);
168 VISITOR_UNARY(cbrt);
169 VISITOR_UNARY(sin);
170 VISITOR_UNARY(cos);
171 VISITOR_UNARY(tan);
172 VISITOR_UNARY(asin);
173 VISITOR_UNARY(acos);
174 VISITOR_UNARY(atan);
175 VISITOR_UNARY(sinh);
176 VISITOR_UNARY(cosh);
177 VISITOR_UNARY(tanh);
178 VISITOR_UNARY(asinh);
179 VISITOR_UNARY(acosh);
180 VISITOR_UNARY(atanh);
181 VISITOR_UNARY(log);
182 VISITOR_UNARY(exp);
183 else if (x.operator_ == "+") ;
184 else BOOST_ASSERT(0);
185 }
186
187 void Compiler::operator()(ast::expression const& x)
188 {
189 boost::apply_visitor(*this, x.first);
190 for(ast::operation const& oper : x.rest)
191 {
192 (*this)(oper);
193 }
194 }
195
196}
static Double_t a
#define VM_CASE_UNARY(OP)
#define VISITOR_UNARY(OP)
#define x
Class describing a single element in a text expression.
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:148
Namespace holding all the expression evaluation code.
void bin_op(std::vector< StackElement > &stack, T_func a_func)