/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include #include #include #include namespace ExpressionEvaluation { //////////////////////////// // MathExpressionOperators //////////////////////////// ElementInformation MathExpressionOperators::AddOperator() { ElementInformation elementInfo; elementInfo.m_id = MathExpressionOperators::Add; elementInfo.m_priority = AddSubtract; return elementInfo; } ElementInformation MathExpressionOperators::SubtractOperator() { ElementInformation elementInfo; elementInfo.m_id = MathExpressionOperators::Subtract; elementInfo.m_priority = AddSubtract; return elementInfo; } ElementInformation MathExpressionOperators::MultiplyOperator() { ElementInformation elementInfo; elementInfo.m_id = MathExpressionOperators::Multiply; elementInfo.m_priority = MultiplyDivideModulo; return elementInfo; } ElementInformation MathExpressionOperators::DivideOperator() { ElementInformation elementInfo; elementInfo.m_id = MathExpressionOperators::Divide; elementInfo.m_priority = MultiplyDivideModulo; return elementInfo; } ElementInformation MathExpressionOperators::ModuloOperator() { ElementInformation elementInfo; elementInfo.m_id = MathExpressionOperators::Modulo; elementInfo.m_priority = MultiplyDivideModulo; return elementInfo; } ExpressionParserId MathExpressionOperators::GetParserId() const { return Interfaces::MathOperators; } MathExpressionOperators::ParseResult MathExpressionOperators::ParseElement(const AZStd::string& inputText, size_t offset) const { ParseResult result; char firstChar = inputText.at(offset); if (firstChar == '+') { result.m_charactersConsumed = 1; result.m_element = AddOperator(); } else if (firstChar == '-') { result.m_charactersConsumed = 1; result.m_element = SubtractOperator(); } else if (firstChar == '*') { result.m_charactersConsumed = 1; result.m_element = MultiplyOperator(); } else if (firstChar == '/') { result.m_charactersConsumed = 1; result.m_element = DivideOperator(); } else if (firstChar == '%') { result.m_charactersConsumed = 1; result.m_element = ModuloOperator(); } return result; } void MathExpressionOperators::EvaluateToken(const ElementInformation& elementInformation, ExpressionResultStack& resultStack) const { if (resultStack.size() < 2) { return; } auto rightValue = resultStack.PopAndReturn(); auto leftValue = resultStack.PopAndReturn(); ExpressionResult result; switch (elementInformation.m_id) { case Add: result = OnAddOperator(leftValue, rightValue); break; case Subtract: result = OnSubtractOperator(leftValue, rightValue); break; case Multiply: result = OnMultiplyOperator(leftValue, rightValue); break; case Divide: result = OnDivideOperator(leftValue, rightValue); break; case Modulo: result = OnModuloOperator(leftValue, rightValue); break; default: break; } if (!result.empty()) { resultStack.emplace(AZStd::move(result)); } } ExpressionResult MathExpressionOperators::OnAddOperator(const AZStd::any& leftValue, const AZStd::any& rightValue) const { double lhsValue = Utils::GetAnyValue(leftValue); double rhsValue = Utils::GetAnyValue(rightValue); return ExpressionResult(lhsValue + rhsValue); } ExpressionResult MathExpressionOperators::OnSubtractOperator(const AZStd::any& leftValue, const AZStd::any& rightValue) const { double lhsValue = Utils::GetAnyValue(leftValue); double rhsValue = Utils::GetAnyValue(rightValue); return ExpressionResult(lhsValue - rhsValue); } ExpressionResult MathExpressionOperators::OnMultiplyOperator(const AZStd::any& leftValue, const AZStd::any& rightValue) const { double lhsValue = Utils::GetAnyValue(leftValue); double rhsValue = Utils::GetAnyValue(rightValue); return ExpressionResult(lhsValue * rhsValue); } ExpressionResult MathExpressionOperators::OnDivideOperator(const AZStd::any& leftValue, const AZStd::any& rightValue) const { double lhsValue = Utils::GetAnyValue(leftValue); double rhsValue = Utils::GetAnyValue(rightValue); if (!AZ::IsClose(rhsValue, 0.0, std::numeric_limits::epsilon())) { return ExpressionResult(lhsValue / rhsValue); } return ExpressionResult(); } ExpressionResult MathExpressionOperators::OnModuloOperator(const AZStd::any& leftValue, const AZStd::any& rightValue) const { double lhsValue = Utils::GetAnyValue(leftValue); double rhsValue = Utils::GetAnyValue(rightValue); if (!AZ::IsClose(rhsValue, 0.0, std::numeric_limits().epsilon())) { return ExpressionResult(aznumeric_cast(aznumeric_cast(lhsValue) % aznumeric_cast(rhsValue))); } return ExpressionResult(); } }