143 lines
7.6 KiB
C++
143 lines
7.6 KiB
C++
|
|
#include "NumericEvalValue.hpp"
|
|
|
|
namespace Porygon::Evaluation {
|
|
EvalValue *NumericEvalValue::BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue *b) const {
|
|
auto right = dynamic_cast<const NumericEvalValue*>(b);
|
|
if (_isFloat){
|
|
double v1 = std::get<double >(_floatValue);
|
|
if (right->_isFloat){
|
|
double v2 =std::get<double >(right->_floatValue);
|
|
switch (operation){
|
|
|
|
case Binder::BoundBinaryOperation::Addition: return new NumericEvalValue(v1 + v2);
|
|
case Binder::BoundBinaryOperation::Subtraction: return new NumericEvalValue(v1 - v2);
|
|
case Binder::BoundBinaryOperation::Multiplication: return new NumericEvalValue(v1 * v2);
|
|
case Binder::BoundBinaryOperation::Division: return new NumericEvalValue(v1 / v2);
|
|
case Binder::BoundBinaryOperation::Equality: return new BooleanEvalValue(v1 == v2);
|
|
case Binder::BoundBinaryOperation::Inequality: return new BooleanEvalValue(v1 != v2);
|
|
case Binder::BoundBinaryOperation::LessThan: return new BooleanEvalValue(v1 < v2);
|
|
case Binder::BoundBinaryOperation::LessThanEquals: return new BooleanEvalValue(v1 <= v2);
|
|
case Binder::BoundBinaryOperation::GreaterThan: return new BooleanEvalValue(v1 > v2);
|
|
case Binder::BoundBinaryOperation::GreaterThanEquals: return new BooleanEvalValue(v1 >= v2);
|
|
default: throw exception();
|
|
}
|
|
}
|
|
else{
|
|
int64_t v2 = std::get<int64_t >(right->_intValue);
|
|
switch (operation){
|
|
|
|
case Binder::BoundBinaryOperation::Addition: return new NumericEvalValue(v1 + v2);
|
|
case Binder::BoundBinaryOperation::Subtraction: return new NumericEvalValue(v1 - v2);
|
|
case Binder::BoundBinaryOperation::Multiplication: return new NumericEvalValue(v1 * v2);
|
|
case Binder::BoundBinaryOperation::Division: return new NumericEvalValue(v1 / v2);
|
|
case Binder::BoundBinaryOperation::Equality: return new BooleanEvalValue(v1 == v2);
|
|
case Binder::BoundBinaryOperation::Inequality: return new BooleanEvalValue(v1 != v2);
|
|
case Binder::BoundBinaryOperation::LessThan: return new BooleanEvalValue(v1 < v2);
|
|
case Binder::BoundBinaryOperation::LessThanEquals: return new BooleanEvalValue(v1 <= v2);
|
|
case Binder::BoundBinaryOperation::GreaterThan: return new BooleanEvalValue(v1 > v2);
|
|
case Binder::BoundBinaryOperation::GreaterThanEquals: return new BooleanEvalValue(v1 >= v2);
|
|
default: throw exception();
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
int64_t v1 = std::get<int64_t >(_intValue);
|
|
if (right->_isFloat){
|
|
double v2 =std::get<double>(right->_floatValue);;
|
|
switch (operation){
|
|
|
|
case Binder::BoundBinaryOperation::Addition: return new NumericEvalValue(v1 + v2);
|
|
case Binder::BoundBinaryOperation::Subtraction: return new NumericEvalValue(v1 - v2);
|
|
case Binder::BoundBinaryOperation::Multiplication: return new NumericEvalValue(v1 * v2);
|
|
case Binder::BoundBinaryOperation::Division: return new NumericEvalValue(v1 / v2);
|
|
case Binder::BoundBinaryOperation::Equality: return new BooleanEvalValue(v1 == v2);
|
|
case Binder::BoundBinaryOperation::Inequality: return new BooleanEvalValue(v1 != v2);
|
|
case Binder::BoundBinaryOperation::LessThan: return new BooleanEvalValue(v1 < v2);
|
|
case Binder::BoundBinaryOperation::LessThanEquals: return new BooleanEvalValue(v1 <= v2);
|
|
case Binder::BoundBinaryOperation::GreaterThan: return new BooleanEvalValue(v1 > v2);
|
|
case Binder::BoundBinaryOperation::GreaterThanEquals: return new BooleanEvalValue(v1 >= v2);
|
|
default: throw exception();
|
|
}
|
|
} else{
|
|
int64_t v2 = std::get<int64_t >(right->_intValue);
|
|
switch (operation){
|
|
|
|
case Binder::BoundBinaryOperation::Addition: return new NumericEvalValue(v1 + v2);
|
|
case Binder::BoundBinaryOperation::Subtraction: return new NumericEvalValue(v1 - v2);
|
|
case Binder::BoundBinaryOperation::Multiplication: return new NumericEvalValue(v1 * v2);
|
|
case Binder::BoundBinaryOperation::Division: return new NumericEvalValue(v1 / v2);
|
|
case Binder::BoundBinaryOperation::Equality: return new BooleanEvalValue(v1 == v2);
|
|
case Binder::BoundBinaryOperation::Inequality: return new BooleanEvalValue(v1 != v2);
|
|
case Binder::BoundBinaryOperation::LessThan: return new BooleanEvalValue(v1 < v2);
|
|
case Binder::BoundBinaryOperation::LessThanEquals: return new BooleanEvalValue(v1 <= v2);
|
|
case Binder::BoundBinaryOperation::GreaterThan: return new BooleanEvalValue(v1 > v2);
|
|
case Binder::BoundBinaryOperation::GreaterThanEquals: return new BooleanEvalValue(v1 >= v2);
|
|
default: throw exception();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
EvalValue *NumericEvalValue::Cast(shared_ptr<const ScriptType> castType) const {
|
|
if (castType->GetClass() == TypeClass::Number){
|
|
auto num = static_pointer_cast<const NumericScriptType>(castType);
|
|
if (num->IsFloat() && !this->_isFloat){
|
|
return new NumericEvalValue(static_cast<double>(std::get<int64_t >(_intValue)));
|
|
}
|
|
else if(!num->IsFloat() && this->_isFloat){
|
|
return new NumericEvalValue(static_cast<int64_t>(std::get<double >(_floatValue)));
|
|
}
|
|
}
|
|
return EvalValue::Cast(castType);
|
|
}
|
|
|
|
EvalValue *NumericEvalValue::Clone() const {
|
|
if (_isFloat)
|
|
return new NumericEvalValue(std::get<double >(_floatValue));
|
|
return new NumericEvalValue(std::get<int64_t >(_intValue));
|
|
}
|
|
|
|
size_t NumericEvalValue::GetHashCode() const {
|
|
if (_isFloat)
|
|
return std::get<double >(_floatValue);
|
|
return std::get<int64_t >(_intValue);;
|
|
}
|
|
|
|
bool NumericEvalValue::operator==(const EvalValue *b) const {
|
|
if (b->GetTypeClass() != TypeClass::Number)
|
|
return false;
|
|
auto right = dynamic_cast<const NumericEvalValue*>(b);
|
|
if (_isFloat != right->_isFloat)
|
|
return false;
|
|
if (_isFloat){
|
|
return _floatValue == right->_floatValue;
|
|
}
|
|
return _intValue == right->_intValue;
|
|
}
|
|
|
|
int64_t NumericEvalValue::EvaluateInteger() const {
|
|
return std::get<int64_t >(_intValue);;
|
|
}
|
|
|
|
double NumericEvalValue::EvaluateFloat() const {
|
|
if (!_isFloat)
|
|
return std::get<int64_t >(_intValue);
|
|
return std::get<double>(_floatValue);
|
|
}
|
|
|
|
u16string NumericEvalValue::EvaluateString() const {
|
|
if (_isFloat){
|
|
return Utilities::StringUtils::FloatToString(std::get<double >(_floatValue));
|
|
}
|
|
return Utilities::StringUtils::IntToString(std::get<int64_t >(_intValue));
|
|
}
|
|
|
|
EvalValue *NumericEvalValue::UnaryOperation(Binder::BoundUnaryOperation operation) const {
|
|
if (_isFloat){
|
|
return new NumericEvalValue(- std::get<double >(_floatValue));
|
|
}
|
|
return new NumericEvalValue(- std::get<int64_t >(_intValue));
|
|
}
|
|
|
|
} |