Zigbee Protocol Controller 1.6.0
attribute_mapper_ast_reducer.hpp
Go to the documentation of this file.
1/******************************************************************************
2 * # License
3 * <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
4 ******************************************************************************
5 * The licensor of this software is Silicon Laboratories Inc. Your use of this
6 * software is governed by the terms of Silicon Labs Master Software License
7 * Agreement (MSLA) available at
8 * www.silabs.com/about-us/legal/master-software-license-agreement. This
9 * software is distributed to you in Source Code format and is governed by the
10 * sections of the MSLA applicable to Source Code.
11 *
12 *****************************************************************************/
13
22#ifndef ATTRIBUTE_MAPPER_AST_REDUCER_H
23#define ATTRIBUTE_MAPPER_AST_REDUCER_H
24
25#include <string>
26#include <map>
27#include <iostream>
28#include <boost/optional.hpp>
29#include "attribute.hpp"
32
33namespace ast
34{
51{
52 public:
54
55 operand operator()(const nil &x) const
56 {
57 return operand(x); //Cannot be reduced
58 }
59
61 {
62 return operand(n); //Cannot be reduced
63 }
64
65 operand operator()(float n) const
66 {
67 return operand(n); //Cannot be reduced
68 }
69
71 {
72 return operand(a); //Cannot be reduced
73 }
74
75 operand operator()(const signed_ &x) const
76 {
77 if (x.sign == '+') { // Unary + can just be replaced by its operand
78 return boost::apply_visitor(*this, x.operand_);
79 } else {
80 signed_ s;
81 s.sign = x.sign;
82 s.operand_ = boost::apply_visitor(*this, x.operand_);
83 return operand(s);
84 }
85 }
86
88 {
89 //Check if we can statically reduce cond_value
90 auto val = boost::apply_visitor(evaluator, x.cond_value);
91 if (val) {
92 return val.value() ? x.cond_true : x.cond_false;
93 } else {
95 cond.cond_value = boost::apply_visitor(*this, x.cond_value);
96 cond.cond_true = boost::apply_visitor(*this, x.cond_true);
97 cond.cond_false = boost::apply_visitor(*this, x.cond_false);
98 return operand(cond);
99 }
100 }
101
103 {
104 // Not supported for now
105 return operand(f);
106 }
107
109 {
110 return operand(reduce_expression(x));
111 }
112
123 {
124 operation o = x;
125 auto val = boost::apply_visitor(evaluator, x.operand_);
126 if (val) {
127 o.operand_ = operand(val.value());
128 } else {
129 o.operand_ = boost::apply_visitor(*this, x.operand_);
130 }
131 return o;
132 }
133
145 {
146 expression reduced_expr;
147 operator_ids unity_operation = ast::operator_plus;
148 //Accumulator to store collected constants
149 result_type_t acc = 0;
150 bool substitute = false;
151
152 reduced_expr.first = boost::apply_visitor(*this, x.first);
153
154 if (x.rest.empty()) {
155 return reduced_expr;
156 }
157
158 // We only try to substitute + - and * /
159 switch (x.rest.begin()->operator_) {
162 acc = 0;
163 substitute = true;
164 unity_operation = ast::operator_plus;
165 break;
168 acc = 1;
169 substitute = true;
170 unity_operation = ast::operator_mult;
171 break;
172 default:
173 acc = 0;
174 //We dont are substituing the other operators
175 substitute = false;
176 }
177
178 // If the first operand is a constant then we can use this for the inital
179 // accumulator value
180 auto lhs = boost::apply_visitor(evaluator, reduced_expr.first);
181 if (lhs) {
182 acc = lhs.value();
183 }
184
185 // Go though all terms, if they are constant merge them into the accumulator
186 for (const auto &op: x.rest) {
187 auto val = evaluator(op, acc);
188 // Don't substitute the div operator due to risk of rounding errors
189 if (substitute && val && (op.operator_ != ast::operator_div)) {
190 acc = val.value();
191 } else {
192 reduced_expr.rest.push_back(reduce_operation(op));
193 }
194 }
195
196 if (substitute) {
197 if (lhs) {
198 reduced_expr.first = acc;
199 } else {
200 if (acc < 0) {
201 signed_ s;
202 s.sign = '-';
203 s.operand_ = operand(-acc);
204 operation const_op = {unity_operation, operand(s)};
205 reduced_expr.rest.push_back(const_op);
206 } else {
207 operation const_op = {unity_operation, operand(acc)};
208 reduced_expr.rest.push_back(const_op);
209 }
210 }
211 }
212 return reduced_expr;
213 }
214
215 //Reduce the assignment by reducing the right hand side
217 {
218 assignment reduced = x;
219 reduced.rhs = reduce_expression(x.rhs);
220 return reduced;
221 }
222
223 //Reduce the assignments in a scope
224 scope operator()(const scope &x) const
225 {
226 scope reduced = x;
227 for (auto &a: reduced.assignments) {
228 a = (*this)(a);
229 }
230 return reduced;
231 }
232
233 //Go though the ast an reduce each element
235 {
236 ast_tree reduced = ast;
237 for (auto &ast_element: reduced) {
238 ast_element = boost::apply_visitor(*this, ast_element);
239 }
240 return reduced;
241 }
242
243 private:
245};
246} // namespace ast
247#endif
attribute store C++ wrapper.
#define ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE
This represents an invalid attribute Type. Shall not be used for nodes in the attribute store.
Definition: attribute_store.h:44
AST reducer.
Definition: attribute_mapper_ast_reducer.hpp:51
operand operator()(const expression &x) const
Definition: attribute_mapper_ast_reducer.hpp:108
operand operator()(float n) const
Definition: attribute_mapper_ast_reducer.hpp:65
operation reduce_operation(const operation &x) const
This function reduces an operation.
Definition: attribute_mapper_ast_reducer.hpp:122
operand operator()(const function_invokation &f) const
Definition: attribute_mapper_ast_reducer.hpp:102
expression reduce_expression(const expression &x) const
Reduce an expression.
Definition: attribute_mapper_ast_reducer.hpp:144
eval< result_type_t > evaluator
Definition: attribute_mapper_ast_reducer.hpp:244
ast_tree operator()(const ast_tree &ast) const
Definition: attribute_mapper_ast_reducer.hpp:234
operand operator()(const signed_ &x) const
Definition: attribute_mapper_ast_reducer.hpp:75
operand operator()(uint32_t n) const
Definition: attribute_mapper_ast_reducer.hpp:60
operand operator()(const attribute &a) const
Definition: attribute_mapper_ast_reducer.hpp:70
scope operator()(const scope &x) const
Definition: attribute_mapper_ast_reducer.hpp:224
operand operator()(const nil &x) const
Definition: attribute_mapper_ast_reducer.hpp:55
assignment operator()(const assignment &x) const
Definition: attribute_mapper_ast_reducer.hpp:216
operand operator()(const condition &x) const
Definition: attribute_mapper_ast_reducer.hpp:87
reducer()
Definition: attribute_mapper_ast_reducer.hpp:53
float result_type_t
Definition: attribute_mapper_ast.hpp:36
Definition: attribute_mapper_ast.hpp:39
operator_ids
Definitions of operators When the parser encounters the string representation of operators,...
Definition: attribute_mapper_ast.hpp:60
@ operator_div
Definition: attribute_mapper_ast.hpp:65
@ operator_minus
Definition: attribute_mapper_ast.hpp:62
@ operator_mult
Definition: attribute_mapper_ast.hpp:64
@ operator_plus
Definition: attribute_mapper_ast.hpp:61
x3::variant< ast::nil, uint32_t, float, x3::forward_ast< attribute >, x3::forward_ast< signed_ >, x3::forward_ast< expression >, x3::forward_ast< condition >, x3::forward_ast< function_invokation > > operand
Operands.
Definition: attribute_mapper_ast.hpp:95
Assignment.
Definition: attribute_mapper_ast.hpp:193
expression rhs
right hand side of the assignment
Definition: attribute_mapper_ast.hpp:200
Definition: attribute_mapper_ast.hpp:53
Attribute.
Definition: attribute_mapper_ast.hpp:177
Condition.
Definition: attribute_mapper_ast.hpp:147
operand cond_true
Truth value.
Definition: attribute_mapper_ast.hpp:149
operand cond_false
False value.
Definition: attribute_mapper_ast.hpp:150
operand cond_value
Selector value.
Definition: attribute_mapper_ast.hpp:148
Expression.
Definition: attribute_mapper_ast.hpp:134
operand first
Definition: attribute_mapper_ast.hpp:135
std::list< operation > rest
Definition: attribute_mapper_ast.hpp:136
Built-in function invokation Example : fn_min_value(r'3, 5, d'5 or 20)
Definition: attribute_mapper_ast.hpp:209
Definition: attribute_mapper_ast.hpp:42
Operation An operation consists of an operator and an right hand side operand. When operations are ev...
Definition: attribute_mapper_ast.hpp:123
operand operand_
right hand side operand
Definition: attribute_mapper_ast.hpp:125
Scope.
Definition: attribute_mapper_ast.hpp:234
std::vector< assignment > assignments
Definition: attribute_mapper_ast.hpp:237
Uniary signed operand.
Definition: attribute_mapper_ast.hpp:111
char sign
Definition: attribute_mapper_ast.hpp:112
operand operand_
Definition: attribute_mapper_ast.hpp:113
pthread_cond_t cond
Definition: uic_stdin_process.c:53