Rework of memory handling in Evaluation
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
268f6b59fb
commit
ccc6e297f2
|
@ -1,91 +0,0 @@
|
||||||
|
|
||||||
#include "../Script.hpp"
|
|
||||||
#include "EvaluationException.hpp"
|
|
||||||
#include "Evaluator.hpp"
|
|
||||||
#include "EvalValues/NumericEvalValue.hpp"
|
|
||||||
#include "EvalValues/StringEvalValue.hpp"
|
|
||||||
|
|
||||||
using namespace Porygon::Binder;
|
|
||||||
|
|
||||||
namespace Porygon::Evaluation {
|
|
||||||
shared_ptr<const NumericEvalValue> Evaluator::EvaluateIntegerBinary(const BoundBinaryExpression *expression) {
|
|
||||||
auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft());
|
|
||||||
auto rightValue = this->EvaluateIntegerExpression(expression->GetRight());
|
|
||||||
|
|
||||||
switch (expression->GetOperation()) {
|
|
||||||
case BoundBinaryOperation::Addition:
|
|
||||||
return leftValue.get()->operator+(rightValue);
|
|
||||||
case BoundBinaryOperation::Subtraction:
|
|
||||||
return leftValue.get()->operator-(rightValue);
|
|
||||||
case BoundBinaryOperation::Multiplication:
|
|
||||||
return leftValue.get()->operator*(rightValue);
|
|
||||||
case BoundBinaryOperation::Division:
|
|
||||||
return leftValue.get()->operator/(rightValue);
|
|
||||||
default:
|
|
||||||
throw EvaluationException("Can't evaluate operation to numeric");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<const BooleanEvalValue> Evaluator::EvaluateBooleanBinary(const BoundBinaryExpression *expression) {
|
|
||||||
switch (expression->GetOperation()) {
|
|
||||||
case BoundBinaryOperation::Equality: {
|
|
||||||
auto leftValue = this->EvaluateExpression(expression->GetLeft());
|
|
||||||
auto rightValue = this->EvaluateExpression(expression->GetRight());
|
|
||||||
bool equals = leftValue.get()->operator==(rightValue.get());
|
|
||||||
return make_shared<BooleanEvalValue>(equals);
|
|
||||||
}
|
|
||||||
case BoundBinaryOperation::Inequality: {
|
|
||||||
auto leftValue = this->EvaluateExpression(expression->GetLeft());
|
|
||||||
auto rightValue = this->EvaluateExpression(expression->GetRight());
|
|
||||||
bool equals = leftValue.get()->operator!=(rightValue.get());
|
|
||||||
return make_shared<BooleanEvalValue>(equals);
|
|
||||||
}
|
|
||||||
case BoundBinaryOperation::LessThan: {
|
|
||||||
auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft());
|
|
||||||
auto rightValue = this->EvaluateIntegerExpression(expression->GetRight());
|
|
||||||
return leftValue->operator<(rightValue);
|
|
||||||
}
|
|
||||||
case BoundBinaryOperation::LessThanEquals: {
|
|
||||||
auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft());
|
|
||||||
auto rightValue = this->EvaluateIntegerExpression(expression->GetRight());
|
|
||||||
return leftValue->operator<=(rightValue);
|
|
||||||
}
|
|
||||||
case BoundBinaryOperation::GreaterThan: {
|
|
||||||
auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft());
|
|
||||||
auto rightValue = this->EvaluateIntegerExpression(expression->GetRight());
|
|
||||||
return leftValue->operator>(rightValue);
|
|
||||||
}
|
|
||||||
case BoundBinaryOperation::GreaterThanEquals: {
|
|
||||||
auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft());
|
|
||||||
auto rightValue = this->EvaluateIntegerExpression(expression->GetRight());
|
|
||||||
return leftValue->operator>=(rightValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
case BoundBinaryOperation::LogicalAnd: {
|
|
||||||
auto leftValue = this->EvaluateBoolExpression(expression->GetLeft());
|
|
||||||
if (!leftValue->EvaluateBool()) return leftValue;
|
|
||||||
auto rightValue = this->EvaluateBoolExpression(expression->GetRight());
|
|
||||||
return rightValue;
|
|
||||||
}
|
|
||||||
case BoundBinaryOperation::LogicalOr: {
|
|
||||||
auto leftValue = this->EvaluateBoolExpression(expression->GetLeft());
|
|
||||||
if (leftValue->EvaluateBool()) return leftValue;
|
|
||||||
auto rightValue = this->EvaluateBoolExpression(expression->GetRight());
|
|
||||||
return rightValue;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw EvaluationException("Can't evaluate operation to boolean");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<const StringEvalValue> Evaluator::EvaluateStringBinary(const BoundBinaryExpression *expression) {
|
|
||||||
if (expression->GetOperation() != BoundBinaryOperation::Concatenation)
|
|
||||||
throw;
|
|
||||||
std::basic_ostringstream<char16_t> stringStream;
|
|
||||||
auto left = this->EvaluateStringExpression(expression->GetLeft());
|
|
||||||
stringStream << left->EvaluateString();
|
|
||||||
auto right = this->EvaluateExpression(expression->GetRight());
|
|
||||||
stringStream << right->EvaluateString();
|
|
||||||
return make_shared<StringEvalValue>(stringStream.str());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
#include "EvalValuePointer.hpp"
|
|
@ -0,0 +1,85 @@
|
||||||
|
#ifndef PORYGONLANG_EVALVALUEPOINTER_HPP
|
||||||
|
#define PORYGONLANG_EVALVALUEPOINTER_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include "EvalValues/EvalValue.hpp"
|
||||||
|
|
||||||
|
namespace Porygon::Evaluation {
|
||||||
|
class EvalValuePointer {
|
||||||
|
const EvalValue *_ptr;
|
||||||
|
public:
|
||||||
|
EvalValuePointer(const EvalValue* p) :_ptr(p){};
|
||||||
|
EvalValuePointer(const EvalValuePointer& b){
|
||||||
|
if (b._ptr == nullptr){
|
||||||
|
_ptr = nullptr;
|
||||||
|
} else{
|
||||||
|
_ptr = b._ptr->Clone();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
EvalValuePointer(){
|
||||||
|
_ptr = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
~EvalValuePointer(){
|
||||||
|
delete _ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
inline const EvalValue* Get() const{
|
||||||
|
return _ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
inline const EvalValue* Clone() const{
|
||||||
|
if (_ptr == nullptr){
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return _ptr->Clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const EvalValue* Take(){
|
||||||
|
auto p = _ptr;
|
||||||
|
_ptr = nullptr;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void ClearAssign(const EvalValue* n){
|
||||||
|
delete _ptr;
|
||||||
|
_ptr = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const bool HasValue() const{
|
||||||
|
return _ptr == nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const EvalValue* operator ->() const{
|
||||||
|
return Get();
|
||||||
|
}
|
||||||
|
inline bool operator == (const EvalValuePointer& b) const{
|
||||||
|
if (!_ptr){
|
||||||
|
return !b._ptr;
|
||||||
|
}
|
||||||
|
if (!b._ptr) return false;
|
||||||
|
return _ptr->operator==(b._ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator != (const EvalValuePointer& b) const{
|
||||||
|
if (!_ptr){
|
||||||
|
return b._ptr;
|
||||||
|
}
|
||||||
|
if (!b._ptr) return false;
|
||||||
|
return _ptr->operator!=(b._ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalValuePointer& operator =(const EvalValuePointer& a){
|
||||||
|
if (a._ptr == nullptr){
|
||||||
|
_ptr = nullptr;
|
||||||
|
} else{
|
||||||
|
_ptr = a._ptr->Clone();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //PORYGONLANG_EVALVALUEPOINTER_HPP
|
|
@ -64,9 +64,9 @@ TEST_CASE( "Evaluate String", "[integration]" ) {
|
||||||
auto script = Porygon::Script::Create(*sc);
|
auto script = Porygon::Script::Create(*sc);
|
||||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||||
auto result = script->Evaluate();
|
auto result = script->Evaluate();
|
||||||
size_t size = GetEvalValueStringLength(result.get());
|
size_t size = GetEvalValueStringLength(result.Get());
|
||||||
auto dst = new char16_t[size + 1]{'\0'};
|
auto dst = new char16_t[size + 1]{'\0'};
|
||||||
EvaluateEvalValueString(result.get(), dst, size);
|
EvaluateEvalValueString(result.Get(), dst, size);
|
||||||
auto s = u16string(dst);
|
auto s = u16string(dst);
|
||||||
REQUIRE(s == u"foo bar");
|
REQUIRE(s == u"foo bar");
|
||||||
delete[] dst;
|
delete[] dst;
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace Porygon::Evaluation{
|
||||||
class Iterator;
|
class Iterator;
|
||||||
}
|
}
|
||||||
#include "../Iterator/Iterator.hpp"
|
#include "../Iterator/Iterator.hpp"
|
||||||
|
#include "../../Binder/BoundOperators.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace Porygon::Evaluation {
|
namespace Porygon::Evaluation {
|
||||||
|
@ -33,7 +34,7 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
virtual shared_ptr<const EvalValue> Clone() const = 0;
|
virtual EvalValue* Clone() const = 0;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
virtual long EvaluateInteger() const {
|
virtual long EvaluateInteger() const {
|
||||||
|
@ -59,16 +60,16 @@ namespace Porygon::Evaluation {
|
||||||
virtual std::size_t GetHashCode() const = 0;
|
virtual std::size_t GetHashCode() const = 0;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
virtual shared_ptr<const EvalValue> IndexValue(const EvalValue *val) const {
|
virtual const EvalValue* IndexValue(const EvalValue *val) const {
|
||||||
throw EvaluationException("Can't index this EvalValue");
|
throw EvaluationException("Can't index this EvalValue");
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
virtual shared_ptr<const EvalValue> IndexValue(uint32_t hash) const {
|
virtual const EvalValue* IndexValue(uint32_t hash) const {
|
||||||
throw EvaluationException("Can't index this EvalValue");
|
throw EvaluationException("Can't index this EvalValue");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SetIndexValue(const EvalValue *key, const shared_ptr<const EvalValue> &value) const {
|
virtual void SetIndexValue(const EvalValue *key, const EvalValue* value) const {
|
||||||
throw EvaluationException("Can't index this EvalValue");
|
throw EvaluationException("Can't index this EvalValue");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +77,16 @@ namespace Porygon::Evaluation {
|
||||||
virtual Iterator * GetKeyIterator() const{
|
virtual Iterator * GetKeyIterator() const{
|
||||||
throw EvaluationException("Can't iterate over this EvalValue");
|
throw EvaluationException("Can't iterate over this EvalValue");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
virtual EvalValue* BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue* b) const{
|
||||||
|
throw EvaluationException("Binary operations are not implemented for this type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
virtual EvalValue* UnaryOperation(Binder::BoundUnaryOperation operation) const{
|
||||||
|
throw EvaluationException("Unary operations are not implemented for this type.");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BooleanEvalValue : public EvalValue {
|
class BooleanEvalValue : public EvalValue {
|
||||||
|
@ -86,8 +97,8 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> Clone() const final {
|
inline EvalValue* Clone() const final {
|
||||||
return make_shared<BooleanEvalValue>(_value);
|
return new BooleanEvalValue(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
@ -111,6 +122,25 @@ namespace Porygon::Evaluation {
|
||||||
inline std::size_t GetHashCode() const final {
|
inline std::size_t GetHashCode() const final {
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
inline EvalValue* BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue* b) const final{
|
||||||
|
auto bVal = b -> EvaluateBool();
|
||||||
|
switch (operation){
|
||||||
|
case Binder::BoundBinaryOperation::LogicalAnd: return new BooleanEvalValue(_value && bVal);
|
||||||
|
case Binder::BoundBinaryOperation::LogicalOr: return new BooleanEvalValue(_value || bVal);
|
||||||
|
default:
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
EvalValue* UnaryOperation(Binder::BoundUnaryOperation operation) const final{
|
||||||
|
switch (operation){
|
||||||
|
case Binder::BoundUnaryOperation::LogicalNegation: return new BooleanEvalValue(!_value);
|
||||||
|
default: throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@ namespace Porygon::Evaluation{
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> Clone() const final{
|
inline EvalValue* Clone() const final{
|
||||||
return make_shared<NilEvalValue>();
|
return new NilEvalValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
|
|
@ -143,4 +143,70 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalValue *FloatEvalValue::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(_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((long)_value + rightVal);
|
||||||
|
case Binder::BoundBinaryOperation::Subtraction: return new IntegerEvalValue((long)_value - rightVal);
|
||||||
|
case Binder::BoundBinaryOperation::Multiplication: return new IntegerEvalValue((long)_value * rightVal);
|
||||||
|
case Binder::BoundBinaryOperation::Division: return new IntegerEvalValue((long)_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -74,14 +74,25 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> Clone() const final {
|
inline EvalValue* Clone() const final {
|
||||||
return make_shared<IntegerEvalValue>(_value);
|
return new IntegerEvalValue(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline std::size_t GetHashCode() const final {
|
inline std::size_t GetHashCode() const final {
|
||||||
return std::hash<long>{}(_value);
|
return std::hash<long>{}(_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FloatEvalValue : public NumericEvalValue {
|
class FloatEvalValue : public NumericEvalValue {
|
||||||
|
@ -112,14 +123,25 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> Clone() const final {
|
inline EvalValue* Clone() const final {
|
||||||
return make_shared<FloatEvalValue>(_value);
|
return new FloatEvalValue(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline std::size_t GetHashCode() const final {
|
inline std::size_t GetHashCode() const final {
|
||||||
return std::hash<double>{}(_value);
|
return std::hash<double>{}(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
inline 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 FloatEvalValue(-_value);
|
||||||
|
default: throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,3 +4,9 @@
|
||||||
inline Porygon::Evaluation::Iterator *Porygon::Evaluation::NumericalTableEvalValue::GetKeyIterator() const {
|
inline Porygon::Evaluation::Iterator *Porygon::Evaluation::NumericalTableEvalValue::GetKeyIterator() const {
|
||||||
return new NumericalKeyIterator(this);
|
return new NumericalKeyIterator(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Porygon::Evaluation::NumericalTableEvalValue::NumericalTableEvalValue(shared_ptr<vector<EvalValuePointer>> table) :
|
||||||
|
_table(std::move(table)),
|
||||||
|
_hash(rand())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -5,26 +5,23 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "EvalValue.hpp"
|
#include "EvalValue.hpp"
|
||||||
|
#include "../EvalValuePointer.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace Porygon::Evaluation {
|
namespace Porygon::Evaluation {
|
||||||
class NumericalTableEvalValue : public EvalValue {
|
class NumericalTableEvalValue : public EvalValue {
|
||||||
const shared_ptr<vector<shared_ptr<const EvalValue>>> _table;
|
const shared_ptr<vector<EvalValuePointer>> _table;
|
||||||
const size_t _hash;
|
const size_t _hash;
|
||||||
|
|
||||||
explicit NumericalTableEvalValue(shared_ptr<vector<shared_ptr<const EvalValue>>> table, size_t hash)
|
explicit NumericalTableEvalValue(shared_ptr<vector<EvalValuePointer>> table, size_t hash)
|
||||||
: _table(std::move(table)),
|
: _table(std::move(table)),
|
||||||
_hash(hash)
|
_hash(hash)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NumericalTableEvalValue(shared_ptr<vector<shared_ptr<const EvalValue>>> table) :
|
explicit NumericalTableEvalValue(shared_ptr<vector<EvalValuePointer>> table);
|
||||||
_table(std::move(table)),
|
|
||||||
_hash(rand())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline TypeClass GetTypeClass() const final {
|
inline TypeClass GetTypeClass() const final {
|
||||||
|
@ -42,22 +39,22 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> Clone() const final {
|
inline EvalValue* Clone() const final {
|
||||||
return shared_ptr<EvalValue>(new NumericalTableEvalValue(_table, _hash));
|
return new NumericalTableEvalValue(_table, _hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> IndexValue(const EvalValue *val) const final {
|
inline const EvalValue* IndexValue(const EvalValue *val) const final {
|
||||||
const auto index = val->EvaluateInteger() - 1;
|
const auto index = val->EvaluateInteger() - 1;
|
||||||
return this->_table->at(index);
|
return this->_table->at(index).Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> IndexValue(uint32_t hash) const final {
|
inline EvalValue* IndexValue(uint32_t hash) const final {
|
||||||
return this->_table->at(hash - 1);
|
return this->_table->at(hash - 1)-> Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SetIndexValue(const EvalValue *key, const shared_ptr<const EvalValue> &value) const final {
|
inline void SetIndexValue(const EvalValue *key, const EvalValue* value) const final {
|
||||||
auto index = key->EvaluateInteger();
|
auto index = key->EvaluateInteger();
|
||||||
this->_table->at(index - 1) = value;
|
this->_table->at(index - 1) = value;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +63,7 @@ namespace Porygon::Evaluation {
|
||||||
Iterator * GetKeyIterator() const final;
|
Iterator * GetKeyIterator() const final;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<vector<shared_ptr<const EvalValue>>> GetTable() const{
|
inline shared_ptr<vector<EvalValuePointer>> GetTable() const{
|
||||||
return _table;
|
return _table;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,15 +42,15 @@ namespace Porygon::Evaluation {
|
||||||
protected:
|
protected:
|
||||||
const shared_ptr<const GenericFunctionScriptType> _type;
|
const shared_ptr<const GenericFunctionScriptType> _type;
|
||||||
const size_t _hash;
|
const size_t _hash;
|
||||||
vector<shared_ptr<GenericFunctionOption>>* _options;
|
shared_ptr<vector<shared_ptr<GenericFunctionOption>>> _options;
|
||||||
|
GenericFunctionEvalValue(shared_ptr<const GenericFunctionScriptType> type, size_t hash,
|
||||||
|
shared_ptr<vector<shared_ptr<GenericFunctionOption>>> options)
|
||||||
|
:_type(std::move(type)), _hash(hash), _options(std::move(options))
|
||||||
|
{}
|
||||||
public:
|
public:
|
||||||
GenericFunctionEvalValue(shared_ptr<const GenericFunctionScriptType> type, size_t hash)
|
GenericFunctionEvalValue(shared_ptr<const GenericFunctionScriptType> type, size_t hash)
|
||||||
: _type(move(type)),
|
: _type(move(type)),
|
||||||
_hash(hash), _options(new vector<shared_ptr<GenericFunctionOption>>()){
|
_hash(hash), _options(make_shared<vector<shared_ptr<GenericFunctionOption>>>()){
|
||||||
}
|
|
||||||
|
|
||||||
~GenericFunctionEvalValue() final{
|
|
||||||
delete _options;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericFunctionEvalValue(const GenericFunctionEvalValue& _) = delete;
|
GenericFunctionEvalValue(const GenericFunctionEvalValue& _) = delete;
|
||||||
|
@ -58,19 +58,16 @@ namespace Porygon::Evaluation {
|
||||||
GenericFunctionEvalValue& operator =(GenericFunctionEvalValue v) = delete;
|
GenericFunctionEvalValue& operator =(GenericFunctionEvalValue v) = delete;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
shared_ptr<const EvalValue> Clone() const final {
|
EvalValue* Clone() const final {
|
||||||
auto t = make_shared<GenericFunctionEvalValue>(_type, _hash);
|
return new GenericFunctionEvalValue(_type, _hash, _options);
|
||||||
for (const auto& o: *_options){
|
|
||||||
t->_options->push_back(o);
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RegisterOption(GenericFunctionOption* option) const{
|
inline void RegisterOption(GenericFunctionOption* option) const{
|
||||||
_options->push_back(shared_ptr<GenericFunctionOption>(option));
|
_options->push_back(shared_ptr<GenericFunctionOption>(option));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<const ScriptType> GetType() const {
|
[[nodiscard]]
|
||||||
|
inline std::shared_ptr<const GenericFunctionScriptType> GetType() const {
|
||||||
return _type;
|
return _type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,20 +34,31 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> Clone() const final {
|
inline EvalValue* Clone() const final {
|
||||||
return make_shared<StringEvalValue>(_value);
|
return new StringEvalValue(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> IndexValue(const EvalValue *val) const final {
|
EvalValue* IndexValue(const EvalValue *val) const final {
|
||||||
// Porygon is 1-indexed, so we convert to that.
|
// Porygon is 1-indexed, so we convert to that.
|
||||||
auto l = val->EvaluateInteger() - 1;
|
auto l = val->EvaluateInteger() - 1;
|
||||||
return make_shared<const StringEvalValue>(u16string(1, _value[l]));
|
return new StringEvalValue(u16string(1, _value[l]));
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline std::size_t GetHashCode() const final {
|
inline std::size_t GetHashCode() const final {
|
||||||
return _hash;
|
return _hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
inline EvalValue* BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue* b) const final{
|
||||||
|
if (operation != Binder::BoundBinaryOperation::Concatenation){
|
||||||
|
throw EvaluationException("Binary operation not supported for strings.");
|
||||||
|
}
|
||||||
|
std::basic_ostringstream<char16_t> stringStream;
|
||||||
|
stringStream << _value;
|
||||||
|
stringStream << b->EvaluateString();
|
||||||
|
return new StringEvalValue(stringStream.str());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,22 +5,23 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "EvalValue.hpp"
|
#include "EvalValue.hpp"
|
||||||
#include "../../Utilities/Random.hpp"
|
#include "../../Utilities/Random.hpp"
|
||||||
|
#include "../EvalValuePointer.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace Porygon::Evaluation {
|
namespace Porygon::Evaluation {
|
||||||
class TableEvalValue : public EvalValue {
|
class TableEvalValue : public EvalValue {
|
||||||
const shared_ptr<map<Utilities::HashedString, shared_ptr<const EvalValue>>> _table;
|
const shared_ptr<map<Utilities::HashedString, EvalValuePointer>> _table;
|
||||||
const size_t _hash;
|
const size_t _hash;
|
||||||
|
|
||||||
explicit TableEvalValue(shared_ptr<map<Utilities::HashedString, shared_ptr<const EvalValue>>> table, size_t hash)
|
explicit TableEvalValue(shared_ptr<map<Utilities::HashedString, EvalValuePointer>> table, size_t hash)
|
||||||
: _table(std::move(table)),
|
: _table(std::move(table)),
|
||||||
_hash(hash)
|
_hash(hash)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TableEvalValue(shared_ptr<map<Utilities::HashedString, shared_ptr<const EvalValue>>> table) :
|
explicit TableEvalValue(shared_ptr<map<Utilities::HashedString, EvalValuePointer>> table) :
|
||||||
_table(std::move(table)),
|
_table(std::move(table)),
|
||||||
_hash(Utilities::Random::Get())
|
_hash(Utilities::Random::Get())
|
||||||
{
|
{
|
||||||
|
@ -42,41 +43,41 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> Clone() const final {
|
inline EvalValue* Clone() const final {
|
||||||
return shared_ptr<EvalValue>(new TableEvalValue(_table, _hash));
|
return new TableEvalValue(_table, _hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> IndexValue(const EvalValue *val) const final {
|
inline EvalValue* IndexValue(const EvalValue *val) const final {
|
||||||
const auto stringKey = val->EvaluateString();
|
const auto stringKey = val->EvaluateString();
|
||||||
return this->_table->at(Utilities::HashedString::CreateLookup(stringKey));
|
return this->_table->at(Utilities::HashedString::CreateLookup(stringKey))->Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> IndexValue(uint32_t hash) const final {
|
inline EvalValue* IndexValue(uint32_t hash) const final {
|
||||||
return this->_table->at(Utilities::HashedString::CreateLookup(hash));
|
return this->_table->at(Utilities::HashedString::CreateLookup(hash))->Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> IndexValue(const char *val) const {
|
inline const EvalValue* IndexValue(const char *val) const {
|
||||||
auto hash = Utilities::HashedString::ConstHash(val);
|
auto hash = Utilities::HashedString::ConstHash(val);
|
||||||
return this->_table->at(Utilities::HashedString::CreateLookup(hash));
|
return this->_table->at(Utilities::HashedString::CreateLookup(hash)).Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SetIndexValue(const EvalValue *key, const shared_ptr<const EvalValue> &value) const final {
|
inline void SetIndexValue(const EvalValue *key, const EvalValue* value) const final {
|
||||||
auto hash = key->GetHashCode();
|
auto hash = key->GetHashCode();
|
||||||
this->_table->at(Utilities::HashedString::CreateLookup(hash)) = value;
|
this->_table->at(Utilities::HashedString::CreateLookup(hash)).ClearAssign(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
Iterator * GetKeyIterator() const final;
|
Iterator * GetKeyIterator() const final;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline _Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<const EvalValue>>> GetTableIterator() const{
|
inline _Rb_tree_const_iterator<pair<const Utilities::HashedString, EvalValuePointer>> GetTableIterator() const{
|
||||||
return _table->cbegin();
|
return _table->cbegin();
|
||||||
};
|
};
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline _Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<const EvalValue>>> GetTableIteratorEnd() const{
|
inline _Rb_tree_const_iterator<pair<const Utilities::HashedString, EvalValuePointer>> GetTableIteratorEnd() const{
|
||||||
return _table->cend();
|
return _table->cend();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,38 +4,39 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace Porygon::Evaluation {
|
namespace Porygon::Evaluation {
|
||||||
EvaluationScope::EvaluationScope(map<Utilities::HashedString, shared_ptr<const EvalValue>> *scriptVariables)
|
EvaluationScope::EvaluationScope(map<Utilities::HashedString, EvalValuePointer> *scriptVariables)
|
||||||
: _scriptScope(scriptVariables),
|
: _scriptScope(scriptVariables),
|
||||||
_localScope(map<uint64_t, shared_ptr<const EvalValue>>()) {
|
_localScope(map<uint64_t, EvalValuePointer>()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvaluationScope::CreateVariable(const BoundVariableKey *key, const shared_ptr<const EvalValue>& value) {
|
void EvaluationScope::CreateVariable(const BoundVariableKey *key, EvalValuePointer value) {
|
||||||
if (key->GetScopeId() == 0) {
|
if (key->GetScopeId() == 0) {
|
||||||
_scriptScope->at(*key->GetIdentifier()) = value;
|
_scriptScope->at(*key->GetIdentifier()).ClearAssign(value.Take());
|
||||||
} else {
|
} else {
|
||||||
auto insert = _localScope.insert({key->GetHash(), value});
|
auto val = value.Clone();
|
||||||
|
auto insert = _localScope.insert({key->GetHash(), val});
|
||||||
if (!insert.second) {
|
if (!insert.second) {
|
||||||
_localScope[key->GetHash()] = value;
|
_localScope[key->GetHash()].ClearAssign(value.Take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvaluationScope::SetVariable(const BoundVariableKey *key, const shared_ptr<const EvalValue> &value) {
|
void EvaluationScope::SetVariable(const BoundVariableKey *key, EvalValuePointer value) {
|
||||||
if (key->GetScopeId() == 0) {
|
if (key->GetScopeId() == 0) {
|
||||||
_scriptScope->at(*key->GetIdentifier()) = value;
|
_scriptScope->at(*key->GetIdentifier()).ClearAssign(value.Take());
|
||||||
} else {
|
} else {
|
||||||
_localScope[key->GetHash()] = value;
|
_localScope[key->GetHash()].ClearAssign(value.Take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> EvaluationScope::GetVariable(const BoundVariableKey *key) {
|
EvalValuePointer EvaluationScope::GetVariable(const BoundVariableKey *key) {
|
||||||
auto scopeId = key -> GetScopeId();
|
auto scopeId = key -> GetScopeId();
|
||||||
if (scopeId== 0) {
|
if (scopeId== 0) {
|
||||||
return _scriptScope->at(*key->GetIdentifier());
|
return _scriptScope->at(*key->GetIdentifier())->Clone();
|
||||||
} else if(scopeId == -2){
|
} else if(scopeId == -2){
|
||||||
return StandardLibraries::StaticScope::GetVariable(*key->GetIdentifier());
|
return StandardLibraries::StaticScope::GetVariable(*key->GetIdentifier()).Clone();
|
||||||
} else {
|
} else {
|
||||||
return _localScope[key->GetHash()];
|
return _localScope[key->GetHash()]->Clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,22 +5,26 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../EvalValues/EvalValue.hpp"
|
#include "../EvalValues/EvalValue.hpp"
|
||||||
|
#include "../EvalValuePointer.hpp"
|
||||||
|
|
||||||
using namespace Porygon::Binder;
|
using namespace Porygon::Binder;
|
||||||
|
|
||||||
namespace Porygon::Evaluation {
|
namespace Porygon::Evaluation {
|
||||||
class EvaluationScope {
|
class EvaluationScope {
|
||||||
map<Utilities::HashedString, shared_ptr<const EvalValue>> *_scriptScope;
|
map<Utilities::HashedString, EvalValuePointer> *_scriptScope;
|
||||||
map<uint64_t, shared_ptr<const EvalValue>> _localScope;
|
map<uint64_t, EvalValuePointer> _localScope;
|
||||||
public:
|
public:
|
||||||
explicit EvaluationScope(map<Utilities::HashedString, shared_ptr<const EvalValue>> *scriptVariables);
|
explicit EvaluationScope(map<Utilities::HashedString, EvalValuePointer> *scriptVariables);
|
||||||
|
|
||||||
~EvaluationScope() = default;
|
~EvaluationScope(){
|
||||||
|
_localScope.clear();
|
||||||
|
};
|
||||||
|
|
||||||
void CreateVariable(const BoundVariableKey *key, const shared_ptr<const EvalValue>&value);
|
void CreateVariable(const BoundVariableKey *key, EvalValuePointer value);
|
||||||
|
|
||||||
void SetVariable(const BoundVariableKey *key, const shared_ptr<const EvalValue> &value);
|
void SetVariable(const BoundVariableKey *key, EvalValuePointer value);
|
||||||
|
|
||||||
shared_ptr<const EvalValue> GetVariable(const BoundVariableKey *key);
|
EvalValuePointer GetVariable(const BoundVariableKey *key);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,15 +15,18 @@ using namespace std;
|
||||||
using namespace Porygon::Binder;
|
using namespace Porygon::Binder;
|
||||||
|
|
||||||
namespace Porygon::Evaluation {
|
namespace Porygon::Evaluation {
|
||||||
shared_ptr<const EvalValue> Evaluator::Evaluate(const BoundScriptStatement *statement) {
|
const EvalValue* Evaluator::Evaluate(const BoundScriptStatement *statement) {
|
||||||
this->_evaluationScope = make_shared<EvaluationScope>(this->_scriptVariables);
|
this->_evaluationScope = make_shared<EvaluationScope>(this->_scriptVariables);
|
||||||
auto statements = statement->GetStatements();
|
auto statements = statement->GetStatements();
|
||||||
if (statements -> size() == 1 && statements->at(0)->GetKind() == BoundStatementKind::Expression){
|
if (statements -> size() == 1 && statements->at(0)->GetKind() == BoundStatementKind::Expression){
|
||||||
auto expStatement = (BoundExpressionStatement*) statements -> at(0);
|
auto expStatement = (BoundExpressionStatement*) statements -> at(0);
|
||||||
return this -> EvaluateExpression(expStatement -> GetExpression());
|
return this -> EvaluateExpression(expStatement -> GetExpression()).Clone();
|
||||||
}
|
}
|
||||||
EvaluateBlockStatement(statement);
|
EvaluateBlockStatement(statement);
|
||||||
return this->_returnValue;
|
if (this->_returnValue.Get() == nullptr){
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return this->_returnValue.Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Evaluator::EvaluateStatement(const BoundStatement *statement) {
|
void Evaluator::EvaluateStatement(const BoundStatement *statement) {
|
||||||
|
@ -78,9 +81,9 @@ namespace Porygon::Evaluation {
|
||||||
auto value = this->EvaluateExpression(statement->GetExpression());
|
auto value = this->EvaluateExpression(statement->GetExpression());
|
||||||
auto key = statement->GetKey();
|
auto key = statement->GetKey();
|
||||||
if (key->IsCreation()) {
|
if (key->IsCreation()) {
|
||||||
this->_evaluationScope->CreateVariable(key, value);
|
this->_evaluationScope->CreateVariable(key, value.Clone());
|
||||||
} else {
|
} else {
|
||||||
this->_evaluationScope->SetVariable(key, value);
|
this->_evaluationScope->SetVariable(key, value.Clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +93,7 @@ namespace Porygon::Evaluation {
|
||||||
auto index = ((BoundIndexExpression *) indexExpression);
|
auto index = ((BoundIndexExpression *) indexExpression);
|
||||||
auto table = this->EvaluateExpression(index->GetIndexableExpression());
|
auto table = this->EvaluateExpression(index->GetIndexableExpression());
|
||||||
auto key = this->EvaluateExpression(index->GetIndexExpression());
|
auto key = this->EvaluateExpression(index->GetIndexExpression());
|
||||||
table->SetIndexValue(key.get(), value);
|
table->SetIndexValue(key.Get(), value.Take());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Evaluator::EvaluateFunctionDeclarationStatement(const BoundFunctionDeclarationStatement *statement) {
|
void Evaluator::EvaluateFunctionDeclarationStatement(const BoundFunctionDeclarationStatement *statement) {
|
||||||
|
@ -100,13 +103,14 @@ namespace Porygon::Evaluation {
|
||||||
auto option = new Evaluation::EvaluationScriptFunctionOption(block, this->_evaluationScope);
|
auto option = new Evaluation::EvaluationScriptFunctionOption(block, this->_evaluationScope);
|
||||||
|
|
||||||
if (key->IsCreation()) {
|
if (key->IsCreation()) {
|
||||||
auto value = make_shared<GenericFunctionEvalValue>(type, Utilities::Random::Get());
|
auto p = new GenericFunctionEvalValue(type, Utilities::Random::Get());
|
||||||
value->RegisterOption(option);
|
p->RegisterOption(option);
|
||||||
|
auto value = EvalValuePointer(p);
|
||||||
this->_evaluationScope->CreateVariable(key, value);
|
this->_evaluationScope->CreateVariable(key, value);
|
||||||
} else {
|
} else {
|
||||||
auto var = dynamic_pointer_cast<const GenericFunctionEvalValue>(this -> _evaluationScope ->GetVariable(key));
|
auto var = (GenericFunctionEvalValue*)this -> _evaluationScope ->GetVariable(key).Get();
|
||||||
var->RegisterOption(option);
|
var->RegisterOption(option);
|
||||||
this->_evaluationScope->SetVariable(key, var);
|
//this->_evaluationScope->SetVariable(key, var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,17 +118,17 @@ namespace Porygon::Evaluation {
|
||||||
auto expression = statement->GetExpression();
|
auto expression = statement->GetExpression();
|
||||||
if (expression == nullptr) {
|
if (expression == nullptr) {
|
||||||
this->_hasReturned = true;
|
this->_hasReturned = true;
|
||||||
this -> _returnValue = nullptr;
|
this -> _returnValue.ClearAssign(nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto value = this->EvaluateExpression(expression);
|
auto value = this->EvaluateExpression(expression).Take();
|
||||||
this->_hasReturned = true;
|
this->_hasReturned = true;
|
||||||
this->_returnValue = value;
|
this->_returnValue.ClearAssign(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Evaluator::EvaluateConditionalStatement(const BoundConditionalStatement *statement) {
|
void Evaluator::EvaluateConditionalStatement(const BoundConditionalStatement *statement) {
|
||||||
auto condition = statement->GetCondition();
|
auto condition = statement->GetCondition();
|
||||||
if (EvaluateBoolExpression(condition)->EvaluateBool()) {
|
if (EvaluateExpression(condition)->EvaluateBool()) {
|
||||||
this->EvaluateStatement(statement->GetBlock());
|
this->EvaluateStatement(statement->GetBlock());
|
||||||
} else {
|
} else {
|
||||||
auto elseStatement = statement->GetElseStatement();
|
auto elseStatement = statement->GetElseStatement();
|
||||||
|
@ -135,12 +139,12 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Evaluator::EvaluateNumericalForStatement(const BoundNumericalForStatement *statement) {
|
void Evaluator::EvaluateNumericalForStatement(const BoundNumericalForStatement *statement) {
|
||||||
long start = this->EvaluateIntegerExpression(statement -> GetStart()) -> EvaluateInteger();
|
long start = this->EvaluateExpression(statement -> GetStart()) -> EvaluateInteger();
|
||||||
long end = this->EvaluateIntegerExpression(statement -> GetEnd()) -> EvaluateInteger();
|
long end = this->EvaluateExpression(statement -> GetEnd()) -> EvaluateInteger();
|
||||||
long step = 1;
|
long step = 1;
|
||||||
auto stepExp = statement -> GetStep();
|
auto stepExp = statement -> GetStep();
|
||||||
if (stepExp != nullptr){
|
if (stepExp != nullptr){
|
||||||
step = this -> EvaluateIntegerExpression(stepExp) -> EvaluateInteger();
|
step = this -> EvaluateExpression(stepExp) -> EvaluateInteger();
|
||||||
}
|
}
|
||||||
auto identifier = statement -> GetIdentifier();
|
auto identifier = statement -> GetIdentifier();
|
||||||
this -> _evaluationScope -> CreateVariable(identifier, nullptr);
|
this -> _evaluationScope -> CreateVariable(identifier, nullptr);
|
||||||
|
@ -148,7 +152,7 @@ namespace Porygon::Evaluation {
|
||||||
auto statements = *block -> GetStatements();
|
auto statements = *block -> GetStatements();
|
||||||
if (step >= 0){
|
if (step >= 0){
|
||||||
for (long i = start; i <= end; i += step){
|
for (long i = start; i <= end; i += step){
|
||||||
this -> _evaluationScope -> SetVariable(identifier, make_shared<IntegerEvalValue>(i));
|
this -> _evaluationScope -> SetVariable(identifier, new IntegerEvalValue(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)
|
||||||
|
@ -159,7 +163,7 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
} else{
|
} else{
|
||||||
for (long i = start; i >= end; i += step){
|
for (long i = start; i >= end; i += step){
|
||||||
this -> _evaluationScope -> SetVariable(identifier, make_shared<IntegerEvalValue>(i));
|
this -> _evaluationScope -> SetVariable(identifier, new IntegerEvalValue(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)
|
||||||
|
@ -184,10 +188,10 @@ namespace Porygon::Evaluation {
|
||||||
auto block = (BoundBlockStatement*)statement -> GetBlock();
|
auto block = (BoundBlockStatement*)statement -> GetBlock();
|
||||||
auto statements = *block -> GetStatements();
|
auto statements = *block -> GetStatements();
|
||||||
while (iterator->MoveNext()){
|
while (iterator->MoveNext()){
|
||||||
auto currentKey = iterator->GetCurrent();
|
auto currentKey = EvalValuePointer(iterator->GetCurrent());
|
||||||
this -> _evaluationScope -> SetVariable(keyVariable, currentKey);
|
this -> _evaluationScope -> SetVariable(keyVariable, currentKey);
|
||||||
if (valueVariable != nullptr){
|
if (valueVariable != nullptr){
|
||||||
auto currentValue = iteratorVal -> IndexValue(currentKey.get());
|
auto currentValue = EvalValuePointer(iteratorVal -> IndexValue(currentKey.Get()));
|
||||||
this -> _evaluationScope -> SetVariable(valueVariable, currentValue);
|
this -> _evaluationScope -> SetVariable(valueVariable, currentValue);
|
||||||
}
|
}
|
||||||
for (auto s: statements) {
|
for (auto s: statements) {
|
||||||
|
@ -206,7 +210,7 @@ namespace Porygon::Evaluation {
|
||||||
auto condition = statement -> GetCondition();
|
auto condition = statement -> GetCondition();
|
||||||
auto block = (BoundBlockStatement*)statement -> GetBlock();
|
auto block = (BoundBlockStatement*)statement -> GetBlock();
|
||||||
auto statements = *block -> GetStatements();
|
auto statements = *block -> GetStatements();
|
||||||
while (this->EvaluateBoolExpression(condition)->EvaluateBool()){
|
while (this->EvaluateExpression(condition)->EvaluateBool()){
|
||||||
for (auto s: statements) {
|
for (auto s: statements) {
|
||||||
this->EvaluateStatement(s);
|
this->EvaluateStatement(s);
|
||||||
if (this->_hasReturned || this -> _hasBroken)
|
if (this->_hasReturned || this -> _hasBroken)
|
||||||
|
@ -222,161 +226,75 @@ namespace Porygon::Evaluation {
|
||||||
// Expressions //
|
// Expressions //
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::EvaluateExpression(const BoundExpression *expression) {
|
EvalValuePointer Evaluator::EvaluateExpression(const BoundExpression *expression) {
|
||||||
auto type = expression->GetType();
|
|
||||||
switch (type->GetClass()) {
|
|
||||||
case TypeClass::Number:
|
|
||||||
return this->EvaluateIntegerExpression(expression);
|
|
||||||
case TypeClass::Bool:
|
|
||||||
return this->EvaluateBoolExpression(expression);
|
|
||||||
case TypeClass::String:
|
|
||||||
return this->EvaluateStringExpression(expression);
|
|
||||||
case TypeClass::Function:
|
|
||||||
return this->EvaluateFunctionExpression(expression);
|
|
||||||
case TypeClass::Nil:
|
|
||||||
return this->EvaluateNilExpression(expression);
|
|
||||||
case TypeClass::Table:
|
|
||||||
return this->EvaluateTableExpression(expression);
|
|
||||||
case TypeClass::UserData:
|
|
||||||
return this->EvaluateUserDataExpression(expression);
|
|
||||||
default:
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::GetVariable(const BoundVariableExpression *expression) {
|
|
||||||
auto variable = this->_evaluationScope->GetVariable(expression->GetKey());
|
|
||||||
if (variable == nullptr) {
|
|
||||||
throw EvaluationException("Variable not found");
|
|
||||||
}
|
|
||||||
return variable->Clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<const NumericEvalValue> Evaluator::EvaluateIntegerExpression(const BoundExpression *expression) {
|
|
||||||
switch (expression->GetKind()){
|
switch (expression->GetKind()){
|
||||||
|
|
||||||
|
case BoundExpressionKind::Bad: throw;
|
||||||
case BoundExpressionKind::LiteralInteger:
|
case BoundExpressionKind::LiteralInteger:
|
||||||
return make_shared<IntegerEvalValue>(((BoundLiteralIntegerExpression *) expression)->GetValue());
|
return new IntegerEvalValue(((BoundLiteralIntegerExpression *) expression)->GetValue());
|
||||||
case BoundExpressionKind::LiteralFloat:
|
case BoundExpressionKind::LiteralFloat:
|
||||||
return make_shared<FloatEvalValue>(((BoundLiteralFloatExpression *) expression)->GetValue());
|
return new FloatEvalValue(((BoundLiteralFloatExpression *) expression)->GetValue());
|
||||||
case BoundExpressionKind::Unary:
|
|
||||||
return this->EvaluateIntegerUnary((BoundUnaryExpression *) expression);
|
|
||||||
case BoundExpressionKind::Binary:
|
|
||||||
return this->EvaluateIntegerBinary((BoundBinaryExpression *) expression);
|
|
||||||
case BoundExpressionKind::Variable:
|
|
||||||
return dynamic_pointer_cast<const NumericEvalValue>(
|
|
||||||
this->GetVariable((BoundVariableExpression *) expression));
|
|
||||||
case BoundExpressionKind::FunctionCall:
|
|
||||||
return dynamic_pointer_cast<const NumericEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
|
||||||
case BoundExpressionKind::Index:
|
|
||||||
return dynamic_pointer_cast<const NumericEvalValue>(this->EvaluateIndexExpression(expression));
|
|
||||||
case BoundExpressionKind::PeriodIndex:
|
|
||||||
return dynamic_pointer_cast<const NumericEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<const BooleanEvalValue> Evaluator::EvaluateBoolExpression(const BoundExpression *expression) {
|
|
||||||
switch (expression->GetKind()) {
|
|
||||||
case BoundExpressionKind::LiteralBool:
|
|
||||||
return make_shared<BooleanEvalValue>(((BoundLiteralBoolExpression *) expression)->GetValue());
|
|
||||||
case BoundExpressionKind::Unary:
|
|
||||||
return this->EvaluateBooleanUnary((BoundUnaryExpression *) expression);
|
|
||||||
case BoundExpressionKind::Binary:
|
|
||||||
return this->EvaluateBooleanBinary((BoundBinaryExpression *) expression);
|
|
||||||
case BoundExpressionKind::Variable:
|
|
||||||
return dynamic_pointer_cast<const BooleanEvalValue>(
|
|
||||||
this->GetVariable((BoundVariableExpression *) expression));
|
|
||||||
case BoundExpressionKind::FunctionCall:
|
|
||||||
return dynamic_pointer_cast<const BooleanEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
|
||||||
case BoundExpressionKind::Index:
|
|
||||||
return dynamic_pointer_cast<const BooleanEvalValue>(this->EvaluateIndexExpression(expression));
|
|
||||||
case BoundExpressionKind::PeriodIndex:
|
|
||||||
return dynamic_pointer_cast<const BooleanEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<const StringEvalValue> Evaluator::EvaluateStringExpression(const BoundExpression *expression) {
|
|
||||||
switch (expression->GetKind()) {
|
|
||||||
case BoundExpressionKind::LiteralString:
|
case BoundExpressionKind::LiteralString:
|
||||||
return make_shared<StringEvalValue>(*((BoundLiteralStringExpression *) expression)->GetValue());
|
return new StringEvalValue(*((BoundLiteralStringExpression *) expression)->GetValue());
|
||||||
case BoundExpressionKind::Binary:
|
case BoundExpressionKind::LiteralBool:
|
||||||
return this->EvaluateStringBinary((BoundBinaryExpression *) expression);
|
return new BooleanEvalValue(((BoundLiteralBoolExpression *) expression)->GetValue());
|
||||||
case BoundExpressionKind::Variable:
|
|
||||||
return dynamic_pointer_cast<const StringEvalValue>(this->GetVariable((BoundVariableExpression *) expression));
|
|
||||||
case BoundExpressionKind::FunctionCall:
|
|
||||||
return dynamic_pointer_cast<const StringEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
|
||||||
case BoundExpressionKind::Index:
|
|
||||||
return dynamic_pointer_cast<const StringEvalValue>(this->EvaluateIndexExpression(expression));
|
|
||||||
case BoundExpressionKind::PeriodIndex:
|
|
||||||
return dynamic_pointer_cast<const StringEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::EvaluateFunctionExpression(const BoundExpression *expression) {
|
|
||||||
switch (expression->GetKind()) {
|
|
||||||
case BoundExpressionKind::Variable:
|
case BoundExpressionKind::Variable:
|
||||||
return this -> GetVariable((BoundVariableExpression*)expression);
|
return this -> GetVariable((BoundVariableExpression*)expression);
|
||||||
|
case BoundExpressionKind::Unary:
|
||||||
|
return this->EvaluateUnary((BoundUnaryExpression *) expression);
|
||||||
|
case BoundExpressionKind::Binary:
|
||||||
|
return this->EvaluateBinary((BoundBinaryExpression *) expression);
|
||||||
|
case BoundExpressionKind::FunctionCall:
|
||||||
|
return this->EvaluateFunctionCallExpression(expression);
|
||||||
case BoundExpressionKind::Index:
|
case BoundExpressionKind::Index:
|
||||||
return this->EvaluateIndexExpression(expression);
|
return this->EvaluateIndexExpression(expression).Take();
|
||||||
case BoundExpressionKind::PeriodIndex:
|
case BoundExpressionKind::PeriodIndex:
|
||||||
return this->EvaluatePeriodIndexExpression(expression);
|
return this->EvaluatePeriodIndexExpression(expression);
|
||||||
default:
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::EvaluateNilExpression(const BoundExpression *expression) {
|
|
||||||
switch (expression->GetKind()) {
|
|
||||||
case BoundExpressionKind::FunctionCall:
|
|
||||||
return this->EvaluateFunctionCallExpression(expression);
|
|
||||||
default:
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::EvaluateTableExpression(const BoundExpression *expression) {
|
|
||||||
switch (expression->GetKind()) {
|
|
||||||
case BoundExpressionKind::FunctionCall:
|
|
||||||
return this->EvaluateFunctionCallExpression(expression);
|
|
||||||
case BoundExpressionKind::Variable:
|
|
||||||
return this->GetVariable((BoundVariableExpression *) expression);
|
|
||||||
case BoundExpressionKind::Index:
|
|
||||||
return this->EvaluateIndexExpression(expression);
|
|
||||||
case BoundExpressionKind::NumericalTable:
|
case BoundExpressionKind::NumericalTable:
|
||||||
return this->EvaluateNumericTableExpression(expression);
|
return this->EvaluateNumericTableExpression(expression);
|
||||||
case BoundExpressionKind::Table:
|
case BoundExpressionKind::Table:
|
||||||
return this->EvaluateComplexTableExpression(expression);
|
return this->EvaluateComplexTableExpression(expression);
|
||||||
case BoundExpressionKind::PeriodIndex:
|
|
||||||
return this->EvaluatePeriodIndexExpression(expression);
|
|
||||||
default:
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EvalValuePointer Evaluator::EvaluateBinary(const BoundBinaryExpression *expression){
|
||||||
|
auto leftValue = this -> EvaluateExpression(expression->GetLeft());
|
||||||
|
auto rightValue = this -> EvaluateExpression(expression->GetRight());
|
||||||
|
auto operation = expression->GetOperation();
|
||||||
|
if (operation == BoundBinaryOperation::Equality){
|
||||||
|
return new BooleanEvalValue(leftValue == rightValue);
|
||||||
|
} else if (operation == BoundBinaryOperation::Inequality){
|
||||||
|
return new BooleanEvalValue(leftValue != rightValue);
|
||||||
|
}
|
||||||
|
return leftValue->BinaryOperation(operation, rightValue.Get());
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::EvaluateFunctionCallExpression(const BoundExpression *expression) {
|
EvalValuePointer Evaluator::EvaluateUnary(const BoundUnaryExpression *expression) {
|
||||||
|
auto exp = expression->GetOperand();
|
||||||
|
auto val = EvaluateExpression(exp);
|
||||||
|
return val->UnaryOperation(expression->GetOperation());
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalValuePointer Evaluator::GetVariable(const BoundVariableExpression *expression) {
|
||||||
|
auto variable = this->_evaluationScope->GetVariable(expression->GetKey());
|
||||||
|
if (variable.Get() == nullptr) {
|
||||||
|
throw EvaluationException("Variable not found");
|
||||||
|
}
|
||||||
|
return variable;
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalValuePointer Evaluator::EvaluateFunctionCallExpression(const BoundExpression *expression) {
|
||||||
auto functionCall = (BoundFunctionCallExpression *) expression;
|
auto functionCall = (BoundFunctionCallExpression *) expression;
|
||||||
auto function = dynamic_pointer_cast<const GenericFunctionEvalValue>(
|
auto function = (GenericFunctionEvalValue*)this->EvaluateExpression(functionCall->GetFunctionExpression()).Clone();
|
||||||
this->EvaluateExpression(functionCall->GetFunctionExpression()));
|
|
||||||
|
|
||||||
auto boundParameters = functionCall->GetParameters();
|
auto boundParameters = functionCall->GetParameters();
|
||||||
auto parameters = vector<shared_ptr<const EvalValue>>(boundParameters->size());
|
auto parameters = vector<EvalValuePointer>(boundParameters->size());
|
||||||
for (size_t i = 0; i < boundParameters->size(); i++) {
|
for (size_t i = 0; i < boundParameters->size(); i++) {
|
||||||
parameters[i] = this->EvaluateExpression(boundParameters->at(i));
|
parameters[i] = this->EvaluateExpression(boundParameters->at(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto type = std::dynamic_pointer_cast<const GenericFunctionScriptType>(function->GetType());
|
auto type = std::dynamic_pointer_cast<const GenericFunctionScriptType>(function->GetType());
|
||||||
auto func = dynamic_pointer_cast<const GenericFunctionEvalValue>(function);
|
auto func = function;
|
||||||
auto option = functionCall ->GetFunctionOption();
|
auto option = functionCall ->GetFunctionOption();
|
||||||
auto opt = func->GetOption(option->GetOptionId());
|
auto opt = func->GetOption(option->GetOptionId());
|
||||||
if (option -> IsScriptFunction()){
|
if (option -> IsScriptFunction()){
|
||||||
|
@ -390,28 +308,30 @@ namespace Porygon::Evaluation {
|
||||||
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++) {
|
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++) {
|
||||||
auto parameter = parameters[i];
|
auto parameter = parameters[i];
|
||||||
auto key = parameterKeys.at(i);
|
auto key = parameterKeys.at(i);
|
||||||
this->_evaluationScope->CreateVariable(key.get(), parameter->Clone());
|
this->_evaluationScope->CreateVariable(key.get(), parameter.Clone());
|
||||||
}
|
}
|
||||||
this->EvaluateBlockStatement(scriptOption->GetInnerBlock().get());
|
this->EvaluateBlockStatement(scriptOption->GetInnerBlock().get());
|
||||||
this->_evaluationScope = originalScope;
|
this->_evaluationScope = originalScope;
|
||||||
|
|
||||||
this->_hasReturned = false;
|
this->_hasReturned = false;
|
||||||
auto r = this->_returnValue;
|
auto r = this->_returnValue;
|
||||||
this->_returnValue = nullptr;
|
this->_returnValue.ClearAssign(nullptr);
|
||||||
|
delete function;
|
||||||
return r;
|
return r;
|
||||||
} else{
|
} else{
|
||||||
auto scriptOption = dynamic_pointer_cast<const UserData::UserDataFunction>(opt);
|
auto scriptOption = dynamic_pointer_cast<const UserData::UserDataFunction>(opt);
|
||||||
const EvalValue* arr[parameters.size()];
|
const EvalValue* arr[parameters.size()];
|
||||||
for (size_t i = 0; i < parameters.size(); i++){
|
for (size_t i = 0; i < parameters.size(); i++){
|
||||||
arr[i] = parameters[i].get();
|
arr[i] = parameters[i].Get();
|
||||||
}
|
}
|
||||||
return shared_ptr<const EvalValue>(scriptOption -> Call(arr, parameters.size()));
|
delete function;
|
||||||
|
return scriptOption -> Call(arr, parameters.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::EvaluateFunction(const GenericFunctionEvalValue *function,
|
const EvalValue* Evaluator::EvaluateFunction(const GenericFunctionEvalValue *function,
|
||||||
const vector<EvalValue *> ¶meters) {
|
const vector<EvalValue *> ¶meters) {
|
||||||
auto type = std::dynamic_pointer_cast<const GenericFunctionScriptType>(function->GetType());
|
auto type = function->GetType();
|
||||||
auto option = dynamic_cast<const ScriptFunctionOption*>(type->GetFirstOption());
|
auto option = dynamic_cast<const ScriptFunctionOption*>(type->GetFirstOption());
|
||||||
|
|
||||||
auto parameterTypes = option->GetParameterTypes();
|
auto parameterTypes = option->GetParameterTypes();
|
||||||
|
@ -429,42 +349,43 @@ namespace Porygon::Evaluation {
|
||||||
this->EvaluateBlockStatement(scriptOption->GetInnerBlock().get());
|
this->EvaluateBlockStatement(scriptOption->GetInnerBlock().get());
|
||||||
this->_evaluationScope = originalScope;
|
this->_evaluationScope = originalScope;
|
||||||
this->_hasReturned = false;
|
this->_hasReturned = false;
|
||||||
auto r = this->_returnValue;
|
auto r = this->_returnValue.Take();
|
||||||
this->_returnValue = nullptr;
|
delete function;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::EvaluateIndexExpression(const BoundExpression *expression) {
|
EvalValuePointer Evaluator::EvaluateIndexExpression(const BoundExpression *expression) {
|
||||||
auto indexExpression = (BoundIndexExpression *) expression;
|
auto indexExpression = (BoundIndexExpression *) expression;
|
||||||
auto index = this->EvaluateExpression(indexExpression->GetIndexExpression());
|
auto index = this->EvaluateExpression(indexExpression->GetIndexExpression());
|
||||||
auto indexable = this->EvaluateExpression(indexExpression->GetIndexableExpression());
|
auto indexable = this->EvaluateExpression(indexExpression->GetIndexableExpression());
|
||||||
return indexable->IndexValue(index.get());
|
return indexable->IndexValue(index.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::EvaluatePeriodIndexExpression(const BoundExpression *expression) {
|
EvalValuePointer Evaluator::EvaluatePeriodIndexExpression(const BoundExpression *expression) {
|
||||||
auto indexExpression = (BoundPeriodIndexExpression *) expression;
|
auto indexExpression = (BoundPeriodIndexExpression *) expression;
|
||||||
auto index = indexExpression->GetIndex()->GetHash();
|
auto index = indexExpression->GetIndex()->GetHash();
|
||||||
auto indexable = this->EvaluateExpression(indexExpression->GetIndexableExpression());
|
auto indexable = this->EvaluateExpression(indexExpression->GetIndexableExpression());
|
||||||
return indexable->IndexValue(index)->Clone();
|
return indexable->IndexValue(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) {
|
EvalValuePointer Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) {
|
||||||
auto tableExpression = (BoundNumericalTableExpression *) expression;
|
auto tableExpression = (BoundNumericalTableExpression *) expression;
|
||||||
auto valueExpressions = tableExpression->GetExpressions();
|
auto valueExpressions = tableExpression->GetExpressions();
|
||||||
auto values = new vector<shared_ptr<const EvalValue>>(valueExpressions->size());
|
auto values = new vector<EvalValuePointer>(valueExpressions->size());
|
||||||
for (size_t i = 0; i < valueExpressions->size(); i++) {
|
for (size_t i = 0; i < valueExpressions->size(); i++) {
|
||||||
auto val = this->EvaluateExpression(valueExpressions->at(i));
|
auto val = this->EvaluateExpression(valueExpressions->at(i));
|
||||||
values->at(i) = val;
|
values->at(i) = val.Take();
|
||||||
}
|
}
|
||||||
auto valuesPointer = shared_ptr<vector<shared_ptr<const EvalValue>>>(values);
|
auto valuesPointer = shared_ptr<vector<EvalValuePointer>>(values);
|
||||||
return make_shared<NumericalTableEvalValue>(valuesPointer);
|
return new NumericalTableEvalValue(valuesPointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::EvaluateComplexTableExpression(const BoundExpression *expression) {
|
EvalValuePointer Evaluator::EvaluateComplexTableExpression(const BoundExpression *expression) {
|
||||||
auto tableExpression = (BoundTableExpression *) expression;
|
auto tableExpression = (BoundTableExpression *) expression;
|
||||||
auto type = dynamic_pointer_cast<const TableScriptType>(tableExpression->GetType());
|
const auto& baseType = tableExpression -> GetType();
|
||||||
|
auto type = dynamic_pointer_cast<const TableScriptType>(baseType);
|
||||||
auto declaredVars = type->GetValues();
|
auto declaredVars = type->GetValues();
|
||||||
auto variables = make_shared<map<Utilities::HashedString, shared_ptr<const EvalValue>>>();
|
auto variables = make_shared<map<Utilities::HashedString, EvalValuePointer>>();
|
||||||
for (const auto& i : *declaredVars) {
|
for (const auto& i : *declaredVars) {
|
||||||
variables->insert({i.first, nullptr});
|
variables->insert({i.first, nullptr});
|
||||||
}
|
}
|
||||||
|
@ -473,17 +394,6 @@ namespace Porygon::Evaluation {
|
||||||
this->_evaluationScope = evaluator;
|
this->_evaluationScope = evaluator;
|
||||||
this->EvaluateBlockStatement(tableExpression->GetBlock());
|
this->EvaluateBlockStatement(tableExpression->GetBlock());
|
||||||
this->_evaluationScope = currentEvaluator;
|
this->_evaluationScope = currentEvaluator;
|
||||||
return make_shared<TableEvalValue>(variables);
|
return new TableEvalValue(variables);
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluator::EvaluateUserDataExpression(const BoundExpression *expression) {
|
|
||||||
switch (expression->GetKind()) {
|
|
||||||
case BoundExpressionKind::Variable:
|
|
||||||
return this->GetVariable((BoundVariableExpression *) expression);
|
|
||||||
case BoundExpressionKind::Index:
|
|
||||||
return this->EvaluateIndexExpression(expression);
|
|
||||||
default:
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,13 +10,14 @@
|
||||||
#include "EvalValues/StringEvalValue.hpp"
|
#include "EvalValues/StringEvalValue.hpp"
|
||||||
#include "EvalValues/ScriptFunctionEvalValue.hpp"
|
#include "EvalValues/ScriptFunctionEvalValue.hpp"
|
||||||
#include "EvaluationScope/EvaluationScope.hpp"
|
#include "EvaluationScope/EvaluationScope.hpp"
|
||||||
|
#include "EvalValuePointer.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace Porygon::Evaluation{
|
namespace Porygon::Evaluation{
|
||||||
class Evaluator {
|
class Evaluator {
|
||||||
shared_ptr<const EvalValue> _returnValue;
|
EvalValuePointer _returnValue;
|
||||||
map<Utilities::HashedString, shared_ptr<const EvalValue>>* _scriptVariables;
|
map<Utilities::HashedString, EvalValuePointer>* _scriptVariables;
|
||||||
bool _hasReturned;
|
bool _hasReturned;
|
||||||
bool _hasBroken;
|
bool _hasBroken;
|
||||||
|
|
||||||
|
@ -35,36 +36,25 @@ namespace Porygon::Evaluation{
|
||||||
void EvaluateGenericForStatement(const BoundGenericForStatement *statement);
|
void EvaluateGenericForStatement(const BoundGenericForStatement *statement);
|
||||||
void EvaluateWhileStatement(const BoundWhileStatement *statement);
|
void EvaluateWhileStatement(const BoundWhileStatement *statement);
|
||||||
|
|
||||||
shared_ptr<const EvalValue> EvaluateExpression(const BoundExpression *expression);
|
EvalValuePointer EvaluateExpression(const BoundExpression *expression);
|
||||||
shared_ptr<const NumericEvalValue> EvaluateIntegerExpression(const BoundExpression *expression);
|
EvalValuePointer EvaluateBinary(const BoundBinaryExpression *expression);
|
||||||
shared_ptr<const BooleanEvalValue> EvaluateBoolExpression(const BoundExpression *expression);
|
EvalValuePointer EvaluateUnary(const BoundUnaryExpression *expression);
|
||||||
shared_ptr<const StringEvalValue> EvaluateStringExpression(const BoundExpression *expression);
|
|
||||||
shared_ptr<const EvalValue> EvaluateFunctionExpression(const BoundExpression *expression);
|
|
||||||
shared_ptr<const EvalValue> EvaluateNilExpression(const BoundExpression *expression);
|
|
||||||
shared_ptr<const EvalValue> EvaluateTableExpression(const BoundExpression *expression);
|
|
||||||
|
|
||||||
shared_ptr<const NumericEvalValue> EvaluateIntegerBinary(const BoundBinaryExpression *expression);
|
EvalValuePointer EvaluateFunctionCallExpression(const BoundExpression *expression);
|
||||||
shared_ptr<const BooleanEvalValue> EvaluateBooleanBinary(const BoundBinaryExpression *expression);
|
EvalValuePointer EvaluateIndexExpression(const BoundExpression *expression);
|
||||||
shared_ptr<const StringEvalValue> EvaluateStringBinary(const BoundBinaryExpression *expression);
|
EvalValuePointer EvaluatePeriodIndexExpression(const BoundExpression *expression);
|
||||||
|
EvalValuePointer EvaluateNumericTableExpression(const BoundExpression *expression);
|
||||||
|
EvalValuePointer EvaluateComplexTableExpression(const BoundExpression *expression);
|
||||||
|
|
||||||
shared_ptr<const NumericEvalValue> EvaluateIntegerUnary(const BoundUnaryExpression *expression);
|
EvalValuePointer GetVariable(const BoundVariableExpression *expression);
|
||||||
shared_ptr<const BooleanEvalValue> EvaluateBooleanUnary(const BoundUnaryExpression *expression);
|
|
||||||
shared_ptr<const EvalValue> EvaluateFunctionCallExpression(const BoundExpression *expression);
|
|
||||||
shared_ptr<const EvalValue> EvaluateIndexExpression(const BoundExpression *expression);
|
|
||||||
shared_ptr<const EvalValue> EvaluatePeriodIndexExpression(const BoundExpression *expression);
|
|
||||||
shared_ptr<const EvalValue> EvaluateNumericTableExpression(const BoundExpression *expression);
|
|
||||||
shared_ptr<const EvalValue> EvaluateUserDataExpression(const BoundExpression *expression);
|
|
||||||
shared_ptr<const EvalValue> EvaluateComplexTableExpression(const BoundExpression *expression);
|
|
||||||
|
|
||||||
shared_ptr<const EvalValue> GetVariable(const BoundVariableExpression *expression);
|
|
||||||
public:
|
public:
|
||||||
explicit Evaluator(map<Utilities::HashedString, shared_ptr<const EvalValue>>* scriptVariables)
|
explicit Evaluator(map<Utilities::HashedString, EvalValuePointer>* scriptVariables)
|
||||||
: _scriptVariables(scriptVariables), _hasReturned(false), _hasBroken(false), _returnValue(nullptr),
|
: _scriptVariables(scriptVariables), _hasReturned(false), _hasBroken(false), _returnValue(nullptr),
|
||||||
_evaluationScope(nullptr){
|
_evaluationScope(nullptr){
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluate(const BoundScriptStatement* statement);
|
const EvalValue* Evaluate(const BoundScriptStatement* statement);
|
||||||
shared_ptr<const EvalValue> EvaluateFunction(const GenericFunctionEvalValue *function,
|
const EvalValue* EvaluateFunction(const GenericFunctionEvalValue *function,
|
||||||
const vector<EvalValue *> ¶meters);
|
const vector<EvalValue *> ¶meters);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,7 @@ using namespace std;
|
||||||
namespace Porygon::Evaluation{
|
namespace Porygon::Evaluation{
|
||||||
class Iterator {
|
class Iterator {
|
||||||
public:
|
public:
|
||||||
virtual shared_ptr<EvalValue> GetCurrent() = 0;
|
virtual EvalValue* GetCurrent() = 0;
|
||||||
virtual bool MoveNext() = 0;
|
virtual bool MoveNext() = 0;
|
||||||
virtual void Reset() = 0;
|
virtual void Reset() = 0;
|
||||||
virtual ~Iterator(){}
|
virtual ~Iterator(){}
|
||||||
|
|
|
@ -9,15 +9,15 @@
|
||||||
|
|
||||||
namespace Porygon::Evaluation{
|
namespace Porygon::Evaluation{
|
||||||
class NumericalKeyIterator : public Iterator{
|
class NumericalKeyIterator : public Iterator{
|
||||||
const shared_ptr<vector<shared_ptr<const EvalValue>>> _vec;
|
const shared_ptr<vector<EvalValuePointer>> _vec;
|
||||||
const size_t _size;
|
const size_t _size;
|
||||||
long _position = 0;
|
long _position = 0;
|
||||||
public:
|
public:
|
||||||
explicit NumericalKeyIterator(const NumericalTableEvalValue* table)
|
explicit NumericalKeyIterator(const NumericalTableEvalValue* table)
|
||||||
: _vec(table->GetTable()), _size(_vec->size() + 1){}
|
: _vec(table->GetTable()), _size(_vec->size() + 1){}
|
||||||
|
|
||||||
inline shared_ptr<EvalValue> GetCurrent() final{
|
inline EvalValue* GetCurrent() final{
|
||||||
return make_shared<IntegerEvalValue>(_position);
|
return new IntegerEvalValue(_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool MoveNext() final{
|
inline bool MoveNext() final{
|
||||||
|
|
|
@ -8,15 +8,15 @@
|
||||||
|
|
||||||
namespace Porygon::Evaluation{
|
namespace Porygon::Evaluation{
|
||||||
class TableKeyIterator : public Iterator{
|
class TableKeyIterator : public Iterator{
|
||||||
_Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<const EvalValue>>> _iterator;
|
_Rb_tree_const_iterator<pair<const Utilities::HashedString, EvalValuePointer>> _iterator;
|
||||||
_Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<const EvalValue>>> _end;
|
_Rb_tree_const_iterator<pair<const Utilities::HashedString, EvalValuePointer>> _end;
|
||||||
bool _hasStarted = false;
|
bool _hasStarted = false;
|
||||||
public:
|
public:
|
||||||
explicit TableKeyIterator(const TableEvalValue* table)
|
explicit TableKeyIterator(const TableEvalValue* table)
|
||||||
: _iterator(table->GetTableIterator()), _end(table->GetTableIteratorEnd()){}
|
: _iterator(table->GetTableIterator()), _end(table->GetTableIteratorEnd()){}
|
||||||
|
|
||||||
inline shared_ptr<EvalValue> GetCurrent() final{
|
inline EvalValue* GetCurrent() final{
|
||||||
return make_shared<StringEvalValue>(*_iterator->first.GetString());
|
return new StringEvalValue(*_iterator->first.GetString());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MoveNext() final{
|
bool MoveNext() final{
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
|
|
||||||
#include "EvalValues/NumericEvalValue.hpp"
|
|
||||||
#include "Evaluator.hpp"
|
|
||||||
#include "EvaluationException.hpp"
|
|
||||||
#include "../Script.hpp"
|
|
||||||
|
|
||||||
namespace Porygon::Evaluation {
|
|
||||||
shared_ptr<const NumericEvalValue> Evaluator::EvaluateIntegerUnary(const BoundUnaryExpression *expression) {
|
|
||||||
switch (expression->GetOperation()) {
|
|
||||||
case BoundUnaryOperation::Negation: {
|
|
||||||
auto operandValue = EvaluateIntegerExpression(expression->GetOperand());
|
|
||||||
if (operandValue->IsFloat()) {
|
|
||||||
double f = operandValue->EvaluateFloat();
|
|
||||||
return make_shared<FloatEvalValue>(-f);
|
|
||||||
} else {
|
|
||||||
long l = operandValue->EvaluateInteger();
|
|
||||||
return make_shared<IntegerEvalValue>(-l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<const BooleanEvalValue> Evaluator::EvaluateBooleanUnary(const BoundUnaryExpression *expression) {
|
|
||||||
switch (expression->GetOperation()) {
|
|
||||||
case BoundUnaryOperation::LogicalNegation: {
|
|
||||||
auto val = EvaluateBoolExpression(expression->GetOperand());
|
|
||||||
bool b = val->EvaluateBool();
|
|
||||||
return make_shared<BooleanEvalValue>(!b);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,13 +24,13 @@ Porygon::Script *Porygon::Script::Create(const string &script) {
|
||||||
Porygon::Script::Script(const u16string& s)
|
Porygon::Script::Script(const u16string& s)
|
||||||
: Diagnostics(make_shared<Diagnostics::DiagnosticsHolder>(s)),
|
: Diagnostics(make_shared<Diagnostics::DiagnosticsHolder>(s)),
|
||||||
_boundScript(nullptr),
|
_boundScript(nullptr),
|
||||||
_scriptVariables(new map<Utilities::HashedString, shared_ptr<const EvalValue>>())
|
_scriptVariables(new map<Utilities::HashedString, EvalValuePointer>())
|
||||||
{
|
{
|
||||||
_evaluator = new Evaluator(this -> _scriptVariables);
|
_evaluator = new Evaluator(this -> _scriptVariables);
|
||||||
this -> Parse(s);
|
this -> Parse(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Porygon::Script::Evaluate() {
|
EvalValuePointer Porygon::Script::Evaluate() {
|
||||||
return _evaluator->Evaluate(_boundScript.get());
|
return _evaluator->Evaluate(_boundScript.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ void Porygon::Script::Parse(const u16string& script) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const EvalValue* Porygon::Script::GetVariable(const u16string &key) {
|
const EvalValue* Porygon::Script::GetVariable(const u16string &key) {
|
||||||
return _scriptVariables -> at(HashedString::CreateLookup(key)).get();
|
return _scriptVariables -> at(HashedString::CreateLookup(key)).Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Porygon::Script::HasVariable(const u16string &key) {
|
bool Porygon::Script::HasVariable(const u16string &key) {
|
||||||
|
@ -80,7 +80,7 @@ bool Porygon::Script::HasFunction(const u16string &key) {
|
||||||
return f != _scriptVariables->end() && f.operator->()->second->GetTypeClass() == TypeClass ::Function;
|
return f != _scriptVariables->end() && f.operator->()->second->GetTypeClass() == TypeClass ::Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Porygon::Script::CallFunction(const u16string &key, const vector<EvalValue *>& variables) {
|
const EvalValue* Porygon::Script::CallFunction(const u16string &key, const vector<EvalValue *>& variables) {
|
||||||
auto var = (GenericFunctionEvalValue*)GetVariable(key);
|
auto var = (GenericFunctionEvalValue*)GetVariable(key);
|
||||||
return this->_evaluator->EvaluateFunction(var, variables);
|
return this->_evaluator->EvaluateFunction(var, variables);
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ Porygon::Script::Script(shared_ptr<BoundScriptStatement> boundScript,
|
||||||
shared_ptr<Porygon::Diagnostics::DiagnosticsHolder> diagnostics)
|
shared_ptr<Porygon::Diagnostics::DiagnosticsHolder> diagnostics)
|
||||||
: _boundScript(std::move(boundScript)),
|
: _boundScript(std::move(boundScript)),
|
||||||
Diagnostics(std::move(diagnostics)),
|
Diagnostics(std::move(diagnostics)),
|
||||||
_scriptVariables(new map<Utilities::HashedString, shared_ptr<const EvalValue>>())
|
_scriptVariables(new map<Utilities::HashedString, EvalValuePointer>())
|
||||||
{
|
{
|
||||||
_evaluator = new Evaluator(_scriptVariables);
|
_evaluator = new Evaluator(_scriptVariables);
|
||||||
}
|
}
|
||||||
|
@ -111,8 +111,7 @@ extern "C" {
|
||||||
|
|
||||||
const EvalValue* EvaluateScript(Porygon::Script* script){
|
const EvalValue* EvaluateScript(Porygon::Script* script){
|
||||||
auto result = script -> Evaluate();
|
auto result = script -> Evaluate();
|
||||||
auto resultPtr = result.get();
|
return result.Clone();
|
||||||
return resultPtr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasVariable(Porygon::Script* script, const char16_t* key){
|
bool HasVariable(Porygon::Script* script, const char16_t* key){
|
||||||
|
@ -129,6 +128,6 @@ extern "C" {
|
||||||
|
|
||||||
const EvalValue* CallFunction(Porygon::Script* script, const char16_t* key, EvalValue* parameters[], int parameterCount){
|
const EvalValue* CallFunction(Porygon::Script* script, const char16_t* key, EvalValue* parameters[], int parameterCount){
|
||||||
std::vector<EvalValue*> v(parameters, parameters + parameterCount);
|
std::vector<EvalValue*> v(parameters, parameters + parameterCount);
|
||||||
return script->CallFunction(key, v).get();
|
return script->CallFunction(key, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,7 +17,7 @@ using namespace Porygon::Evaluation;
|
||||||
namespace Porygon{
|
namespace Porygon{
|
||||||
class Script {
|
class Script {
|
||||||
Evaluator* _evaluator;
|
Evaluator* _evaluator;
|
||||||
map<Utilities::HashedString, shared_ptr<const EvalValue>>* _scriptVariables;
|
map<Utilities::HashedString, EvalValuePointer>* _scriptVariables;
|
||||||
shared_ptr<Binder::BoundScriptStatement> _boundScript;
|
shared_ptr<Binder::BoundScriptStatement> _boundScript;
|
||||||
shared_ptr<const ScriptType> _returnType;
|
shared_ptr<const ScriptType> _returnType;
|
||||||
|
|
||||||
|
@ -41,14 +41,12 @@ namespace Porygon{
|
||||||
_returnType = t;
|
_returnType = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> Evaluate();
|
EvalValuePointer Evaluate();
|
||||||
|
|
||||||
//const EvalValue* GetLastValue();
|
|
||||||
|
|
||||||
const EvalValue* GetVariable(const u16string& key);
|
const EvalValue* GetVariable(const u16string& key);
|
||||||
bool HasVariable(const u16string& key);
|
bool HasVariable(const u16string& key);
|
||||||
|
|
||||||
shared_ptr<const EvalValue> CallFunction(const u16string& key, const vector<EvalValue*>& variables);
|
const EvalValue* CallFunction(const u16string& key, const vector<EvalValue*>& variables);
|
||||||
bool HasFunction(const u16string& key);
|
bool HasFunction(const u16string& key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -74,10 +74,10 @@ namespace Porygon::StandardLibraries{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static shared_ptr<Evaluation::EvalValue> GetFuncEvalValue(
|
static Evaluation::EvalValue* GetFuncEvalValue(
|
||||||
const Evaluation::EvalValue* (*func)(void* obj, const Evaluation::EvalValue* parameters[], int parameterCount),
|
const Evaluation::EvalValue* (*func)(void* obj, const Evaluation::EvalValue* parameters[], int parameterCount),
|
||||||
const shared_ptr<GenericFunctionScriptType>& type, size_t optionLength){
|
const shared_ptr<GenericFunctionScriptType>& type, size_t optionLength){
|
||||||
auto f = make_shared<Evaluation::GenericFunctionEvalValue>(type, rand());
|
auto f = new Evaluation::GenericFunctionEvalValue(type, rand());
|
||||||
for (size_t i = 0; i < optionLength; i++){
|
for (size_t i = 0; i < optionLength; i++){
|
||||||
auto funcOption = new UserData::UserDataFunction(func, nullptr);
|
auto funcOption = new UserData::UserDataFunction(func, nullptr);
|
||||||
f->RegisterOption(funcOption);
|
f->RegisterOption(funcOption);
|
||||||
|
@ -88,7 +88,7 @@ namespace Porygon::StandardLibraries{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void RegisterVariables(std::map<Utilities::HashedString, Binder::BoundVariable *>* bound,
|
static void RegisterVariables(std::map<Utilities::HashedString, Binder::BoundVariable *>* bound,
|
||||||
std::map<Utilities::HashedString, shared_ptr<Evaluation::EvalValue>>* values){
|
std::map<Utilities::HashedString, Evaluation::EvalValue*>* values){
|
||||||
// Register error function
|
// Register error function
|
||||||
auto errorFuncType = BasicLibrary::GetErrorFuncType();
|
auto errorFuncType = BasicLibrary::GetErrorFuncType();
|
||||||
auto errorLookup = Utilities::HashedString::CreateLookup(u"error");
|
auto errorLookup = Utilities::HashedString::CreateLookup(u"error");
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace Porygon::StandardLibraries{
|
||||||
class InternalScope{
|
class InternalScope{
|
||||||
public:
|
public:
|
||||||
map<Utilities::HashedString, Binder::BoundVariable *> _boundVariables;
|
map<Utilities::HashedString, Binder::BoundVariable *> _boundVariables;
|
||||||
map<Utilities::HashedString, shared_ptr<Evaluation::EvalValue>> _variables;
|
map<Utilities::HashedString, Evaluation::EvalValue*> _variables;
|
||||||
|
|
||||||
InternalScope(){
|
InternalScope(){
|
||||||
BasicLibrary::RegisterVariables(&_boundVariables, &_variables);
|
BasicLibrary::RegisterVariables(&_boundVariables, &_variables);
|
||||||
|
@ -29,6 +29,9 @@ namespace Porygon::StandardLibraries{
|
||||||
for (const auto& b: _boundVariables){
|
for (const auto& b: _boundVariables){
|
||||||
delete b.second;
|
delete b.second;
|
||||||
}
|
}
|
||||||
|
for (const auto& v: _variables){
|
||||||
|
delete v.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,7 +39,7 @@ namespace Porygon::StandardLibraries{
|
||||||
public:
|
public:
|
||||||
static void RegisterVariable(const Utilities::HashedString& identifier, shared_ptr<ScriptType> type, Evaluation::EvalValue* value){
|
static void RegisterVariable(const Utilities::HashedString& identifier, shared_ptr<ScriptType> type, Evaluation::EvalValue* value){
|
||||||
_internal._boundVariables.insert({identifier, new Binder::BoundVariable(std::move(type))});
|
_internal._boundVariables.insert({identifier, new Binder::BoundVariable(std::move(type))});
|
||||||
_internal._variables.insert({identifier, shared_ptr<Evaluation::EvalValue>(value)});
|
_internal._variables.insert({identifier, value});
|
||||||
}
|
}
|
||||||
|
|
||||||
static Binder::BoundVariable* GetBoundVariable(const Utilities::HashedString &identifier){
|
static Binder::BoundVariable* GetBoundVariable(const Utilities::HashedString &identifier){
|
||||||
|
@ -47,8 +50,8 @@ namespace Porygon::StandardLibraries{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static shared_ptr<Evaluation::EvalValue> GetVariable(const Utilities::HashedString &identifier){
|
inline static Evaluation::EvalValuePointer GetVariable(const Utilities::HashedString &identifier){
|
||||||
return _internal._variables[identifier];
|
return _internal._variables[identifier]->Clone();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@ namespace Porygon::UserData {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> Clone() const final {
|
inline Evaluation::EvalValue* Clone() const final {
|
||||||
return make_shared<UserDataValue>(_userData, _obj);
|
return new UserDataValue(_userData, _obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
@ -43,22 +43,23 @@ namespace Porygon::UserData {
|
||||||
return reinterpret_cast<intptr_t>(_obj);
|
return reinterpret_cast<intptr_t>(_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const EvalValue> IndexValue(const EvalValue *val) const final {
|
const Evaluation::EvalValue* IndexValue(const EvalValue *val) const final {
|
||||||
auto fieldId = val->GetHashCode();
|
auto fieldId = val->GetHashCode();
|
||||||
auto field = _userData->GetField(fieldId);
|
auto field = _userData->GetField(fieldId);
|
||||||
return shared_ptr<const EvalValue>(field->Get(_obj));
|
return field->Get(_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const EvalValue> IndexValue(uint32_t hash) const final {
|
inline const EvalValue* IndexValue(uint32_t hash) const final {
|
||||||
auto field = _userData->GetField(hash);
|
auto field = _userData->GetField(hash);
|
||||||
return shared_ptr<const EvalValue>(field->Get(_obj));
|
return field->Get(_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIndexValue(const EvalValue *key, const shared_ptr<const EvalValue> &value) const final {
|
void SetIndexValue(const EvalValue *key, const EvalValue* value) const final {
|
||||||
auto fieldId = key->GetHashCode();
|
auto fieldId = key->GetHashCode();
|
||||||
auto field = _userData->GetField(fieldId);
|
auto field = _userData->GetField(fieldId);
|
||||||
field->Set(_obj, value.get());
|
field->Set(_obj, value);
|
||||||
|
delete value;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void* GetObjectPointer(){
|
inline void* GetObjectPointer(){
|
||||||
|
|
|
@ -14,6 +14,7 @@ TEST_CASE( "Basic conditional", "[integration]" ) {
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
REQUIRE(variable->EvaluateBool());
|
REQUIRE(variable->EvaluateBool());
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "If then, else", "[integration]" ) {
|
TEST_CASE( "If then, else", "[integration]" ) {
|
||||||
|
@ -26,6 +27,7 @@ TEST_CASE( "If then, else", "[integration]" ) {
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
REQUIRE(variable->EvaluateBool());
|
REQUIRE(variable->EvaluateBool());
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "If then, else if", "[integration]" ) {
|
TEST_CASE( "If then, else if", "[integration]" ) {
|
||||||
|
@ -38,6 +40,7 @@ TEST_CASE( "If then, else if", "[integration]" ) {
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
REQUIRE(variable->EvaluateBool());
|
REQUIRE(variable->EvaluateBool());
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ TEST_CASE( "Define script function", "[integration]" ) {
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
REQUIRE(variable->GetTypeClass() == TypeClass::Function);
|
REQUIRE(variable->GetTypeClass() == TypeClass::Function);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Define script function and call", "[integration]" ) {
|
TEST_CASE( "Define script function and call", "[integration]" ) {
|
||||||
|
@ -25,6 +26,8 @@ TEST_CASE( "Define script function and call", "[integration]" ) {
|
||||||
REQUIRE(result->GetTypeClass() == TypeClass::Number);
|
REQUIRE(result->GetTypeClass() == TypeClass::Number);
|
||||||
REQUIRE(result->EvaluateInteger() == 3);
|
REQUIRE(result->EvaluateInteger() == 3);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Define script function and call multiple times", "[integration]" ) {
|
TEST_CASE( "Define script function and call multiple times", "[integration]" ) {
|
||||||
|
@ -38,6 +41,8 @@ TEST_CASE( "Define script function and call multiple times", "[integration]" ) {
|
||||||
REQUIRE(result->GetTypeClass() == TypeClass::Number);
|
REQUIRE(result->GetTypeClass() == TypeClass::Number);
|
||||||
REQUIRE(result->EvaluateInteger() == 5);
|
REQUIRE(result->EvaluateInteger() == 5);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Define script function and call from extern", "[integration]" ) {
|
TEST_CASE( "Define script function and call from extern", "[integration]" ) {
|
||||||
|
@ -57,6 +62,7 @@ TEST_CASE( "Define script function and call from extern", "[integration]" ) {
|
||||||
REQUIRE(result->GetTypeClass() == TypeClass::Number);
|
REQUIRE(result->GetTypeClass() == TypeClass::Number);
|
||||||
REQUIRE(result->EvaluateInteger() == 11);
|
REQUIRE(result->EvaluateInteger() == 11);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Define script function and return", "[integration]" ) {
|
TEST_CASE( "Define script function and return", "[integration]" ) {
|
||||||
|
@ -84,6 +90,8 @@ TEST_CASE( "Define script function and return", "[integration]" ) {
|
||||||
REQUIRE(variable->EvaluateInteger() == 0);
|
REQUIRE(variable->EvaluateInteger() == 0);
|
||||||
|
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Functions can call themselves", "[integration]" ) {
|
TEST_CASE( "Functions can call themselves", "[integration]" ) {
|
||||||
|
@ -106,6 +114,7 @@ end
|
||||||
REQUIRE(variable->EvaluateInteger() == 5);
|
REQUIRE(variable->EvaluateInteger() == 5);
|
||||||
|
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Functions respect scope", "[integration]" ) {
|
TEST_CASE( "Functions respect scope", "[integration]" ) {
|
||||||
|
@ -134,6 +143,7 @@ test()
|
||||||
REQUIRE(variable->EvaluateInteger() == 50);
|
REQUIRE(variable->EvaluateInteger() == 50);
|
||||||
|
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Return doesn't parse next line expression", "[integration]" ) {
|
TEST_CASE( "Return doesn't parse next line expression", "[integration]" ) {
|
||||||
|
@ -174,8 +184,9 @@ stringResult = add('foo', 'bar')
|
||||||
REQUIRE(stringVar != nullptr);
|
REQUIRE(stringVar != nullptr);
|
||||||
CHECK(stringVar->EvaluateString() == u"foobar");
|
CHECK(stringVar->EvaluateString() == u"foobar");
|
||||||
|
|
||||||
|
|
||||||
delete script;
|
delete script;
|
||||||
|
delete intVar;
|
||||||
|
delete stringVar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ end
|
||||||
auto var = script->GetVariable(u"result");
|
auto var = script->GetVariable(u"result");
|
||||||
REQUIRE(var->EvaluateInteger() == 33);
|
REQUIRE(var->EvaluateInteger() == 33);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete var;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Numerical for loop with step", "[integration]" ) {
|
TEST_CASE( "Numerical for loop with step", "[integration]" ) {
|
||||||
|
@ -29,6 +30,7 @@ end
|
||||||
auto var = script->GetVariable(u"result");
|
auto var = script->GetVariable(u"result");
|
||||||
REQUIRE(var->EvaluateInteger() == 12);
|
REQUIRE(var->EvaluateInteger() == 12);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete var;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Numerical for loop with negative step", "[integration]" ) {
|
TEST_CASE( "Numerical for loop with negative step", "[integration]" ) {
|
||||||
|
@ -43,6 +45,7 @@ end
|
||||||
auto var = script->GetVariable(u"result");
|
auto var = script->GetVariable(u"result");
|
||||||
REQUIRE(var->EvaluateInteger() == 33);
|
REQUIRE(var->EvaluateInteger() == 33);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,6 +61,7 @@ end
|
||||||
auto var = script->GetVariable(u"result");
|
auto var = script->GetVariable(u"result");
|
||||||
REQUIRE(var->EvaluateInteger() == 15);
|
REQUIRE(var->EvaluateInteger() == 15);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete var;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Numerical for loop, break", "[integration]" ) {
|
TEST_CASE( "Numerical for loop, break", "[integration]" ) {
|
||||||
|
@ -73,6 +77,7 @@ end
|
||||||
auto var = script->GetVariable(u"result");
|
auto var = script->GetVariable(u"result");
|
||||||
REQUIRE(var->EvaluateInteger() == 6);
|
REQUIRE(var->EvaluateInteger() == 6);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,6 +94,7 @@ end
|
||||||
auto var = script->GetVariable(u"result");
|
auto var = script->GetVariable(u"result");
|
||||||
REQUIRE(var->EvaluateInteger() == 15);
|
REQUIRE(var->EvaluateInteger() == 15);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete var;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Generic for loop over simple numerical table, get values", "[integration]" ) {
|
TEST_CASE( "Generic for loop over simple numerical table, get values", "[integration]" ) {
|
||||||
|
@ -104,6 +110,7 @@ end
|
||||||
auto var = script->GetVariable(u"result");
|
auto var = script->GetVariable(u"result");
|
||||||
REQUIRE(var->EvaluateInteger() == 25);
|
REQUIRE(var->EvaluateInteger() == 25);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete var;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Generic for loop over simple numerical table, break", "[integration]" ) {
|
TEST_CASE( "Generic for loop over simple numerical table, break", "[integration]" ) {
|
||||||
|
@ -120,6 +127,7 @@ end
|
||||||
auto var = script->GetVariable(u"result");
|
auto var = script->GetVariable(u"result");
|
||||||
REQUIRE(var->EvaluateInteger() == 9);
|
REQUIRE(var->EvaluateInteger() == 9);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete var;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "While loop", "[integration]" ) {
|
TEST_CASE( "While loop", "[integration]" ) {
|
||||||
|
@ -134,6 +142,7 @@ end
|
||||||
auto var = script->GetVariable(u"result");
|
auto var = script->GetVariable(u"result");
|
||||||
REQUIRE(var->EvaluateInteger() == 5);
|
REQUIRE(var->EvaluateInteger() == 5);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete var;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "While loop break", "[integration]" ) {
|
TEST_CASE( "While loop break", "[integration]" ) {
|
||||||
|
@ -149,6 +158,7 @@ end
|
||||||
auto var = script->GetVariable(u"result");
|
auto var = script->GetVariable(u"result");
|
||||||
REQUIRE(var->EvaluateInteger() == 5);
|
REQUIRE(var->EvaluateInteger() == 5);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete var;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,6 +11,7 @@ TEST_CASE( "Create empty table", "[integration]" ) {
|
||||||
auto variable = script->GetVariable(u"table");
|
auto variable = script->GetVariable(u"table");
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Create simple integer table", "[integration]" ) {
|
TEST_CASE( "Create simple integer table", "[integration]" ) {
|
||||||
|
@ -20,6 +21,7 @@ TEST_CASE( "Create simple integer table", "[integration]" ) {
|
||||||
auto variable = script->GetVariable(u"table");
|
auto variable = script->GetVariable(u"table");
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Create simple string table", "[integration]" ) {
|
TEST_CASE( "Create simple string table", "[integration]" ) {
|
||||||
|
@ -29,6 +31,7 @@ TEST_CASE( "Create simple string table", "[integration]" ) {
|
||||||
auto variable = script->GetVariable(u"table");
|
auto variable = script->GetVariable(u"table");
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Index string table", "[integration]" ) {
|
TEST_CASE( "Index string table", "[integration]" ) {
|
||||||
|
@ -39,7 +42,7 @@ return table[3]
|
||||||
)");
|
)");
|
||||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||||
auto variable = script->Evaluate();
|
auto variable = script->Evaluate();
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable.Get() != nullptr);
|
||||||
REQUIRE(variable->EvaluateString() == u"foo");
|
REQUIRE(variable->EvaluateString() == u"foo");
|
||||||
delete script;
|
delete script;
|
||||||
}
|
}
|
||||||
|
@ -57,9 +60,14 @@ table = {
|
||||||
auto variable = script->GetVariable(u"table");
|
auto variable = script->GetVariable(u"table");
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
auto table = (TableEvalValue*)variable;
|
auto table = (TableEvalValue*)variable;
|
||||||
CHECK(table->IndexValue("foo")->EvaluateString() == u"test");
|
auto res = table->IndexValue("foo");
|
||||||
CHECK(table->IndexValue("bar")->EvaluateInteger() == 100);
|
auto res2 = table->IndexValue("bar");
|
||||||
|
CHECK(res->EvaluateString() == u"test");
|
||||||
|
CHECK(res2->EvaluateInteger() == 100);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete table;
|
||||||
|
delete res;
|
||||||
|
delete res2;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Complex table with function", "[integration]" ) {
|
TEST_CASE( "Complex table with function", "[integration]" ) {
|
||||||
|
@ -75,7 +83,7 @@ return table["getFoo"]()
|
||||||
)");
|
)");
|
||||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||||
auto variable = script->Evaluate();
|
auto variable = script->Evaluate();
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable.Get() != nullptr);
|
||||||
delete script;
|
delete script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ end
|
||||||
delete par;
|
delete par;
|
||||||
delete parameter;
|
delete parameter;
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
UserDataStorage::ClearTypes();
|
UserDataStorage::ClearTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +93,7 @@ end
|
||||||
delete script;
|
delete script;
|
||||||
delete obj;
|
delete obj;
|
||||||
delete parameter;
|
delete parameter;
|
||||||
|
delete result;
|
||||||
UserDataStorage::ClearTypes();
|
UserDataStorage::ClearTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +113,7 @@ end
|
||||||
delete script;
|
delete script;
|
||||||
delete obj;
|
delete obj;
|
||||||
delete parameter;
|
delete parameter;
|
||||||
|
delete result;
|
||||||
UserDataStorage::ClearTypes();
|
UserDataStorage::ClearTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ TEST_CASE( "Create script variable", "[integration]" ) {
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
REQUIRE(variable->EvaluateBool());
|
REQUIRE(variable->EvaluateBool());
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Create local variable", "[integration]" ) {
|
TEST_CASE( "Create local variable", "[integration]" ) {
|
||||||
|
@ -32,6 +33,7 @@ TEST_CASE( "Create script variable and use", "[integration]" ) {
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
CHECK(variable->EvaluateBool());
|
CHECK(variable->EvaluateBool());
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Create local variable and use", "[integration]" ) {
|
TEST_CASE( "Create local variable and use", "[integration]" ) {
|
||||||
|
@ -43,6 +45,7 @@ TEST_CASE( "Create local variable and use", "[integration]" ) {
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
CHECK(variable->EvaluateBool());
|
CHECK(variable->EvaluateBool());
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Local variables in upmost scope persist", "[integration]" ) {
|
TEST_CASE( "Local variables in upmost scope persist", "[integration]" ) {
|
||||||
|
@ -62,6 +65,7 @@ end
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
CHECK(variable->EvaluateInteger() == 2);
|
CHECK(variable->EvaluateInteger() == 2);
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Able to use emoji", "[integration]" ) {
|
TEST_CASE( "Able to use emoji", "[integration]" ) {
|
||||||
|
@ -75,6 +79,7 @@ TEST_CASE( "Able to use emoji", "[integration]" ) {
|
||||||
REQUIRE(variable != nullptr);
|
REQUIRE(variable != nullptr);
|
||||||
CHECK(variable->EvaluateString() == u"LJ");
|
CHECK(variable->EvaluateString() == u"LJ");
|
||||||
delete script;
|
delete script;
|
||||||
|
delete variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue