blob: 377bdd86b861364598c433553a5f4d03ef1c094a [file] [log] [blame]
Andrew Jefferya05437e2022-04-07 16:17:21 +09301/*
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
Brad Bishope45d8c72022-05-25 15:12:53 -040018#include "expression.hpp"
Andrew Jefferya05437e2022-04-07 16:17:21 +093019
Andrew Jeffery5ace4e42022-04-07 16:58:30 +093020#include <iostream>
Andrew Jefferya05437e2022-04-07 16:17:21 +093021#include <stdexcept>
22
23namespace expression
24{
25std::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
51int 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 {
V-Sanjana9e92c962023-01-19 20:41:39 +053069 if (b == 0)
70 {
71 throw std::runtime_error(
72 "Math error: Attempted to divide by Zero\n");
73 }
Andrew Jefferya05437e2022-04-07 16:17:21 +093074 return a / b;
75 }
76 case Operation::modulo:
77 {
P Dheeraj Srujan Kumar2eb6c6f2023-01-23 20:57:16 +053078 if (b == 0)
79 {
80 throw std::runtime_error(
81 "Math error: Attempted to divide by Zero\n");
82 }
Andrew Jefferya05437e2022-04-07 16:17:21 +093083 return a % b;
84 }
85
86 default:
87 throw std::invalid_argument("Unrecognised operation");
88 }
89}
Andrew Jeffery5ace4e42022-04-07 16:58:30 +093090
Andrew Jeffery95559612022-04-07 17:22:47 +093091int evaluate(int substitute, std::vector<std::string>::iterator curr,
92 std::vector<std::string>::iterator& end)
Andrew Jeffery5ace4e42022-04-07 16:58:30 +093093{
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
Andrew Jeffery95559612022-04-07 17:22:47 +0930124 end = curr;
Andrew Jeffery5ace4e42022-04-07 16:58:30 +0930125 return substitute;
126}
Andrew Jefferya05437e2022-04-07 16:17:21 +0930127} // namespace expression