Greatly simplify handling numerical eval values, using std::variant
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
7b5d03ed74
commit
5d700aa0e9
|
@ -39,11 +39,11 @@ namespace Porygon::Evaluation {
|
|||
|
||||
|
||||
EvalValue *CreateIntegerEvalValue(int64_t l) {
|
||||
return new IntegerEvalValue(l);
|
||||
return new NumericEvalValue(l);
|
||||
}
|
||||
|
||||
EvalValue *CreateFloatEvalValue(double d) {
|
||||
return new FloatEvalValue(d);
|
||||
return new NumericEvalValue(d);
|
||||
}
|
||||
|
||||
EvalValue *CreateBoolEvalValue(bool b) {
|
||||
|
|
|
@ -9,38 +9,38 @@ namespace Porygon::Evaluation{
|
|||
class EvalValueHelper{
|
||||
public:
|
||||
inline static EvalValue* Create(unsigned char i){
|
||||
return new IntegerEvalValue((int64_t )i);
|
||||
return new NumericEvalValue((int64_t )i);
|
||||
}
|
||||
inline static EvalValue* Create(signed char i){
|
||||
return new IntegerEvalValue((int64_t )i);
|
||||
return new NumericEvalValue((int64_t )i);
|
||||
}
|
||||
inline static EvalValue* Create(short int i){
|
||||
return new IntegerEvalValue(i);
|
||||
return new NumericEvalValue(i);
|
||||
}
|
||||
inline static EvalValue* Create(unsigned short int i){
|
||||
return new IntegerEvalValue(i);
|
||||
return new NumericEvalValue(i);
|
||||
}
|
||||
inline static EvalValue* Create(signed int i){
|
||||
return new IntegerEvalValue(i);
|
||||
return new NumericEvalValue(i);
|
||||
}
|
||||
inline static EvalValue* Create(unsigned int i){
|
||||
return new IntegerEvalValue(i);
|
||||
return new NumericEvalValue(static_cast<int64_t>(i));
|
||||
}
|
||||
inline static EvalValue* Create(int64_t l){
|
||||
return new IntegerEvalValue(l);
|
||||
return new NumericEvalValue(l);
|
||||
}
|
||||
inline static EvalValue* Create(uint64_t l){
|
||||
return new IntegerEvalValue(l);
|
||||
return new NumericEvalValue(static_cast<int64_t>(l));
|
||||
}
|
||||
|
||||
inline static EvalValue* Create(float f){
|
||||
return new FloatEvalValue(f);
|
||||
return new NumericEvalValue(f);
|
||||
}
|
||||
inline static EvalValue* Create(double f){
|
||||
return new FloatEvalValue(f);
|
||||
return new NumericEvalValue(f);
|
||||
}
|
||||
inline static EvalValue* Create(long double f){
|
||||
return new FloatEvalValue(f);
|
||||
return new NumericEvalValue(static_cast<double>(f));
|
||||
}
|
||||
|
||||
inline static EvalValue* Create(bool b){
|
||||
|
@ -49,8 +49,8 @@ namespace Porygon::Evaluation{
|
|||
inline static EvalValue* Create(const string& s){
|
||||
return new StringEvalValue(Utilities::StringUtils::ToUTF8(s));
|
||||
}
|
||||
inline static EvalValue* Create(u16string s){
|
||||
return new StringEvalValue(std::move(s));
|
||||
inline static EvalValue* Create(const u16string& s){
|
||||
return new StringEvalValue(s);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,198 +2,139 @@
|
|||
#include "NumericEvalValue.hpp"
|
||||
|
||||
namespace Porygon::Evaluation {
|
||||
shared_ptr<const NumericEvalValue> NumericEvalValue::operator+(const shared_ptr<const NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() + b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() + (double) b->GetIntegerValue());
|
||||
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 {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>((double) this->GetIntegerValue() + b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() + b->GetIntegerValue());
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<const NumericEvalValue> NumericEvalValue::operator-(const shared_ptr<const NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() - b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() - (double) b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>((double) this->GetIntegerValue() - b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() - b->GetIntegerValue());
|
||||
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()){
|
||||
return new NumericEvalValue(std::get<int64_t >(_intValue));
|
||||
}
|
||||
}
|
||||
return EvalValue::Cast(castType);
|
||||
}
|
||||
|
||||
shared_ptr<const NumericEvalValue> NumericEvalValue::operator*(const shared_ptr<const NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() * b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() * (double) b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>((double) this->GetIntegerValue() * b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() * b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
EvalValue *NumericEvalValue::Clone() const {
|
||||
if (_isFloat)
|
||||
return new NumericEvalValue(std::get<double >(_floatValue));
|
||||
return new NumericEvalValue(std::get<int64_t >(_intValue));
|
||||
}
|
||||
|
||||
shared_ptr<const NumericEvalValue> NumericEvalValue::operator/(const shared_ptr<const NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() / b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() / (double) b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>((double) this->GetIntegerValue() / b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() / b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
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 numVal = dynamic_cast<const NumericEvalValue*>(b);
|
||||
if (this->IsFloat() != numVal->IsFloat())
|
||||
return false;
|
||||
|
||||
if (this->IsFloat()) {
|
||||
return this->EvaluateFloat() == numVal->EvaluateFloat();
|
||||
} else {
|
||||
return this->EvaluateInteger() == numVal->EvaluateInteger();
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<const BooleanEvalValue> NumericEvalValue::operator<(const shared_ptr<const NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() < b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() < (double) b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>((double) this->GetIntegerValue() < b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() < b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<const BooleanEvalValue> NumericEvalValue::operator<=(const shared_ptr<const NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() <= b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() <=(double) b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>((double) this->GetIntegerValue() <= b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() <= b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<const BooleanEvalValue> NumericEvalValue::operator>(const shared_ptr<const NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() > b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() > (double) b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>((double) this->GetIntegerValue() > b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() > b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<const BooleanEvalValue> NumericEvalValue::operator>=(const shared_ptr<const NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() >= b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() >= (double) b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>((double) this->GetIntegerValue() >= b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() >= b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EvalValue *IntegerEvalValue::BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue *b) const {
|
||||
auto right = dynamic_cast<const NumericEvalValue*>(b);
|
||||
if (right->IsFloat()){
|
||||
auto rightVal = right->EvaluateFloat();
|
||||
switch (operation){
|
||||
case Binder::BoundBinaryOperation::Addition: return new FloatEvalValue((double)_value + rightVal);
|
||||
case Binder::BoundBinaryOperation::Subtraction: return new FloatEvalValue((double)_value - rightVal);
|
||||
case Binder::BoundBinaryOperation::Multiplication: return new FloatEvalValue((double)_value * rightVal);
|
||||
case Binder::BoundBinaryOperation::Division: return new FloatEvalValue((double)_value / rightVal);
|
||||
case Binder::BoundBinaryOperation::LessThan: return new BooleanEvalValue((double)_value < rightVal);
|
||||
case Binder::BoundBinaryOperation::LessThanEquals: return new BooleanEvalValue((double)_value <= rightVal);
|
||||
case Binder::BoundBinaryOperation::GreaterThan: return new BooleanEvalValue((double)_value > rightVal);
|
||||
case Binder::BoundBinaryOperation::GreaterThanEquals: return new BooleanEvalValue((double)_value >= rightVal);
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
} else{
|
||||
auto rightVal = right->EvaluateInteger();
|
||||
switch (operation){
|
||||
case Binder::BoundBinaryOperation::Addition: return new IntegerEvalValue(_value + rightVal);
|
||||
case Binder::BoundBinaryOperation::Subtraction: return new IntegerEvalValue(_value - rightVal);
|
||||
case Binder::BoundBinaryOperation::Multiplication: return new IntegerEvalValue(_value * rightVal);
|
||||
case Binder::BoundBinaryOperation::Division: return new IntegerEvalValue(_value / rightVal);
|
||||
case Binder::BoundBinaryOperation::LessThan: return new BooleanEvalValue(_value < rightVal);
|
||||
case Binder::BoundBinaryOperation::LessThanEquals: return new BooleanEvalValue(_value <= rightVal);
|
||||
case Binder::BoundBinaryOperation::GreaterThan: return new BooleanEvalValue(_value > rightVal);
|
||||
case Binder::BoundBinaryOperation::GreaterThanEquals: return new BooleanEvalValue(_value >= rightVal);
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
if (_isFloat != right->_isFloat)
|
||||
return false;
|
||||
if (_isFloat){
|
||||
return _floatValue == right->_floatValue;
|
||||
}
|
||||
return _intValue == right->_intValue;
|
||||
}
|
||||
|
||||
EvalValue *IntegerEvalValue::Cast(shared_ptr<const ScriptType> castType) const {
|
||||
if (castType->GetClass() == TypeClass::Number){
|
||||
auto num = static_pointer_cast<const NumericScriptType>(castType);
|
||||
if (num->IsFloat()){
|
||||
return new FloatEvalValue(GetIntegerValue());
|
||||
}
|
||||
}
|
||||
return EvalValue::Cast(castType);
|
||||
int64_t NumericEvalValue::EvaluateInteger() const {
|
||||
return std::get<int64_t >(_intValue);;
|
||||
}
|
||||
|
||||
EvalValue *FloatEvalValue::Cast(shared_ptr<const ScriptType> castType) const {
|
||||
if (castType->GetClass() == TypeClass::Number){
|
||||
auto num = static_pointer_cast<const NumericScriptType>(castType);
|
||||
if (!num->IsFloat()){
|
||||
return new IntegerEvalValue(GetFloatValue());
|
||||
}
|
||||
}
|
||||
return EvalValue::Cast(castType);
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
|
@ -3,195 +3,44 @@
|
|||
#define PORYGONLANG_NUMERICEVALVALUE_HPP
|
||||
|
||||
#include <sstream>
|
||||
#include <variant>
|
||||
#include "EvalValue.hpp"
|
||||
#include "../../Utilities/StringUtils.hpp"
|
||||
|
||||
namespace Porygon::Evaluation {
|
||||
class NumericEvalValue : public EvalValue {
|
||||
std::variant<int64_t , double> _intValue, _floatValue;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual int64_t GetIntegerValue() const = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual double GetFloatValue() const = 0;
|
||||
|
||||
bool _isFloat;
|
||||
public:
|
||||
|
||||
explicit NumericEvalValue(int64_t i) : _intValue(i), _isFloat(false) {}
|
||||
explicit NumericEvalValue(int32_t i) : _intValue(static_cast<int64_t>(i)), _isFloat(false) {}
|
||||
explicit NumericEvalValue(double d) : _floatValue(d), _isFloat(true) {}
|
||||
explicit NumericEvalValue(float f) : _floatValue(f), _isFloat(true) {}
|
||||
|
||||
[[nodiscard]]
|
||||
virtual bool IsFloat() const = 0;
|
||||
virtual bool IsFloat() const{
|
||||
return _isFloat;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline TypeClass GetTypeClass() const final {
|
||||
return TypeClass::Number;
|
||||
}
|
||||
|
||||
shared_ptr<const NumericEvalValue> operator+(const shared_ptr<const NumericEvalValue> &b) const;
|
||||
|
||||
shared_ptr<const NumericEvalValue> operator-(const shared_ptr<const NumericEvalValue> &b) const;
|
||||
|
||||
shared_ptr<const NumericEvalValue> operator*(const shared_ptr<const NumericEvalValue> &b) const;
|
||||
|
||||
shared_ptr<const NumericEvalValue> operator/(const shared_ptr<const NumericEvalValue> &b) const;
|
||||
|
||||
shared_ptr<const BooleanEvalValue> operator<(const shared_ptr<const NumericEvalValue> &b) const;
|
||||
|
||||
shared_ptr<const BooleanEvalValue> operator<=(const shared_ptr<const NumericEvalValue> &b) const;
|
||||
|
||||
shared_ptr<const BooleanEvalValue> operator>(const shared_ptr<const NumericEvalValue> &b) const;
|
||||
|
||||
shared_ptr<const BooleanEvalValue> operator>=(const shared_ptr<const NumericEvalValue> &b) const;
|
||||
|
||||
bool operator==(const EvalValue *b) const final;
|
||||
};
|
||||
|
||||
class IntegerEvalValue : public NumericEvalValue {
|
||||
const int64_t _value;
|
||||
[[nodiscard]] EvalValue *Clone() const override;
|
||||
[[nodiscard]] size_t GetHashCode() const override;
|
||||
[[nodiscard]] EvalValue* Cast(shared_ptr<const ScriptType> castType) const final;
|
||||
|
||||
[[nodiscard]]
|
||||
int64_t GetIntegerValue() const final { return _value; }
|
||||
[[nodiscard]] int64_t EvaluateInteger() const override;
|
||||
[[nodiscard]] double EvaluateFloat() const override;
|
||||
[[nodiscard]] u16string EvaluateString() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
double GetFloatValue() const final {
|
||||
throw EvaluationException("Attempting to retrieve float from int eval value.");
|
||||
}
|
||||
|
||||
public:
|
||||
explicit IntegerEvalValue(int64_t value) : _value(value) {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool IsFloat() const final {
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline int64_t EvaluateInteger() const final {
|
||||
return _value;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline std::u16string EvaluateString() const final{
|
||||
return Utilities::StringUtils::IntToString(_value);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline EvalValue* Clone() const final {
|
||||
return new IntegerEvalValue(_value);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline std::size_t GetHashCode() const final {
|
||||
return std::hash<int64_t >{}(_value);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
EvalValue* BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue* b) const final;
|
||||
|
||||
[[nodiscard]]
|
||||
EvalValue* UnaryOperation(Binder::BoundUnaryOperation operation) const final{
|
||||
switch (operation){
|
||||
case Binder::BoundUnaryOperation::Negation: return new IntegerEvalValue(-_value);
|
||||
default: throw;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
EvalValue* Cast(shared_ptr<const ScriptType> castType) const final;
|
||||
};
|
||||
|
||||
class FloatEvalValue : public NumericEvalValue {
|
||||
const double _value;
|
||||
|
||||
[[nodiscard]]
|
||||
int64_t GetIntegerValue() const final {
|
||||
throw EvaluationException("Attempting to retrieve int from float eval value.");
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline double GetFloatValue() const final {
|
||||
return _value;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit FloatEvalValue(double value) : _value(value) {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool IsFloat() const final {
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline double EvaluateFloat() const final {
|
||||
return _value;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline std::u16string EvaluateString() const final{
|
||||
return Utilities::StringUtils::FloatToString(_value);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline EvalValue* Clone() const final {
|
||||
return new FloatEvalValue(_value);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline std::size_t GetHashCode() const final {
|
||||
return std::hash<double>{}(_value);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline EvalValue* BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue* b) const final{
|
||||
auto right = dynamic_cast<const NumericEvalValue*>(b);
|
||||
if (right->IsFloat()){
|
||||
auto rightVal = right->EvaluateFloat();
|
||||
switch (operation){
|
||||
case Binder::BoundBinaryOperation::Addition: return new FloatEvalValue(_value + rightVal);
|
||||
case Binder::BoundBinaryOperation::Subtraction: return new FloatEvalValue(_value - rightVal);
|
||||
case Binder::BoundBinaryOperation::Multiplication: return new FloatEvalValue(_value * rightVal);
|
||||
case Binder::BoundBinaryOperation::Division: return new FloatEvalValue(_value / rightVal);
|
||||
case Binder::BoundBinaryOperation::LessThan: return new BooleanEvalValue(_value < rightVal);
|
||||
case Binder::BoundBinaryOperation::LessThanEquals: return new BooleanEvalValue(_value <= rightVal);
|
||||
case Binder::BoundBinaryOperation::GreaterThan: return new BooleanEvalValue(_value > rightVal);
|
||||
case Binder::BoundBinaryOperation::GreaterThanEquals: return new BooleanEvalValue(_value >= rightVal);
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
} else {
|
||||
auto rightVal = right->EvaluateInteger();
|
||||
switch (operation) {
|
||||
case Binder::BoundBinaryOperation::Addition:
|
||||
return new IntegerEvalValue((int64_t ) _value + rightVal);
|
||||
case Binder::BoundBinaryOperation::Subtraction:
|
||||
return new IntegerEvalValue((int64_t ) _value - rightVal);
|
||||
case Binder::BoundBinaryOperation::Multiplication:
|
||||
return new IntegerEvalValue((int64_t ) _value * rightVal);
|
||||
case Binder::BoundBinaryOperation::Division:
|
||||
return new IntegerEvalValue((int64_t ) _value / rightVal);
|
||||
case Binder::BoundBinaryOperation::LessThan:
|
||||
return new BooleanEvalValue(_value < rightVal);
|
||||
case Binder::BoundBinaryOperation::LessThanEquals:
|
||||
return new BooleanEvalValue(_value <= rightVal);
|
||||
case Binder::BoundBinaryOperation::GreaterThan:
|
||||
return new BooleanEvalValue(_value > rightVal);
|
||||
case Binder::BoundBinaryOperation::GreaterThanEquals:
|
||||
return new BooleanEvalValue(_value >= rightVal);
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
EvalValue* UnaryOperation(Binder::BoundUnaryOperation operation) const final{
|
||||
switch (operation){
|
||||
case Binder::BoundUnaryOperation::Negation: return new FloatEvalValue(-_value);
|
||||
default: throw;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
EvalValue* Cast(shared_ptr<const ScriptType> castType) const final;
|
||||
[[nodiscard]] EvalValue *BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue *b) const final;
|
||||
[[nodiscard]] EvalValue *UnaryOperation(Binder::BoundUnaryOperation operation) const override;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ namespace Porygon::Evaluation {
|
|||
auto statements = *block -> GetStatements();
|
||||
if (step >= 0){
|
||||
for (int64_t i = start; i <= end; i += step){
|
||||
this -> _evaluationScope -> SetVariable(identifier, new IntegerEvalValue(i));
|
||||
this -> _evaluationScope -> SetVariable(identifier, new NumericEvalValue(i));
|
||||
for (auto s: statements) {
|
||||
this->EvaluateStatement(s);
|
||||
if (this->_hasReturned || this -> _hasBroken)
|
||||
|
@ -165,7 +165,7 @@ namespace Porygon::Evaluation {
|
|||
}
|
||||
} else{
|
||||
for (int64_t i = start; i >= end; i += step){
|
||||
this -> _evaluationScope -> SetVariable(identifier, new IntegerEvalValue(i));
|
||||
this -> _evaluationScope -> SetVariable(identifier, new NumericEvalValue(i));
|
||||
for (auto s: statements) {
|
||||
this->EvaluateStatement(s);
|
||||
if (this->_hasReturned || this -> _hasBroken)
|
||||
|
@ -233,9 +233,9 @@ namespace Porygon::Evaluation {
|
|||
|
||||
case BoundExpressionKind::Bad: throw;
|
||||
case BoundExpressionKind::LiteralInteger:
|
||||
return new IntegerEvalValue(((BoundLiteralIntegerExpression *) expression)->GetValue());
|
||||
return new NumericEvalValue(((BoundLiteralIntegerExpression *) expression)->GetValue());
|
||||
case BoundExpressionKind::LiteralFloat:
|
||||
return new FloatEvalValue(((BoundLiteralFloatExpression *) expression)->GetValue());
|
||||
return new NumericEvalValue(((BoundLiteralFloatExpression *) expression)->GetValue());
|
||||
case BoundExpressionKind::LiteralString:
|
||||
return new StringEvalValue(*((BoundLiteralStringExpression *) expression)->GetValue());
|
||||
case BoundExpressionKind::LiteralBool:
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Porygon::Evaluation{
|
|||
: _vec(table->GetTable()), _size(_vec->size() + 1){}
|
||||
|
||||
inline const EvalValue* GetCurrent() final{
|
||||
return new IntegerEvalValue(_position);
|
||||
return new NumericEvalValue(static_cast<int64_t >(_position));
|
||||
}
|
||||
|
||||
inline bool MoveNext() final{
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace Porygon::StandardLibraries{
|
|||
static const Evaluation::EvalValue* _toInt(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
auto parameter = parameters[0]->EvaluateString();
|
||||
auto parsed = Utilities::StringUtils::ParseInteger(parameter);
|
||||
return new Evaluation::IntegerEvalValue(parsed);
|
||||
return new Evaluation::NumericEvalValue(parsed);
|
||||
}
|
||||
static shared_ptr<GenericFunctionScriptType> GetToIntFuncType(){
|
||||
return GetFuncType(NumericScriptType::AwareInt,
|
||||
|
@ -77,7 +77,7 @@ namespace Porygon::StandardLibraries{
|
|||
static const Evaluation::EvalValue* _toFloat(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
auto parameter = parameters[0]->EvaluateString();
|
||||
auto parsed = Utilities::StringUtils::ParseFloat(parameter);
|
||||
return new Evaluation::FloatEvalValue(parsed);
|
||||
return new Evaluation::NumericEvalValue(parsed);
|
||||
}
|
||||
static shared_ptr<GenericFunctionScriptType> GetToFloatFuncType(){
|
||||
return GetFuncType(NumericScriptType::AwareFloat,
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace Porygon::StandardLibraries{
|
||||
using namespace Porygon::Evaluation;
|
||||
const EvalValue* MathLibrary::_huge = new FloatEvalValue(DBL_MAX);
|
||||
const EvalValue* MathLibrary::_maxInteger = new IntegerEvalValue(INT64_MAX);
|
||||
const EvalValue* MathLibrary::_minInteger = new IntegerEvalValue(INT64_MIN);
|
||||
const EvalValue* MathLibrary::_pi = new FloatEvalValue(M_PI);
|
||||
const EvalValue* MathLibrary::_huge = new NumericEvalValue(DBL_MAX);
|
||||
const EvalValue* MathLibrary::_maxInteger = new NumericEvalValue(INT64_MAX);
|
||||
const EvalValue* MathLibrary::_minInteger = new NumericEvalValue(INT64_MIN);
|
||||
const EvalValue* MathLibrary::_pi = new NumericEvalValue(M_PI);
|
||||
}
|
|
@ -42,67 +42,67 @@ namespace Porygon::StandardLibraries {
|
|||
static const EvalValue* _abs(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
if (parameter->IsFloat()){
|
||||
return new FloatEvalValue(std::abs(parameter->EvaluateFloat()));
|
||||
return new NumericEvalValue(std::abs(parameter->EvaluateFloat()));
|
||||
} else{
|
||||
return new IntegerEvalValue(std::abs(parameter->EvaluateInteger()));
|
||||
return new NumericEvalValue(std::abs(parameter->EvaluateInteger()));
|
||||
}
|
||||
}
|
||||
|
||||
static const EvalValue* _acos(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
return new FloatEvalValue(std::acos(parameter->EvaluateFloat()));
|
||||
return new NumericEvalValue(std::acos(parameter->EvaluateFloat()));
|
||||
}
|
||||
|
||||
static const EvalValue* _asin(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
return new FloatEvalValue(std::asin(parameter->EvaluateFloat()));
|
||||
return new NumericEvalValue(std::asin(parameter->EvaluateFloat()));
|
||||
}
|
||||
|
||||
static const EvalValue* _atan(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
if (parameterCount == 1){
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
return new FloatEvalValue(std::atan(parameter->EvaluateFloat()));
|
||||
return new NumericEvalValue(std::atan(parameter->EvaluateFloat()));
|
||||
}
|
||||
else{
|
||||
auto parameter1 = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
auto parameter2 = dynamic_cast<const NumericEvalValue*>(parameters[1]);
|
||||
return new FloatEvalValue(std::atan2(parameter1->EvaluateFloat(), parameter2->EvaluateFloat()));
|
||||
return new NumericEvalValue(std::atan2(parameter1->EvaluateFloat(), parameter2->EvaluateFloat()));
|
||||
}
|
||||
}
|
||||
static const EvalValue* _ceil(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
auto f = parameter->EvaluateFloat();
|
||||
return new IntegerEvalValue(std::ceil(f));
|
||||
return new NumericEvalValue(static_cast<int64_t>(std::ceil(f)));
|
||||
}
|
||||
|
||||
static const EvalValue* _cos(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
auto f = parameter->EvaluateFloat();
|
||||
return new FloatEvalValue(std::cos(f));
|
||||
return new NumericEvalValue(std::cos(f));
|
||||
}
|
||||
|
||||
static const EvalValue* _deg(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
auto f = parameter->EvaluateFloat();
|
||||
return new FloatEvalValue(f * 180 / M_PI);
|
||||
return new NumericEvalValue(f * 180 / M_PI);
|
||||
}
|
||||
|
||||
static const EvalValue* _exp(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
auto f = parameter->EvaluateFloat();
|
||||
return new FloatEvalValue(std::exp(f));
|
||||
return new NumericEvalValue(std::exp(f));
|
||||
}
|
||||
|
||||
static const EvalValue* _floor(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
auto f = parameter->EvaluateFloat();
|
||||
return new IntegerEvalValue(std::floor(f));
|
||||
return new NumericEvalValue(std::floor(f));
|
||||
}
|
||||
|
||||
static const EvalValue* _fmod(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto f1 = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat();
|
||||
auto f2 = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat();
|
||||
return new FloatEvalValue(std::fmod(f1, f2));
|
||||
return new NumericEvalValue(std::fmod(f1, f2));
|
||||
}
|
||||
|
||||
static const EvalValue* _huge;
|
||||
|
@ -110,12 +110,12 @@ namespace Porygon::StandardLibraries {
|
|||
static const EvalValue* _log(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
if (parameterCount == 1){
|
||||
auto f = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat();
|
||||
return new FloatEvalValue(std::log(f));
|
||||
return new NumericEvalValue(std::log(f));
|
||||
}
|
||||
else{
|
||||
auto f1 = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat();
|
||||
auto f2 = dynamic_cast<const NumericEvalValue*>(parameters[1])->EvaluateFloat();
|
||||
return new FloatEvalValue(std::log(f2) / std::log(f1));
|
||||
return new NumericEvalValue(std::log(f2) / std::log(f1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,22 +126,22 @@ namespace Porygon::StandardLibraries {
|
|||
static const EvalValue* _rad(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
auto f = parameter->EvaluateFloat();
|
||||
return new FloatEvalValue(M_PI *(f / 180));
|
||||
return new NumericEvalValue(M_PI *(f / 180));
|
||||
}
|
||||
|
||||
static const EvalValue* _sin(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
return new FloatEvalValue(std::sin(parameter->EvaluateFloat()));
|
||||
return new NumericEvalValue(std::sin(parameter->EvaluateFloat()));
|
||||
}
|
||||
|
||||
static const EvalValue* _sqrt(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
return new FloatEvalValue(std::sqrt(parameter->EvaluateFloat()));
|
||||
return new NumericEvalValue(std::sqrt(parameter->EvaluateFloat()));
|
||||
}
|
||||
|
||||
static const EvalValue* _tan(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||
return new FloatEvalValue(std::tan(parameter->EvaluateFloat()));
|
||||
return new NumericEvalValue(std::tan(parameter->EvaluateFloat()));
|
||||
}
|
||||
|
||||
static const EvalValue* _ult(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Porygon::UserData{
|
|||
}
|
||||
|
||||
const Evaluation::EvalValue* GetCurrent() final{
|
||||
return new Evaluation::IntegerEvalValue(_current);
|
||||
return new Evaluation::NumericEvalValue(static_cast<int64_t>(_current));
|
||||
}
|
||||
bool MoveNext() final{
|
||||
_current ++;
|
||||
|
|
|
@ -51,11 +51,11 @@
|
|||
|
||||
#define PORYGON_INTEGER_FIELD(fieldName) \
|
||||
PORYGON_FIELD(fieldName, PORYGON_INTEGER_TYPE, \
|
||||
const Porygon::Evaluation::IntegerEvalValue(((T_USERDATA*)obj)->fieldName), val->EvaluateInteger())
|
||||
const Porygon::Evaluation::NumericEvalValue(((T_USERDATA*)obj)->fieldName), val->EvaluateInteger())
|
||||
|
||||
#define PORYGON_READONLY_INTEGER_FIELD(fieldName) \
|
||||
PORYGON_READONLY_FIELD(fieldName, PORYGON_INTEGER_TYPE, \
|
||||
Porygon::Evaluation::IntegerEvalValue(((T_USERDATA*)obj)->fieldName))
|
||||
Porygon::Evaluation::NumericEvalValue(((T_USERDATA*)obj)->fieldName))
|
||||
|
||||
#define PORYGON_FLOAT_FIELD(fieldName) \
|
||||
PORYGON_FIELD(fieldName, PORYGON_FLOAT_TYPE, \
|
||||
|
|
|
@ -51,10 +51,10 @@ TEST_CASE( "Define script function and call from extern", "[integration]" ) {
|
|||
script->Evaluate();
|
||||
|
||||
REQUIRE(script->HasFunction(u"add"));
|
||||
auto toAddVal = new IntegerEvalValue(5);
|
||||
auto toAddVal = new NumericEvalValue(5);
|
||||
script->CallFunction(u"add", {toAddVal});
|
||||
delete toAddVal;
|
||||
toAddVal = new IntegerEvalValue(6);
|
||||
toAddVal = new NumericEvalValue(6);
|
||||
script->CallFunction(u"add", {toAddVal});
|
||||
delete toAddVal;
|
||||
|
||||
|
@ -76,8 +76,8 @@ TEST_CASE( "Define script function and return", "[integration]" ) {
|
|||
script->Evaluate();
|
||||
|
||||
REQUIRE(script->HasFunction(u"add"));
|
||||
auto toAddVal = new IntegerEvalValue(5);
|
||||
auto toAddVal2 = new IntegerEvalValue(6);
|
||||
auto toAddVal = new NumericEvalValue(5);
|
||||
auto toAddVal2 = new NumericEvalValue(6);
|
||||
auto result = script->CallFunction(u"add", {toAddVal, toAddVal2});
|
||||
delete toAddVal;
|
||||
delete toAddVal2;
|
||||
|
|
Loading…
Reference in New Issue