OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
evaluator.cpp
Go to the documentation of this file.
1/*=============================================================================
2 Distributed under the Boost Software License, Version 1.0. (See accompanying
3 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4=============================================================================*/
5#include "evaluator.hpp"
6
7#include <boost/variant/apply_visitor.hpp>
8
9namespace client { namespace code_gen {
10
11 bool StackEvaluator::operator()(unsigned int x) {
12 evaluation_stack_.emplace_back(std::in_place_type<double>, static_cast<double>(x));
13 return true;
14 }
15
17 evaluation_stack_.emplace_back(std::in_place_type<double>, x);
18 return true;
19 }
20
22 evaluation_stack_.emplace_back(std::in_place_type<double>, static_cast<double>(x));
23 return true;
24 }
25
27 evaluation_stack_.emplace_back(std::in_place_type<std::string>, x.value);
28 return true;
29 }
30
32
33 auto i = variableDictionary_.find(x.name);
34 if (i == variableDictionary_.end()) {
35 std::cout << "Undefined variable " << x.name << std::endl;
36 return false;
37 }
38
39 evaluation_stack_.emplace_back(std::in_place_type<double>, i->second);
40 return true;
41 }
42
44
45 if (!boost::apply_visitor(*this, x.operand_)) {
46 return false;
47 }
48
49 double op2 = std::get<double>(evaluation_stack_.back());
50 evaluation_stack_.pop_back();
51 double op1 = std::get<double>(evaluation_stack_.back());
52 evaluation_stack_.pop_back();
53 double res = 0.0;
54
55 switch (x.operator_) {
56 case ast::op_plus : res = op1 + op2; break;
57 case ast::op_minus : res = op1 - op2; break;
58 case ast::op_times : res = op1 * op2; break;
59 case ast::op_divide : res = op1 / op2; break;
60
61 case ast::op_equal : res = op1 == op2; break;
62 case ast::op_not_equal : res = op1 != op2; break;
63 case ast::op_less : res = op1 < op2; break;
64 case ast::op_less_equal : res = op1 <= op2; break;
65 case ast::op_greater : res = op1 > op2; break;
66 case ast::op_greater_equal : res = op1 >= op2; break;
67
68 case ast::op_and : res = op1 && op2; break;
69 case ast::op_or : res = op1 || op2; break;
70 default : BOOST_ASSERT(0); return false;
71 }
72
73 evaluation_stack_.emplace_back(std::in_place_type<double>, res);
74 return true;
75 }
76
78
79 if (!boost::apply_visitor(*this, x.operand_))
80 return false;
81
82 double op = std::get<double>(evaluation_stack_.back());
83 evaluation_stack_.pop_back();
84
85 switch (x.operator_) {
86 case ast::op_negative : op = -op; break;
87 case ast::op_not : op = !op; break;
88 case ast::op_positive : break;
89 default : BOOST_ASSERT(0); return false;
90 }
91
92 evaluation_stack_.emplace_back(std::in_place_type<double>, op);
93 return true;
94 }
95
97
98 for (ast::function_call_argument const& arg : x.args) {
99 if (!boost::apply_visitor(*this, arg))
100 return false;
101 }
102
103 std::vector<client::function::argument_t> args(x.args.size());
104 for (size_t i = 0; i < x.args.size(); ++i) {
105 args[x.args.size() - 1 - i] = std::move(evaluation_stack_.back());
106 evaluation_stack_.pop_back();
107 }
108
109 std::map<std::string, client::function::type>::iterator itr =
111 if (itr == functions_.end()) {
112 std::cout << "Undefined function "
113 << x.function_name.name << std::endl;
114 return false;
115 }
116
117 auto function_eval = itr->second(args);
118 if (!std::get<1>(function_eval)) {
119 return false;
120 }
121
122 double function_result = std::get<0>(function_eval);
123 evaluation_stack_.emplace_back(std::in_place_type<double>, function_result);
124
125 return true;
126 }
127
129
130 if (!boost::apply_visitor(*this, x.first))
131 return false;
132
133 for (ast::operation const& oper : x.rest) {
134 if (!(*this)(oper))
135 return false;
136 }
137
138 return true;
139 }
140
141}}
arg(a))
@ op_plus
Definition ast.hpp:65
@ op_not_equal
Definition ast.hpp:73
@ op_less
Definition ast.hpp:74
@ op_equal
Definition ast.hpp:72
@ op_times
Definition ast.hpp:67
@ op_minus
Definition ast.hpp:66
@ op_less_equal
Definition ast.hpp:75
@ op_greater
Definition ast.hpp:76
@ op_greater_equal
Definition ast.hpp:77
@ op_positive
Definition ast.hpp:69
@ op_negative
Definition ast.hpp:70
@ op_divide
Definition ast.hpp:68
boost::variant< expression, quoted_string > function_call_argument
Definition ast.hpp:61
std::string name
Definition ast.hpp:36
operand operand_
Definition ast.hpp:85
optoken operator_
Definition ast.hpp:84
std::list< function_call_argument > args
Definition ast.hpp:97
identifier function_name
Definition ast.hpp:96
std::list< operation > rest
Definition ast.hpp:103
client::function::arguments_t evaluation_stack_
Definition evaluator.hpp:86
std::map< std::string, client::function::type > functions_
Definition evaluator.hpp:83
std::map< std::string, double > variableDictionary_
Definition evaluator.hpp:82