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

This commit is contained in:
2019-09-07 10:57:09 +02:00
parent 7b5d03ed74
commit 5d700aa0e9
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{