xref: /openbmc/entity-manager/src/expression.cpp (revision bfc7296e)
1 /*
2 // Copyright (c) 2017 Intel Corporation
3 // Copyright (c) 2022 IBM Corp.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //      http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 */
17 
18 #include "expression.hpp"
19 
20 #include <iostream>
21 #include <stdexcept>
22 
23 namespace expression
24 {
25 std::optional<Operation> parseOperation(std::string& op)
26 {
27     if (op == "+")
28     {
29         return Operation::addition;
30     }
31     if (op == "-")
32     {
33         return Operation::subtraction;
34     }
35     if (op == "*")
36     {
37         return Operation::multiplication;
38     }
39     if (op == R"(%)")
40     {
41         return Operation::modulo;
42     }
43     if (op == R"(/)")
44     {
45         return Operation::division;
46     }
47 
48     return std::nullopt;
49 }
50 
51 int evaluate(int a, Operation op, int b)
52 {
53     switch (op)
54     {
55         case Operation::addition:
56         {
57             return a + b;
58         }
59         case Operation::subtraction:
60         {
61             return a - b;
62         }
63         case Operation::multiplication:
64         {
65             return a * b;
66         }
67         case Operation::division:
68         {
69             return a / b;
70         }
71         case Operation::modulo:
72         {
73             return a % b;
74         }
75 
76         default:
77             throw std::invalid_argument("Unrecognised operation");
78     }
79 }
80 
81 int evaluate(int substitute, std::vector<std::string>::iterator curr,
82              std::vector<std::string>::iterator& end)
83 {
84     bool isOperator = true;
85     std::optional<Operation> next = Operation::addition;
86 
87     for (; curr != end; curr++)
88     {
89         if (isOperator)
90         {
91             next = expression::parseOperation(*curr);
92             if (!next)
93             {
94                 break;
95             }
96         }
97         else
98         {
99             try
100             {
101                 int constant = std::stoi(*curr);
102                 substitute = evaluate(substitute, *next, constant);
103             }
104             catch (const std::invalid_argument&)
105             {
106                 std::cerr << "Parameter not supported for templates " << *curr
107                           << "\n";
108                 continue;
109             }
110         }
111         isOperator = !isOperator;
112     }
113 
114     end = curr;
115     return substitute;
116 }
117 } // namespace expression
118