#include "../Script.hpp" #include "EvaluationException.hpp" #include "Evaluator.hpp" #include "EvalValues/NumericEvalValue.hpp" #include "EvalValues/StringEvalValue.hpp" using namespace Porygon::Binder; namespace Porygon::Evaluation { const shared_ptr Evaluator::EvaluateIntegerBinary(const BoundBinaryExpression *expression) { auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft()); auto rightValue = this->EvaluateIntegerExpression(expression->GetRight()); switch (expression->GetOperation()) { case BoundBinaryOperation::Addition: return leftValue.get()->operator+(rightValue); case BoundBinaryOperation::Subtraction: return leftValue.get()->operator-(rightValue); case BoundBinaryOperation::Multiplication: return leftValue.get()->operator*(rightValue); case BoundBinaryOperation::Division: return leftValue.get()->operator/(rightValue); default: throw EvaluationException("Can't evaluate operation to numeric"); } } const shared_ptr Evaluator::EvaluateBooleanBinary(const BoundBinaryExpression *expression) { switch (expression->GetOperation()) { case BoundBinaryOperation::Equality: { auto leftValue = this->EvaluateExpression(expression->GetLeft()); auto rightValue = this->EvaluateExpression(expression->GetRight()); bool equals = leftValue.get()->operator==(rightValue.get()); return make_shared(equals); } case BoundBinaryOperation::Inequality: { auto leftValue = this->EvaluateExpression(expression->GetLeft()); auto rightValue = this->EvaluateExpression(expression->GetRight()); bool equals = leftValue.get()->operator!=(rightValue.get()); return make_shared(equals); } case BoundBinaryOperation::LessThan: { auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft()); auto rightValue = this->EvaluateIntegerExpression(expression->GetRight()); return leftValue->operator<(rightValue); } case BoundBinaryOperation::LessThanEquals: { auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft()); auto rightValue = this->EvaluateIntegerExpression(expression->GetRight()); return leftValue->operator<=(rightValue); } case BoundBinaryOperation::GreaterThan: { auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft()); auto rightValue = this->EvaluateIntegerExpression(expression->GetRight()); return leftValue->operator>(rightValue); } case BoundBinaryOperation::GreaterThanEquals: { auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft()); auto rightValue = this->EvaluateIntegerExpression(expression->GetRight()); return leftValue->operator>=(rightValue); } case BoundBinaryOperation::LogicalAnd: { auto leftValue = this->EvaluateBoolExpression(expression->GetLeft()); if (!leftValue->EvaluateBool()) return leftValue; auto rightValue = this->EvaluateBoolExpression(expression->GetRight()); return rightValue; } case BoundBinaryOperation::LogicalOr: { auto leftValue = this->EvaluateBoolExpression(expression->GetLeft()); if (leftValue->EvaluateBool()) return leftValue; auto rightValue = this->EvaluateBoolExpression(expression->GetRight()); return rightValue; } default: throw EvaluationException("Can't evaluate operation to boolean"); } } const shared_ptr Evaluator::EvaluateStringBinary(const BoundBinaryExpression *expression) { if (expression->GetOperation() != BoundBinaryOperation::Concatenation) throw; std::basic_ostringstream stringStream; auto left = this->EvaluateStringExpression(expression->GetLeft()); stringStream << *left->EvaluateString(); auto right = this->EvaluateExpression(expression->GetRight()); stringStream << *right->EvaluateString(); return make_shared(stringStream.str()); } }