blob: 9b878c8fcd1108540c362b882cad2969723480d7 [file] [log] [blame]
Alexander Hansen4e1142d2025-07-25 17:07:27 +02001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright 2017 Intel Corporation, 2022 IBM Corp.
Andrew Jefferya05437e2022-04-07 16:17:21 +09303
Brad Bishope45d8c72022-05-25 15:12:53 -04004#include "expression.hpp"
Andrew Jefferya05437e2022-04-07 16:17:21 +09305
Andrew Jeffery5ace4e42022-04-07 16:58:30 +09306#include <iostream>
Andrew Jefferya05437e2022-04-07 16:17:21 +09307#include <stdexcept>
8
9namespace expression
10{
11std::optional<Operation> parseOperation(std::string& op)
12{
13 if (op == "+")
14 {
15 return Operation::addition;
16 }
17 if (op == "-")
18 {
19 return Operation::subtraction;
20 }
21 if (op == "*")
22 {
23 return Operation::multiplication;
24 }
25 if (op == R"(%)")
26 {
27 return Operation::modulo;
28 }
29 if (op == R"(/)")
30 {
31 return Operation::division;
32 }
33
34 return std::nullopt;
35}
36
37int evaluate(int a, Operation op, int b)
38{
39 switch (op)
40 {
41 case Operation::addition:
42 {
43 return a + b;
44 }
45 case Operation::subtraction:
46 {
47 return a - b;
48 }
49 case Operation::multiplication:
50 {
51 return a * b;
52 }
53 case Operation::division:
54 {
V-Sanjana9e92c962023-01-19 20:41:39 +053055 if (b == 0)
56 {
57 throw std::runtime_error(
58 "Math error: Attempted to divide by Zero\n");
59 }
Andrew Jefferya05437e2022-04-07 16:17:21 +093060 return a / b;
61 }
62 case Operation::modulo:
63 {
P Dheeraj Srujan Kumar2eb6c6f2023-01-23 20:57:16 +053064 if (b == 0)
65 {
66 throw std::runtime_error(
67 "Math error: Attempted to divide by Zero\n");
68 }
Andrew Jefferya05437e2022-04-07 16:17:21 +093069 return a % b;
70 }
71
72 default:
73 throw std::invalid_argument("Unrecognised operation");
74 }
75}
Andrew Jeffery5ace4e42022-04-07 16:58:30 +093076
Andrew Jeffery95559612022-04-07 17:22:47 +093077int evaluate(int substitute, std::vector<std::string>::iterator curr,
78 std::vector<std::string>::iterator& end)
Andrew Jeffery5ace4e42022-04-07 16:58:30 +093079{
80 bool isOperator = true;
81 std::optional<Operation> next = Operation::addition;
82
83 for (; curr != end; curr++)
84 {
85 if (isOperator)
86 {
87 next = expression::parseOperation(*curr);
88 if (!next)
89 {
90 break;
91 }
92 }
93 else
94 {
95 try
96 {
97 int constant = std::stoi(*curr);
98 substitute = evaluate(substitute, *next, constant);
99 }
100 catch (const std::invalid_argument&)
101 {
102 std::cerr << "Parameter not supported for templates " << *curr
103 << "\n";
104 continue;
105 }
106 }
107 isOperator = !isOperator;
108 }
109
Andrew Jeffery95559612022-04-07 17:22:47 +0930110 end = curr;
Andrew Jeffery5ace4e42022-04-07 16:58:30 +0930111 return substitute;
112}
Andrew Jefferya05437e2022-04-07 16:17:21 +0930113} // namespace expression