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 <iostream> 7 #include <stdexcept> 8 9 namespace expression 10 { 11 std::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 37 int 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 { 55 if (b == 0) 56 { 57 throw std::runtime_error( 58 "Math error: Attempted to divide by Zero\n"); 59 } 60 return a / b; 61 } 62 case Operation::modulo: 63 { 64 if (b == 0) 65 { 66 throw std::runtime_error( 67 "Math error: Attempted to divide by Zero\n"); 68 } 69 return a % b; 70 } 71 72 default: 73 throw std::invalid_argument("Unrecognised operation"); 74 } 75 } 76 77 int evaluate(int substitute, std::vector<std::string>::iterator curr, 78 std::vector<std::string>::iterator& end) 79 { 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 110 end = curr; 111 return substitute; 112 } 113 } // namespace expression 114