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) { EvalValue *CreateIntegerEvalValue(int64_t l) {
return new IntegerEvalValue(l); return new NumericEvalValue(l);
} }
EvalValue *CreateFloatEvalValue(double d) { EvalValue *CreateFloatEvalValue(double d) {
return new FloatEvalValue(d); return new NumericEvalValue(d);
} }
EvalValue *CreateBoolEvalValue(bool b) { EvalValue *CreateBoolEvalValue(bool b) {

View File

@ -9,38 +9,38 @@ namespace Porygon::Evaluation{
class EvalValueHelper{ class EvalValueHelper{
public: public:
inline static EvalValue* Create(unsigned char i){ 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){ 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){ inline static EvalValue* Create(short int i){
return new IntegerEvalValue(i); return new NumericEvalValue(i);
} }
inline static EvalValue* Create(unsigned short int i){ inline static EvalValue* Create(unsigned short int i){
return new IntegerEvalValue(i); return new NumericEvalValue(i);
} }
inline static EvalValue* Create(signed int i){ inline static EvalValue* Create(signed int i){
return new IntegerEvalValue(i); return new NumericEvalValue(i);
} }
inline static EvalValue* Create(unsigned int 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){ inline static EvalValue* Create(int64_t l){
return new IntegerEvalValue(l); return new NumericEvalValue(l);
} }
inline static EvalValue* Create(uint64_t 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){ inline static EvalValue* Create(float f){
return new FloatEvalValue(f); return new NumericEvalValue(f);
} }
inline static EvalValue* Create(double f){ inline static EvalValue* Create(double f){
return new FloatEvalValue(f); return new NumericEvalValue(f);
} }
inline static EvalValue* Create(long double 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){ inline static EvalValue* Create(bool b){
@ -49,8 +49,8 @@ namespace Porygon::Evaluation{
inline static EvalValue* Create(const string& s){ inline static EvalValue* Create(const string& s){
return new StringEvalValue(Utilities::StringUtils::ToUTF8(s)); return new StringEvalValue(Utilities::StringUtils::ToUTF8(s));
} }
inline static EvalValue* Create(u16string s){ inline static EvalValue* Create(const u16string& s){
return new StringEvalValue(std::move(s)); return new StringEvalValue(s);
} }
}; };
} }

View File

@ -2,198 +2,139 @@
#include "NumericEvalValue.hpp" #include "NumericEvalValue.hpp"
namespace Porygon::Evaluation { namespace Porygon::Evaluation {
shared_ptr<const NumericEvalValue> NumericEvalValue::operator+(const shared_ptr<const NumericEvalValue> &b) const { EvalValue *NumericEvalValue::BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue *b) const {
if (this->IsFloat()) { auto right = dynamic_cast<const NumericEvalValue*>(b);
if (b->IsFloat()) { if (_isFloat){
return make_shared<FloatEvalValue>(this->GetFloatValue() + b->GetFloatValue()); double v1 = std::get<double >(_floatValue);
} else { if (right->_isFloat){
return make_shared<FloatEvalValue>(this->GetFloatValue() + (double) b->GetIntegerValue()); 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 { else{
if (b->IsFloat()) { int64_t v2 = std::get<int64_t >(right->_intValue);
return make_shared<FloatEvalValue>((double) this->GetIntegerValue() + b->GetFloatValue()); switch (operation){
} else {
return make_shared<IntegerEvalValue>(this->GetIntegerValue() + b->GetIntegerValue()); 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 { EvalValue *NumericEvalValue::Cast(shared_ptr<const ScriptType> castType) const {
if (this->IsFloat()) { if (castType->GetClass() == TypeClass::Number){
if (b->IsFloat()) { auto num = static_pointer_cast<const NumericScriptType>(castType);
return make_shared<FloatEvalValue>(this->GetFloatValue() - b->GetFloatValue()); if (num->IsFloat()){
} else { return new NumericEvalValue(std::get<int64_t >(_intValue));
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());
} }
} }
return EvalValue::Cast(castType);
} }
shared_ptr<const NumericEvalValue> NumericEvalValue::operator*(const shared_ptr<const NumericEvalValue> &b) const { EvalValue *NumericEvalValue::Clone() const {
if (this->IsFloat()) { if (_isFloat)
if (b->IsFloat()) { return new NumericEvalValue(std::get<double >(_floatValue));
return make_shared<FloatEvalValue>(this->GetFloatValue() * b->GetFloatValue()); return new NumericEvalValue(std::get<int64_t >(_intValue));
} 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());
}
}
} }
shared_ptr<const NumericEvalValue> NumericEvalValue::operator/(const shared_ptr<const NumericEvalValue> &b) const { size_t NumericEvalValue::GetHashCode() const {
if (this->IsFloat()) { if (_isFloat)
if (b->IsFloat()) { return std::get<double >(_floatValue);
return make_shared<FloatEvalValue>(this->GetFloatValue() / b->GetFloatValue()); return std::get<int64_t >(_intValue);;
} 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());
}
}
} }
bool NumericEvalValue::operator==(const EvalValue *b) const { bool NumericEvalValue::operator==(const EvalValue *b) const {
if (b->GetTypeClass() != TypeClass::Number) if (b->GetTypeClass() != TypeClass::Number)
return false; 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); auto right = dynamic_cast<const NumericEvalValue*>(b);
if (right->IsFloat()){ if (_isFloat != right->_isFloat)
auto rightVal = right->EvaluateFloat(); return false;
switch (operation){ if (_isFloat){
case Binder::BoundBinaryOperation::Addition: return new FloatEvalValue((double)_value + rightVal); return _floatValue == right->_floatValue;
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;
}
} }
return _intValue == right->_intValue;
} }
EvalValue *IntegerEvalValue::Cast(shared_ptr<const ScriptType> castType) const { int64_t NumericEvalValue::EvaluateInteger() const {
if (castType->GetClass() == TypeClass::Number){ return std::get<int64_t >(_intValue);;
auto num = static_pointer_cast<const NumericScriptType>(castType);
if (num->IsFloat()){
return new FloatEvalValue(GetIntegerValue());
}
}
return EvalValue::Cast(castType);
} }
EvalValue *FloatEvalValue::Cast(shared_ptr<const ScriptType> castType) const { double NumericEvalValue::EvaluateFloat() const {
if (castType->GetClass() == TypeClass::Number){ if (!_isFloat)
auto num = static_pointer_cast<const NumericScriptType>(castType); return std::get<int64_t >(_intValue);
if (!num->IsFloat()){ return std::get<double>(_floatValue);
return new IntegerEvalValue(GetFloatValue());
}
}
return EvalValue::Cast(castType);
} }
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 #define PORYGONLANG_NUMERICEVALVALUE_HPP
#include <sstream> #include <sstream>
#include <variant>
#include "EvalValue.hpp" #include "EvalValue.hpp"
#include "../../Utilities/StringUtils.hpp" #include "../../Utilities/StringUtils.hpp"
namespace Porygon::Evaluation { namespace Porygon::Evaluation {
class NumericEvalValue : public EvalValue { class NumericEvalValue : public EvalValue {
std::variant<int64_t , double> _intValue, _floatValue;
[[nodiscard]] bool _isFloat;
virtual int64_t GetIntegerValue() const = 0;
[[nodiscard]]
virtual double GetFloatValue() const = 0;
public: 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]] [[nodiscard]]
virtual bool IsFloat() const = 0; virtual bool IsFloat() const{
return _isFloat;
}
[[nodiscard]] [[nodiscard]]
inline TypeClass GetTypeClass() const final { inline TypeClass GetTypeClass() const final {
return TypeClass::Number; 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; bool operator==(const EvalValue *b) const final;
};
class IntegerEvalValue : public NumericEvalValue { [[nodiscard]] EvalValue *Clone() const override;
const int64_t _value; [[nodiscard]] size_t GetHashCode() const override;
[[nodiscard]] EvalValue* Cast(shared_ptr<const ScriptType> castType) const final;
[[nodiscard]] [[nodiscard]] int64_t EvaluateInteger() const override;
int64_t GetIntegerValue() const final { return _value; } [[nodiscard]] double EvaluateFloat() const override;
[[nodiscard]] u16string EvaluateString() const override;
[[nodiscard]] [[nodiscard]] EvalValue *BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue *b) const final;
double GetFloatValue() const final { [[nodiscard]] EvalValue *UnaryOperation(Binder::BoundUnaryOperation operation) const override;
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;
}; };
} }

View File

@ -154,7 +154,7 @@ namespace Porygon::Evaluation {
auto statements = *block -> GetStatements(); auto statements = *block -> GetStatements();
if (step >= 0){ if (step >= 0){
for (int64_t i = start; i <= end; i += step){ 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) { for (auto s: statements) {
this->EvaluateStatement(s); this->EvaluateStatement(s);
if (this->_hasReturned || this -> _hasBroken) if (this->_hasReturned || this -> _hasBroken)
@ -165,7 +165,7 @@ namespace Porygon::Evaluation {
} }
} else{ } else{
for (int64_t i = start; i >= end; i += step){ 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) { for (auto s: statements) {
this->EvaluateStatement(s); this->EvaluateStatement(s);
if (this->_hasReturned || this -> _hasBroken) if (this->_hasReturned || this -> _hasBroken)
@ -233,9 +233,9 @@ namespace Porygon::Evaluation {
case BoundExpressionKind::Bad: throw; case BoundExpressionKind::Bad: throw;
case BoundExpressionKind::LiteralInteger: case BoundExpressionKind::LiteralInteger:
return new IntegerEvalValue(((BoundLiteralIntegerExpression *) expression)->GetValue()); return new NumericEvalValue(((BoundLiteralIntegerExpression *) expression)->GetValue());
case BoundExpressionKind::LiteralFloat: case BoundExpressionKind::LiteralFloat:
return new FloatEvalValue(((BoundLiteralFloatExpression *) expression)->GetValue()); return new NumericEvalValue(((BoundLiteralFloatExpression *) expression)->GetValue());
case BoundExpressionKind::LiteralString: case BoundExpressionKind::LiteralString:
return new StringEvalValue(*((BoundLiteralStringExpression *) expression)->GetValue()); return new StringEvalValue(*((BoundLiteralStringExpression *) expression)->GetValue());
case BoundExpressionKind::LiteralBool: case BoundExpressionKind::LiteralBool:

View File

@ -17,7 +17,7 @@ namespace Porygon::Evaluation{
: _vec(table->GetTable()), _size(_vec->size() + 1){} : _vec(table->GetTable()), _size(_vec->size() + 1){}
inline const EvalValue* GetCurrent() final{ inline const EvalValue* GetCurrent() final{
return new IntegerEvalValue(_position); return new NumericEvalValue(static_cast<int64_t >(_position));
} }
inline bool MoveNext() final{ 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){ static const Evaluation::EvalValue* _toInt(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
auto parameter = parameters[0]->EvaluateString(); auto parameter = parameters[0]->EvaluateString();
auto parsed = Utilities::StringUtils::ParseInteger(parameter); auto parsed = Utilities::StringUtils::ParseInteger(parameter);
return new Evaluation::IntegerEvalValue(parsed); return new Evaluation::NumericEvalValue(parsed);
} }
static shared_ptr<GenericFunctionScriptType> GetToIntFuncType(){ static shared_ptr<GenericFunctionScriptType> GetToIntFuncType(){
return GetFuncType(NumericScriptType::AwareInt, 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){ static const Evaluation::EvalValue* _toFloat(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
auto parameter = parameters[0]->EvaluateString(); auto parameter = parameters[0]->EvaluateString();
auto parsed = Utilities::StringUtils::ParseFloat(parameter); auto parsed = Utilities::StringUtils::ParseFloat(parameter);
return new Evaluation::FloatEvalValue(parsed); return new Evaluation::NumericEvalValue(parsed);
} }
static shared_ptr<GenericFunctionScriptType> GetToFloatFuncType(){ static shared_ptr<GenericFunctionScriptType> GetToFloatFuncType(){
return GetFuncType(NumericScriptType::AwareFloat, return GetFuncType(NumericScriptType::AwareFloat,

View File

@ -2,8 +2,8 @@
namespace Porygon::StandardLibraries{ namespace Porygon::StandardLibraries{
using namespace Porygon::Evaluation; using namespace Porygon::Evaluation;
const EvalValue* MathLibrary::_huge = new FloatEvalValue(DBL_MAX); const EvalValue* MathLibrary::_huge = new NumericEvalValue(DBL_MAX);
const EvalValue* MathLibrary::_maxInteger = new IntegerEvalValue(INT64_MAX); const EvalValue* MathLibrary::_maxInteger = new NumericEvalValue(INT64_MAX);
const EvalValue* MathLibrary::_minInteger = new IntegerEvalValue(INT64_MIN); const EvalValue* MathLibrary::_minInteger = new NumericEvalValue(INT64_MIN);
const EvalValue* MathLibrary::_pi = new FloatEvalValue(M_PI); 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){ static const EvalValue* _abs(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
if (parameter->IsFloat()){ if (parameter->IsFloat()){
return new FloatEvalValue(std::abs(parameter->EvaluateFloat())); return new NumericEvalValue(std::abs(parameter->EvaluateFloat()));
} else{ } 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) { static const EvalValue* _acos(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); 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) { static const EvalValue* _asin(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); 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) { static const EvalValue* _atan(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
if (parameterCount == 1){ if (parameterCount == 1){
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
return new FloatEvalValue(std::atan(parameter->EvaluateFloat())); return new NumericEvalValue(std::atan(parameter->EvaluateFloat()));
} }
else{ else{
auto parameter1 = dynamic_cast<const NumericEvalValue*>(parameters[0]); auto parameter1 = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto parameter2 = dynamic_cast<const NumericEvalValue*>(parameters[1]); 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) { static const EvalValue* _ceil(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat(); 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) { static const EvalValue* _cos(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat(); 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) { static const EvalValue* _deg(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat(); 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) { static const EvalValue* _exp(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat(); 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) { static const EvalValue* _floor(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat(); 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) { static const EvalValue* _fmod(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto f1 = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat(); auto f1 = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat();
auto f2 = 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; static const EvalValue* _huge;
@ -110,12 +110,12 @@ namespace Porygon::StandardLibraries {
static const EvalValue* _log(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){ static const EvalValue* _log(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
if (parameterCount == 1){ if (parameterCount == 1){
auto f = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat(); auto f = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat();
return new FloatEvalValue(std::log(f)); return new NumericEvalValue(std::log(f));
} }
else{ else{
auto f1 = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat(); auto f1 = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat();
auto f2 = dynamic_cast<const NumericEvalValue*>(parameters[1])->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) { static const EvalValue* _rad(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat(); 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) { static const EvalValue* _sin(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); 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) { static const EvalValue* _sqrt(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); 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) { static const EvalValue* _tan(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]); 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) { 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{ const Evaluation::EvalValue* GetCurrent() final{
return new Evaluation::IntegerEvalValue(_current); return new Evaluation::NumericEvalValue(static_cast<int64_t>(_current));
} }
bool MoveNext() final{ bool MoveNext() final{
_current ++; _current ++;

View File

@ -51,11 +51,11 @@
#define PORYGON_INTEGER_FIELD(fieldName) \ #define PORYGON_INTEGER_FIELD(fieldName) \
PORYGON_FIELD(fieldName, PORYGON_INTEGER_TYPE, \ 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) \ #define PORYGON_READONLY_INTEGER_FIELD(fieldName) \
PORYGON_READONLY_FIELD(fieldName, PORYGON_INTEGER_TYPE, \ 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) \ #define PORYGON_FLOAT_FIELD(fieldName) \
PORYGON_FIELD(fieldName, PORYGON_FLOAT_TYPE, \ PORYGON_FIELD(fieldName, PORYGON_FLOAT_TYPE, \

View File

@ -51,10 +51,10 @@ TEST_CASE( "Define script function and call from extern", "[integration]" ) {
script->Evaluate(); script->Evaluate();
REQUIRE(script->HasFunction(u"add")); REQUIRE(script->HasFunction(u"add"));
auto toAddVal = new IntegerEvalValue(5); auto toAddVal = new NumericEvalValue(5);
script->CallFunction(u"add", {toAddVal}); script->CallFunction(u"add", {toAddVal});
delete toAddVal; delete toAddVal;
toAddVal = new IntegerEvalValue(6); toAddVal = new NumericEvalValue(6);
script->CallFunction(u"add", {toAddVal}); script->CallFunction(u"add", {toAddVal});
delete toAddVal; delete toAddVal;
@ -76,8 +76,8 @@ TEST_CASE( "Define script function and return", "[integration]" ) {
script->Evaluate(); script->Evaluate();
REQUIRE(script->HasFunction(u"add")); REQUIRE(script->HasFunction(u"add"));
auto toAddVal = new IntegerEvalValue(5); auto toAddVal = new NumericEvalValue(5);
auto toAddVal2 = new IntegerEvalValue(6); auto toAddVal2 = new NumericEvalValue(6);
auto result = script->CallFunction(u"add", {toAddVal, toAddVal2}); auto result = script->CallFunction(u"add", {toAddVal, toAddVal2});
delete toAddVal; delete toAddVal;
delete toAddVal2; delete toAddVal2;