Greatly simplify handling numerical eval values, using std::variant
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2019-09-07 10:57:09 +02:00
parent 7b5d03ed74
commit 5d700aa0e9
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
12 changed files with 183 additions and 393 deletions

View File

@ -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) {

View File

@ -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);
}
};
}

View File

@ -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));
}
}

View File

@ -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;
};
}

View File

@ -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:

View File

@ -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{

View File

@ -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,

View File

@ -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);
}

View File

@ -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) {

View File

@ -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 ++;

View File

@ -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, \

View File

@ -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;