1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright 2017 Intel Corporation, 2022 IBM Corp.
3
4 #include "expression.hpp"
5
6 #include <phosphor-logging/lg2.hpp>
7
8 #include <stdexcept>
9
10 namespace expression
11 {
parseOperation(std::string & op)12 std::optional<Operation> parseOperation(std::string& op)
13 {
14 if (op == "+")
15 {
16 return Operation::addition;
17 }
18 if (op == "-")
19 {
20 return Operation::subtraction;
21 }
22 if (op == "*")
23 {
24 return Operation::multiplication;
25 }
26 if (op == R"(%)")
27 {
28 return Operation::modulo;
29 }
30 if (op == R"(/)")
31 {
32 return Operation::division;
33 }
34
35 return std::nullopt;
36 }
37
evaluate(int a,Operation op,int b)38 int evaluate(int a, Operation op, int b)
39 {
40 switch (op)
41 {
42 case Operation::addition:
43 {
44 return a + b;
45 }
46 case Operation::subtraction:
47 {
48 return a - b;
49 }
50 case Operation::multiplication:
51 {
52 return a * b;
53 }
54 case Operation::division:
55 {
56 if (b == 0)
57 {
58 throw std::runtime_error(
59 "Math error: Attempted to divide by Zero\n");
60 }
61 return a / b;
62 }
63 case Operation::modulo:
64 {
65 if (b == 0)
66 {
67 throw std::runtime_error(
68 "Math error: Attempted to divide by Zero\n");
69 }
70 return a % b;
71 }
72
73 default:
74 throw std::invalid_argument("Unrecognised operation");
75 }
76 }
77
evaluate(int substitute,std::vector<std::string>::iterator curr,std::vector<std::string>::iterator & end)78 int evaluate(int substitute, std::vector<std::string>::iterator curr,
79 std::vector<std::string>::iterator& end)
80 {
81 bool isOperator = true;
82 std::optional<Operation> next = Operation::addition;
83
84 for (; curr != end; curr++)
85 {
86 if (isOperator)
87 {
88 next = expression::parseOperation(*curr);
89 if (!next)
90 {
91 break;
92 }
93 }
94 else
95 {
96 try
97 {
98 int constant = std::stoi(*curr);
99 substitute = evaluate(substitute, *next, constant);
100 }
101 catch (const std::invalid_argument&)
102 {
103 lg2::error("Parameter not supported for templates {STR}", "STR",
104 *curr);
105 continue;
106 }
107 }
108 isOperator = !isOperator;
109 }
110
111 end = curr;
112 return substitute;
113 }
114 } // namespace expression
115