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 {
parseOperation(std::string & op)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
evaluate(int a,Operation op,int b)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 if (b == 0)
70 {
71 throw std::runtime_error(
72 "Math error: Attempted to divide by Zero\n");
73 }
74 return a / b;
75 }
76 case Operation::modulo:
77 {
78 if (b == 0)
79 {
80 throw std::runtime_error(
81 "Math error: Attempted to divide by Zero\n");
82 }
83 return a % b;
84 }
85
86 default:
87 throw std::invalid_argument("Unrecognised operation");
88 }
89 }
90
evaluate(int substitute,std::vector<std::string>::iterator curr,std::vector<std::string>::iterator & end)91 int evaluate(int substitute, std::vector<std::string>::iterator curr,
92 std::vector<std::string>::iterator& end)
93 {
94 bool isOperator = true;
95 std::optional<Operation> next = Operation::addition;
96
97 for (; curr != end; curr++)
98 {
99 if (isOperator)
100 {
101 next = expression::parseOperation(*curr);
102 if (!next)
103 {
104 break;
105 }
106 }
107 else
108 {
109 try
110 {
111 int constant = std::stoi(*curr);
112 substitute = evaluate(substitute, *next, constant);
113 }
114 catch (const std::invalid_argument&)
115 {
116 std::cerr << "Parameter not supported for templates " << *curr
117 << "\n";
118 continue;
119 }
120 }
121 isOperator = !isOperator;
122 }
123
124 end = curr;
125 return substitute;
126 }
127 } // namespace expression
128