From ccc6e297f2b94e2b3e8c9eba82b05c41fe13e39a Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sat, 27 Jul 2019 17:59:42 +0200 Subject: [PATCH] Rework of memory handling in Evaluation --- src/Evaluator/BinaryEvaluation.cpp | 91 ------ src/Evaluator/EvalValuePointer.cpp | 1 + src/Evaluator/EvalValuePointer.hpp | 85 ++++++ src/Evaluator/EvalValues/EvalValue.cpp | 4 +- src/Evaluator/EvalValues/EvalValue.hpp | 42 ++- src/Evaluator/EvalValues/NilEvalValue.hpp | 4 +- src/Evaluator/EvalValues/NumericEvalValue.cpp | 66 +++++ src/Evaluator/EvalValues/NumericEvalValue.hpp | 30 +- .../EvalValues/NumericalTableEvalValue.cpp | 6 + .../EvalValues/NumericalTableEvalValue.hpp | 27 +- .../EvalValues/ScriptFunctionEvalValue.hpp | 23 +- src/Evaluator/EvalValues/StringEvalValue.hpp | 19 +- src/Evaluator/EvalValues/TableEvalValue.hpp | 31 +- .../EvaluationScope/EvaluationScope.cpp | 27 +- .../EvaluationScope/EvaluationScope.hpp | 18 +- src/Evaluator/Evaluator.cpp | 278 ++++++------------ src/Evaluator/Evaluator.hpp | 40 +-- src/Evaluator/Iterator/Iterator.hpp | 2 +- .../Iterator/NumericalKeyIterator.hpp | 6 +- src/Evaluator/Iterator/SimpleKeyIterator.hpp | 8 +- src/Evaluator/UnaryEvaluation.cpp | 36 --- src/Script.cpp | 17 +- src/Script.hpp | 8 +- src/StandardLibraries/BasicLibrary.hpp | 10 +- src/StandardLibraries/StaticScope.hpp | 11 +- src/UserData/UserDataValue.hpp | 17 +- tests/integration/ConditionalTests.cpp | 3 + tests/integration/FunctionsTests.cpp | 13 +- tests/integration/LoopTests.cpp | 10 + tests/integration/TablesTests.cpp | 16 +- tests/integration/UserDataTests.cpp | 3 + tests/integration/VariablesTests.cpp | 5 + 32 files changed, 496 insertions(+), 461 deletions(-) delete mode 100644 src/Evaluator/BinaryEvaluation.cpp create mode 100644 src/Evaluator/EvalValuePointer.cpp create mode 100644 src/Evaluator/EvalValuePointer.hpp delete mode 100644 src/Evaluator/UnaryEvaluation.cpp diff --git a/src/Evaluator/BinaryEvaluation.cpp b/src/Evaluator/BinaryEvaluation.cpp deleted file mode 100644 index 5960cc4..0000000 --- a/src/Evaluator/BinaryEvaluation.cpp +++ /dev/null @@ -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 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 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(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(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 Evaluator::EvaluateStringBinary(const BoundBinaryExpression *expression) { - if (expression->GetOperation() != BoundBinaryOperation::Concatenation) - throw; - std::basic_ostringstream stringStream; - auto left = this->EvaluateStringExpression(expression->GetLeft()); - stringStream << left->EvaluateString(); - auto right = this->EvaluateExpression(expression->GetRight()); - stringStream << right->EvaluateString(); - return make_shared(stringStream.str()); - } -} \ No newline at end of file diff --git a/src/Evaluator/EvalValuePointer.cpp b/src/Evaluator/EvalValuePointer.cpp new file mode 100644 index 0000000..4c4d65e --- /dev/null +++ b/src/Evaluator/EvalValuePointer.cpp @@ -0,0 +1 @@ +#include "EvalValuePointer.hpp" diff --git a/src/Evaluator/EvalValuePointer.hpp b/src/Evaluator/EvalValuePointer.hpp new file mode 100644 index 0000000..bdf76d8 --- /dev/null +++ b/src/Evaluator/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 diff --git a/src/Evaluator/EvalValues/EvalValue.cpp b/src/Evaluator/EvalValues/EvalValue.cpp index 4954094..d36c386 100644 --- a/src/Evaluator/EvalValues/EvalValue.cpp +++ b/src/Evaluator/EvalValues/EvalValue.cpp @@ -64,9 +64,9 @@ TEST_CASE( "Evaluate String", "[integration]" ) { auto script = Porygon::Script::Create(*sc); REQUIRE(!script->Diagnostics -> HasErrors()); auto result = script->Evaluate(); - size_t size = GetEvalValueStringLength(result.get()); + size_t size = GetEvalValueStringLength(result.Get()); auto dst = new char16_t[size + 1]{'\0'}; - EvaluateEvalValueString(result.get(), dst, size); + EvaluateEvalValueString(result.Get(), dst, size); auto s = u16string(dst); REQUIRE(s == u"foo bar"); delete[] dst; diff --git a/src/Evaluator/EvalValues/EvalValue.hpp b/src/Evaluator/EvalValues/EvalValue.hpp index 265f87e..ae5977f 100644 --- a/src/Evaluator/EvalValues/EvalValue.hpp +++ b/src/Evaluator/EvalValues/EvalValue.hpp @@ -12,6 +12,7 @@ namespace Porygon::Evaluation{ class Iterator; } #include "../Iterator/Iterator.hpp" +#include "../../Binder/BoundOperators.hpp" namespace Porygon::Evaluation { @@ -33,7 +34,7 @@ namespace Porygon::Evaluation { } [[nodiscard]] - virtual shared_ptr Clone() const = 0; + virtual EvalValue* Clone() const = 0; [[nodiscard]] virtual long EvaluateInteger() const { @@ -59,16 +60,16 @@ namespace Porygon::Evaluation { virtual std::size_t GetHashCode() const = 0; [[nodiscard]] - virtual shared_ptr IndexValue(const EvalValue *val) const { + virtual const EvalValue* IndexValue(const EvalValue *val) const { throw EvaluationException("Can't index this EvalValue"); } [[nodiscard]] - virtual shared_ptr IndexValue(uint32_t hash) const { + virtual const EvalValue* IndexValue(uint32_t hash) const { throw EvaluationException("Can't index this EvalValue"); } - virtual void SetIndexValue(const EvalValue *key, const shared_ptr &value) const { + virtual void SetIndexValue(const EvalValue *key, const EvalValue* value) const { throw EvaluationException("Can't index this EvalValue"); } @@ -76,6 +77,16 @@ namespace Porygon::Evaluation { virtual Iterator * GetKeyIterator() const{ 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 { @@ -86,8 +97,8 @@ namespace Porygon::Evaluation { } [[nodiscard]] - inline shared_ptr Clone() const final { - return make_shared(_value); + inline EvalValue* Clone() const final { + return new BooleanEvalValue(_value); } [[nodiscard]] @@ -111,6 +122,25 @@ namespace Porygon::Evaluation { inline std::size_t GetHashCode() const final { 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; + } + } }; } diff --git a/src/Evaluator/EvalValues/NilEvalValue.hpp b/src/Evaluator/EvalValues/NilEvalValue.hpp index dabb37b..14ace3e 100644 --- a/src/Evaluator/EvalValues/NilEvalValue.hpp +++ b/src/Evaluator/EvalValues/NilEvalValue.hpp @@ -15,8 +15,8 @@ namespace Porygon::Evaluation{ } [[nodiscard]] - inline shared_ptr Clone() const final{ - return make_shared(); + inline EvalValue* Clone() const final{ + return new NilEvalValue(); } [[nodiscard]] diff --git a/src/Evaluator/EvalValues/NumericEvalValue.cpp b/src/Evaluator/EvalValues/NumericEvalValue.cpp index 9f92d96..02f6cf3 100644 --- a/src/Evaluator/EvalValues/NumericEvalValue.cpp +++ b/src/Evaluator/EvalValues/NumericEvalValue.cpp @@ -143,4 +143,70 @@ namespace Porygon::Evaluation { } } } + + EvalValue *IntegerEvalValue::BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue *b) const { + auto right = dynamic_cast(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(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; + } + } + } } \ No newline at end of file diff --git a/src/Evaluator/EvalValues/NumericEvalValue.hpp b/src/Evaluator/EvalValues/NumericEvalValue.hpp index 7bbb6e0..67c4403 100644 --- a/src/Evaluator/EvalValues/NumericEvalValue.hpp +++ b/src/Evaluator/EvalValues/NumericEvalValue.hpp @@ -74,14 +74,25 @@ namespace Porygon::Evaluation { } [[nodiscard]] - inline shared_ptr Clone() const final { - return make_shared(_value); + inline EvalValue* Clone() const final { + return new IntegerEvalValue(_value); } [[nodiscard]] inline std::size_t GetHashCode() const final { return std::hash{}(_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 { @@ -112,14 +123,25 @@ namespace Porygon::Evaluation { } [[nodiscard]] - inline shared_ptr Clone() const final { - return make_shared(_value); + inline EvalValue* Clone() const final { + return new FloatEvalValue(_value); } [[nodiscard]] inline std::size_t GetHashCode() const final { return std::hash{}(_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; + } + } }; } diff --git a/src/Evaluator/EvalValues/NumericalTableEvalValue.cpp b/src/Evaluator/EvalValues/NumericalTableEvalValue.cpp index eb40561..8e46c27 100644 --- a/src/Evaluator/EvalValues/NumericalTableEvalValue.cpp +++ b/src/Evaluator/EvalValues/NumericalTableEvalValue.cpp @@ -4,3 +4,9 @@ inline Porygon::Evaluation::Iterator *Porygon::Evaluation::NumericalTableEvalValue::GetKeyIterator() const { return new NumericalKeyIterator(this); } + +Porygon::Evaluation::NumericalTableEvalValue::NumericalTableEvalValue(shared_ptr> table) : + _table(std::move(table)), + _hash(rand()) +{ +} diff --git a/src/Evaluator/EvalValues/NumericalTableEvalValue.hpp b/src/Evaluator/EvalValues/NumericalTableEvalValue.hpp index 32f3069..1590ff3 100644 --- a/src/Evaluator/EvalValues/NumericalTableEvalValue.hpp +++ b/src/Evaluator/EvalValues/NumericalTableEvalValue.hpp @@ -5,26 +5,23 @@ #include #include #include "EvalValue.hpp" +#include "../EvalValuePointer.hpp" using namespace std; namespace Porygon::Evaluation { class NumericalTableEvalValue : public EvalValue { - const shared_ptr>> _table; + const shared_ptr> _table; const size_t _hash; - explicit NumericalTableEvalValue(shared_ptr>> table, size_t hash) + explicit NumericalTableEvalValue(shared_ptr> table, size_t hash) : _table(std::move(table)), _hash(hash) { } public: - explicit NumericalTableEvalValue(shared_ptr>> table) : - _table(std::move(table)), - _hash(rand()) - { - } + explicit NumericalTableEvalValue(shared_ptr> table); [[nodiscard]] inline TypeClass GetTypeClass() const final { @@ -42,22 +39,22 @@ namespace Porygon::Evaluation { } [[nodiscard]] - inline shared_ptr Clone() const final { - return shared_ptr(new NumericalTableEvalValue(_table, _hash)); + inline EvalValue* Clone() const final { + return new NumericalTableEvalValue(_table, _hash); } [[nodiscard]] - inline shared_ptr IndexValue(const EvalValue *val) const final { + inline const EvalValue* IndexValue(const EvalValue *val) const final { const auto index = val->EvaluateInteger() - 1; - return this->_table->at(index); + return this->_table->at(index).Clone(); } [[nodiscard]] - inline shared_ptr IndexValue(uint32_t hash) const final { - return this->_table->at(hash - 1); + inline EvalValue* IndexValue(uint32_t hash) const final { + return this->_table->at(hash - 1)-> Clone(); } - inline void SetIndexValue(const EvalValue *key, const shared_ptr &value) const final { + inline void SetIndexValue(const EvalValue *key, const EvalValue* value) const final { auto index = key->EvaluateInteger(); this->_table->at(index - 1) = value; } @@ -66,7 +63,7 @@ namespace Porygon::Evaluation { Iterator * GetKeyIterator() const final; [[nodiscard]] - inline shared_ptr>> GetTable() const{ + inline shared_ptr> GetTable() const{ return _table; }; }; diff --git a/src/Evaluator/EvalValues/ScriptFunctionEvalValue.hpp b/src/Evaluator/EvalValues/ScriptFunctionEvalValue.hpp index 4243db3..46e8100 100644 --- a/src/Evaluator/EvalValues/ScriptFunctionEvalValue.hpp +++ b/src/Evaluator/EvalValues/ScriptFunctionEvalValue.hpp @@ -42,15 +42,15 @@ namespace Porygon::Evaluation { protected: const shared_ptr _type; const size_t _hash; - vector>* _options; + shared_ptr>> _options; + GenericFunctionEvalValue(shared_ptr type, size_t hash, + shared_ptr>> options) + :_type(std::move(type)), _hash(hash), _options(std::move(options)) + {} public: GenericFunctionEvalValue(shared_ptr type, size_t hash) : _type(move(type)), - _hash(hash), _options(new vector>()){ - } - - ~GenericFunctionEvalValue() final{ - delete _options; + _hash(hash), _options(make_shared>>()){ } GenericFunctionEvalValue(const GenericFunctionEvalValue& _) = delete; @@ -58,19 +58,16 @@ namespace Porygon::Evaluation { GenericFunctionEvalValue& operator =(GenericFunctionEvalValue v) = delete; [[nodiscard]] - shared_ptr Clone() const final { - auto t = make_shared(_type, _hash); - for (const auto& o: *_options){ - t->_options->push_back(o); - } - return t; + EvalValue* Clone() const final { + return new GenericFunctionEvalValue(_type, _hash, _options); } inline void RegisterOption(GenericFunctionOption* option) const{ _options->push_back(shared_ptr(option)); } - inline std::shared_ptr GetType() const { + [[nodiscard]] + inline std::shared_ptr GetType() const { return _type; } diff --git a/src/Evaluator/EvalValues/StringEvalValue.hpp b/src/Evaluator/EvalValues/StringEvalValue.hpp index fc405a9..77857e9 100644 --- a/src/Evaluator/EvalValues/StringEvalValue.hpp +++ b/src/Evaluator/EvalValues/StringEvalValue.hpp @@ -34,20 +34,31 @@ namespace Porygon::Evaluation { } [[nodiscard]] - inline shared_ptr Clone() const final { - return make_shared(_value); + inline EvalValue* Clone() const final { + return new StringEvalValue(_value); } - shared_ptr IndexValue(const EvalValue *val) const final { + EvalValue* IndexValue(const EvalValue *val) const final { // Porygon is 1-indexed, so we convert to that. auto l = val->EvaluateInteger() - 1; - return make_shared(u16string(1, _value[l])); + return new StringEvalValue(u16string(1, _value[l])); } [[nodiscard]] inline std::size_t GetHashCode() const final { 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 stringStream; + stringStream << _value; + stringStream << b->EvaluateString(); + return new StringEvalValue(stringStream.str()); + } }; } diff --git a/src/Evaluator/EvalValues/TableEvalValue.hpp b/src/Evaluator/EvalValues/TableEvalValue.hpp index bb382df..7eda4d1 100644 --- a/src/Evaluator/EvalValues/TableEvalValue.hpp +++ b/src/Evaluator/EvalValues/TableEvalValue.hpp @@ -5,22 +5,23 @@ #include #include "EvalValue.hpp" #include "../../Utilities/Random.hpp" +#include "../EvalValuePointer.hpp" using namespace std; namespace Porygon::Evaluation { class TableEvalValue : public EvalValue { - const shared_ptr>> _table; + const shared_ptr> _table; const size_t _hash; - explicit TableEvalValue(shared_ptr>> table, size_t hash) + explicit TableEvalValue(shared_ptr> table, size_t hash) : _table(std::move(table)), _hash(hash) { } public: - explicit TableEvalValue(shared_ptr>> table) : + explicit TableEvalValue(shared_ptr> table) : _table(std::move(table)), _hash(Utilities::Random::Get()) { @@ -42,41 +43,41 @@ namespace Porygon::Evaluation { } [[nodiscard]] - inline shared_ptr Clone() const final { - return shared_ptr(new TableEvalValue(_table, _hash)); + inline EvalValue* Clone() const final { + return new TableEvalValue(_table, _hash); } [[nodiscard]] - inline shared_ptr IndexValue(const EvalValue *val) const final { + inline EvalValue* IndexValue(const EvalValue *val) const final { const auto stringKey = val->EvaluateString(); - return this->_table->at(Utilities::HashedString::CreateLookup(stringKey)); + return this->_table->at(Utilities::HashedString::CreateLookup(stringKey))->Clone(); } [[nodiscard]] - inline shared_ptr IndexValue(uint32_t hash) const final { - return this->_table->at(Utilities::HashedString::CreateLookup(hash)); + inline EvalValue* IndexValue(uint32_t hash) const final { + return this->_table->at(Utilities::HashedString::CreateLookup(hash))->Clone(); } [[nodiscard]] - inline shared_ptr IndexValue(const char *val) const { + inline const EvalValue* IndexValue(const char *val) const { 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 &value) const final { + inline void SetIndexValue(const EvalValue *key, const EvalValue* value) const final { auto hash = key->GetHashCode(); - this->_table->at(Utilities::HashedString::CreateLookup(hash)) = value; + this->_table->at(Utilities::HashedString::CreateLookup(hash)).ClearAssign(value); } [[nodiscard]] Iterator * GetKeyIterator() const final; [[nodiscard]] - inline _Rb_tree_const_iterator>> GetTableIterator() const{ + inline _Rb_tree_const_iterator> GetTableIterator() const{ return _table->cbegin(); }; [[nodiscard]] - inline _Rb_tree_const_iterator>> GetTableIteratorEnd() const{ + inline _Rb_tree_const_iterator> GetTableIteratorEnd() const{ return _table->cend(); }; }; diff --git a/src/Evaluator/EvaluationScope/EvaluationScope.cpp b/src/Evaluator/EvaluationScope/EvaluationScope.cpp index 78a5f2a..333c46c 100644 --- a/src/Evaluator/EvaluationScope/EvaluationScope.cpp +++ b/src/Evaluator/EvaluationScope/EvaluationScope.cpp @@ -4,38 +4,39 @@ #include namespace Porygon::Evaluation { - EvaluationScope::EvaluationScope(map> *scriptVariables) + EvaluationScope::EvaluationScope(map *scriptVariables) : _scriptScope(scriptVariables), - _localScope(map>()) { + _localScope(map()) { } - void EvaluationScope::CreateVariable(const BoundVariableKey *key, const shared_ptr& value) { + void EvaluationScope::CreateVariable(const BoundVariableKey *key, EvalValuePointer value) { if (key->GetScopeId() == 0) { - _scriptScope->at(*key->GetIdentifier()) = value; + _scriptScope->at(*key->GetIdentifier()).ClearAssign(value.Take()); } else { - auto insert = _localScope.insert({key->GetHash(), value}); + auto val = value.Clone(); + auto insert = _localScope.insert({key->GetHash(), val}); if (!insert.second) { - _localScope[key->GetHash()] = value; + _localScope[key->GetHash()].ClearAssign(value.Take()); } } } - void EvaluationScope::SetVariable(const BoundVariableKey *key, const shared_ptr &value) { + void EvaluationScope::SetVariable(const BoundVariableKey *key, EvalValuePointer value) { if (key->GetScopeId() == 0) { - _scriptScope->at(*key->GetIdentifier()) = value; + _scriptScope->at(*key->GetIdentifier()).ClearAssign(value.Take()); } else { - _localScope[key->GetHash()] = value; + _localScope[key->GetHash()].ClearAssign(value.Take()); } } - shared_ptr EvaluationScope::GetVariable(const BoundVariableKey *key) { + EvalValuePointer EvaluationScope::GetVariable(const BoundVariableKey *key) { auto scopeId = key -> GetScopeId(); if (scopeId== 0) { - return _scriptScope->at(*key->GetIdentifier()); + return _scriptScope->at(*key->GetIdentifier())->Clone(); } else if(scopeId == -2){ - return StandardLibraries::StaticScope::GetVariable(*key->GetIdentifier()); + return StandardLibraries::StaticScope::GetVariable(*key->GetIdentifier()).Clone(); } else { - return _localScope[key->GetHash()]; + return _localScope[key->GetHash()]->Clone(); } } } \ No newline at end of file diff --git a/src/Evaluator/EvaluationScope/EvaluationScope.hpp b/src/Evaluator/EvaluationScope/EvaluationScope.hpp index 6001684..5ab2a7b 100644 --- a/src/Evaluator/EvaluationScope/EvaluationScope.hpp +++ b/src/Evaluator/EvaluationScope/EvaluationScope.hpp @@ -5,22 +5,26 @@ #include #include #include "../EvalValues/EvalValue.hpp" +#include "../EvalValuePointer.hpp" + using namespace Porygon::Binder; namespace Porygon::Evaluation { class EvaluationScope { - map> *_scriptScope; - map> _localScope; + map *_scriptScope; + map _localScope; public: - explicit EvaluationScope(map> *scriptVariables); + explicit EvaluationScope(map *scriptVariables); - ~EvaluationScope() = default; + ~EvaluationScope(){ + _localScope.clear(); + }; - void CreateVariable(const BoundVariableKey *key, const shared_ptr&value); + void CreateVariable(const BoundVariableKey *key, EvalValuePointer value); - void SetVariable(const BoundVariableKey *key, const shared_ptr &value); + void SetVariable(const BoundVariableKey *key, EvalValuePointer value); - shared_ptr GetVariable(const BoundVariableKey *key); + EvalValuePointer GetVariable(const BoundVariableKey *key); }; } diff --git a/src/Evaluator/Evaluator.cpp b/src/Evaluator/Evaluator.cpp index 9839323..105082b 100644 --- a/src/Evaluator/Evaluator.cpp +++ b/src/Evaluator/Evaluator.cpp @@ -15,15 +15,18 @@ using namespace std; using namespace Porygon::Binder; namespace Porygon::Evaluation { - shared_ptr Evaluator::Evaluate(const BoundScriptStatement *statement) { + const EvalValue* Evaluator::Evaluate(const BoundScriptStatement *statement) { this->_evaluationScope = make_shared(this->_scriptVariables); auto statements = statement->GetStatements(); if (statements -> size() == 1 && statements->at(0)->GetKind() == BoundStatementKind::Expression){ auto expStatement = (BoundExpressionStatement*) statements -> at(0); - return this -> EvaluateExpression(expStatement -> GetExpression()); + return this -> EvaluateExpression(expStatement -> GetExpression()).Clone(); } EvaluateBlockStatement(statement); - return this->_returnValue; + if (this->_returnValue.Get() == nullptr){ + return nullptr; + } + return this->_returnValue.Clone(); } void Evaluator::EvaluateStatement(const BoundStatement *statement) { @@ -78,9 +81,9 @@ namespace Porygon::Evaluation { auto value = this->EvaluateExpression(statement->GetExpression()); auto key = statement->GetKey(); if (key->IsCreation()) { - this->_evaluationScope->CreateVariable(key, value); + this->_evaluationScope->CreateVariable(key, value.Clone()); } else { - this->_evaluationScope->SetVariable(key, value); + this->_evaluationScope->SetVariable(key, value.Clone()); } } @@ -90,7 +93,7 @@ namespace Porygon::Evaluation { auto index = ((BoundIndexExpression *) indexExpression); auto table = this->EvaluateExpression(index->GetIndexableExpression()); auto key = this->EvaluateExpression(index->GetIndexExpression()); - table->SetIndexValue(key.get(), value); + table->SetIndexValue(key.Get(), value.Take()); } void Evaluator::EvaluateFunctionDeclarationStatement(const BoundFunctionDeclarationStatement *statement) { @@ -100,13 +103,14 @@ namespace Porygon::Evaluation { auto option = new Evaluation::EvaluationScriptFunctionOption(block, this->_evaluationScope); if (key->IsCreation()) { - auto value = make_shared(type, Utilities::Random::Get()); - value->RegisterOption(option); + auto p = new GenericFunctionEvalValue(type, Utilities::Random::Get()); + p->RegisterOption(option); + auto value = EvalValuePointer(p); this->_evaluationScope->CreateVariable(key, value); } else { - auto var = dynamic_pointer_cast(this -> _evaluationScope ->GetVariable(key)); + auto var = (GenericFunctionEvalValue*)this -> _evaluationScope ->GetVariable(key).Get(); var->RegisterOption(option); - this->_evaluationScope->SetVariable(key, var); + //this->_evaluationScope->SetVariable(key, var); } } @@ -114,17 +118,17 @@ namespace Porygon::Evaluation { auto expression = statement->GetExpression(); if (expression == nullptr) { this->_hasReturned = true; - this -> _returnValue = nullptr; + this -> _returnValue.ClearAssign(nullptr); return; } - auto value = this->EvaluateExpression(expression); + auto value = this->EvaluateExpression(expression).Take(); this->_hasReturned = true; - this->_returnValue = value; + this->_returnValue.ClearAssign(value); } void Evaluator::EvaluateConditionalStatement(const BoundConditionalStatement *statement) { auto condition = statement->GetCondition(); - if (EvaluateBoolExpression(condition)->EvaluateBool()) { + if (EvaluateExpression(condition)->EvaluateBool()) { this->EvaluateStatement(statement->GetBlock()); } else { auto elseStatement = statement->GetElseStatement(); @@ -135,12 +139,12 @@ namespace Porygon::Evaluation { } void Evaluator::EvaluateNumericalForStatement(const BoundNumericalForStatement *statement) { - long start = this->EvaluateIntegerExpression(statement -> GetStart()) -> EvaluateInteger(); - long end = this->EvaluateIntegerExpression(statement -> GetEnd()) -> EvaluateInteger(); + long start = this->EvaluateExpression(statement -> GetStart()) -> EvaluateInteger(); + long end = this->EvaluateExpression(statement -> GetEnd()) -> EvaluateInteger(); long step = 1; auto stepExp = statement -> GetStep(); if (stepExp != nullptr){ - step = this -> EvaluateIntegerExpression(stepExp) -> EvaluateInteger(); + step = this -> EvaluateExpression(stepExp) -> EvaluateInteger(); } auto identifier = statement -> GetIdentifier(); this -> _evaluationScope -> CreateVariable(identifier, nullptr); @@ -148,7 +152,7 @@ namespace Porygon::Evaluation { auto statements = *block -> GetStatements(); if (step >= 0){ for (long i = start; i <= end; i += step){ - this -> _evaluationScope -> SetVariable(identifier, make_shared(i)); + this -> _evaluationScope -> SetVariable(identifier, new IntegerEvalValue(i)); for (auto s: statements) { this->EvaluateStatement(s); if (this->_hasReturned || this -> _hasBroken) @@ -159,7 +163,7 @@ namespace Porygon::Evaluation { } } else{ for (long i = start; i >= end; i += step){ - this -> _evaluationScope -> SetVariable(identifier, make_shared(i)); + this -> _evaluationScope -> SetVariable(identifier, new IntegerEvalValue(i)); for (auto s: statements) { this->EvaluateStatement(s); if (this->_hasReturned || this -> _hasBroken) @@ -184,10 +188,10 @@ namespace Porygon::Evaluation { auto block = (BoundBlockStatement*)statement -> GetBlock(); auto statements = *block -> GetStatements(); while (iterator->MoveNext()){ - auto currentKey = iterator->GetCurrent(); + auto currentKey = EvalValuePointer(iterator->GetCurrent()); this -> _evaluationScope -> SetVariable(keyVariable, currentKey); if (valueVariable != nullptr){ - auto currentValue = iteratorVal -> IndexValue(currentKey.get()); + auto currentValue = EvalValuePointer(iteratorVal -> IndexValue(currentKey.Get())); this -> _evaluationScope -> SetVariable(valueVariable, currentValue); } for (auto s: statements) { @@ -206,7 +210,7 @@ namespace Porygon::Evaluation { auto condition = statement -> GetCondition(); auto block = (BoundBlockStatement*)statement -> GetBlock(); auto statements = *block -> GetStatements(); - while (this->EvaluateBoolExpression(condition)->EvaluateBool()){ + while (this->EvaluateExpression(condition)->EvaluateBool()){ for (auto s: statements) { this->EvaluateStatement(s); if (this->_hasReturned || this -> _hasBroken) @@ -222,161 +226,75 @@ namespace Porygon::Evaluation { // Expressions // ///////////////// - shared_ptr 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; - } - } + EvalValuePointer Evaluator::EvaluateExpression(const BoundExpression *expression) { + switch (expression->GetKind()){ - shared_ptr 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 Evaluator::EvaluateIntegerExpression(const BoundExpression *expression) { - switch (expression->GetKind()) { + case BoundExpressionKind::Bad: throw; case BoundExpressionKind::LiteralInteger: - return make_shared(((BoundLiteralIntegerExpression *) expression)->GetValue()); + return new IntegerEvalValue(((BoundLiteralIntegerExpression *) expression)->GetValue()); case BoundExpressionKind::LiteralFloat: - return make_shared(((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( - this->GetVariable((BoundVariableExpression *) expression)); - case BoundExpressionKind::FunctionCall: - return dynamic_pointer_cast(this->EvaluateFunctionCallExpression(expression)); - case BoundExpressionKind::Index: - return dynamic_pointer_cast(this->EvaluateIndexExpression(expression)); - case BoundExpressionKind::PeriodIndex: - return dynamic_pointer_cast(this->EvaluatePeriodIndexExpression(expression)); - - default: - throw; - } - } - - shared_ptr Evaluator::EvaluateBoolExpression(const BoundExpression *expression) { - switch (expression->GetKind()) { - case BoundExpressionKind::LiteralBool: - return make_shared(((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( - this->GetVariable((BoundVariableExpression *) expression)); - case BoundExpressionKind::FunctionCall: - return dynamic_pointer_cast(this->EvaluateFunctionCallExpression(expression)); - case BoundExpressionKind::Index: - return dynamic_pointer_cast(this->EvaluateIndexExpression(expression)); - case BoundExpressionKind::PeriodIndex: - return dynamic_pointer_cast(this->EvaluatePeriodIndexExpression(expression)); - - default: - throw; - - } - } - - shared_ptr Evaluator::EvaluateStringExpression(const BoundExpression *expression) { - switch (expression->GetKind()) { + return new FloatEvalValue(((BoundLiteralFloatExpression *) expression)->GetValue()); case BoundExpressionKind::LiteralString: - return make_shared(*((BoundLiteralStringExpression *) expression)->GetValue()); + return new StringEvalValue(*((BoundLiteralStringExpression *) expression)->GetValue()); + case BoundExpressionKind::LiteralBool: + return new BooleanEvalValue(((BoundLiteralBoolExpression *) expression)->GetValue()); + case BoundExpressionKind::Variable: + return this -> GetVariable((BoundVariableExpression*)expression); + case BoundExpressionKind::Unary: + return this->EvaluateUnary((BoundUnaryExpression *) expression); case BoundExpressionKind::Binary: - return this->EvaluateStringBinary((BoundBinaryExpression *) expression); - case BoundExpressionKind::Variable: - return dynamic_pointer_cast(this->GetVariable((BoundVariableExpression *) expression)); + return this->EvaluateBinary((BoundBinaryExpression *) expression); case BoundExpressionKind::FunctionCall: - return dynamic_pointer_cast(this->EvaluateFunctionCallExpression(expression)); + return this->EvaluateFunctionCallExpression(expression); case BoundExpressionKind::Index: - return dynamic_pointer_cast(this->EvaluateIndexExpression(expression)); - case BoundExpressionKind::PeriodIndex: - return dynamic_pointer_cast(this->EvaluatePeriodIndexExpression(expression)); - - default: - throw; - - } - } - - shared_ptr Evaluator::EvaluateFunctionExpression(const BoundExpression *expression) { - switch (expression->GetKind()) { - case BoundExpressionKind::Variable: - return this->GetVariable((BoundVariableExpression *) expression); - case BoundExpressionKind::Index: - return this->EvaluateIndexExpression(expression); + return this->EvaluateIndexExpression(expression).Take(); case BoundExpressionKind::PeriodIndex: return this->EvaluatePeriodIndexExpression(expression); - default: - throw; - } - } - - shared_ptr Evaluator::EvaluateNilExpression(const BoundExpression *expression) { - switch (expression->GetKind()) { - case BoundExpressionKind::FunctionCall: - return this->EvaluateFunctionCallExpression(expression); - default: - return nullptr; - } - } - - shared_ptr 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: return this->EvaluateNumericTableExpression(expression); case BoundExpressionKind::Table: 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 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 function = dynamic_pointer_cast( - this->EvaluateExpression(functionCall->GetFunctionExpression())); + auto function = (GenericFunctionEvalValue*)this->EvaluateExpression(functionCall->GetFunctionExpression()).Clone(); auto boundParameters = functionCall->GetParameters(); - auto parameters = vector>(boundParameters->size()); + auto parameters = vector(boundParameters->size()); for (size_t i = 0; i < boundParameters->size(); i++) { parameters[i] = this->EvaluateExpression(boundParameters->at(i)); } auto type = std::dynamic_pointer_cast(function->GetType()); - auto func = dynamic_pointer_cast(function); + auto func = function; auto option = functionCall ->GetFunctionOption(); auto opt = func->GetOption(option->GetOptionId()); if (option -> IsScriptFunction()){ @@ -390,28 +308,30 @@ namespace Porygon::Evaluation { for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++) { auto parameter = parameters[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->_evaluationScope = originalScope; this->_hasReturned = false; auto r = this->_returnValue; - this->_returnValue = nullptr; + this->_returnValue.ClearAssign(nullptr); + delete function; return r; } else{ auto scriptOption = dynamic_pointer_cast(opt); const EvalValue* arr[parameters.size()]; for (size_t i = 0; i < parameters.size(); i++){ - arr[i] = parameters[i].get(); + arr[i] = parameters[i].Get(); } - return shared_ptr(scriptOption -> Call(arr, parameters.size())); + delete function; + return scriptOption -> Call(arr, parameters.size()); } } - shared_ptr Evaluator::EvaluateFunction(const GenericFunctionEvalValue *function, + const EvalValue* Evaluator::EvaluateFunction(const GenericFunctionEvalValue *function, const vector ¶meters) { - auto type = std::dynamic_pointer_cast(function->GetType()); + auto type = function->GetType(); auto option = dynamic_cast(type->GetFirstOption()); auto parameterTypes = option->GetParameterTypes(); @@ -429,42 +349,43 @@ namespace Porygon::Evaluation { this->EvaluateBlockStatement(scriptOption->GetInnerBlock().get()); this->_evaluationScope = originalScope; this->_hasReturned = false; - auto r = this->_returnValue; - this->_returnValue = nullptr; + auto r = this->_returnValue.Take(); + delete function; return r; } - shared_ptr Evaluator::EvaluateIndexExpression(const BoundExpression *expression) { + EvalValuePointer Evaluator::EvaluateIndexExpression(const BoundExpression *expression) { auto indexExpression = (BoundIndexExpression *) expression; auto index = this->EvaluateExpression(indexExpression->GetIndexExpression()); auto indexable = this->EvaluateExpression(indexExpression->GetIndexableExpression()); - return indexable->IndexValue(index.get()); + return indexable->IndexValue(index.Get()); } - shared_ptr Evaluator::EvaluatePeriodIndexExpression(const BoundExpression *expression) { + EvalValuePointer Evaluator::EvaluatePeriodIndexExpression(const BoundExpression *expression) { auto indexExpression = (BoundPeriodIndexExpression *) expression; auto index = indexExpression->GetIndex()->GetHash(); auto indexable = this->EvaluateExpression(indexExpression->GetIndexableExpression()); - return indexable->IndexValue(index)->Clone(); + return indexable->IndexValue(index); } - shared_ptr Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) { + EvalValuePointer Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) { auto tableExpression = (BoundNumericalTableExpression *) expression; auto valueExpressions = tableExpression->GetExpressions(); - auto values = new vector>(valueExpressions->size()); + auto values = new vector(valueExpressions->size()); for (size_t i = 0; i < valueExpressions->size(); i++) { auto val = this->EvaluateExpression(valueExpressions->at(i)); - values->at(i) = val; + values->at(i) = val.Take(); } - auto valuesPointer = shared_ptr>>(values); - return make_shared(valuesPointer); + auto valuesPointer = shared_ptr>(values); + return new NumericalTableEvalValue(valuesPointer); } - shared_ptr Evaluator::EvaluateComplexTableExpression(const BoundExpression *expression) { + EvalValuePointer Evaluator::EvaluateComplexTableExpression(const BoundExpression *expression) { auto tableExpression = (BoundTableExpression *) expression; - auto type = dynamic_pointer_cast(tableExpression->GetType()); + const auto& baseType = tableExpression -> GetType(); + auto type = dynamic_pointer_cast(baseType); auto declaredVars = type->GetValues(); - auto variables = make_shared>>(); + auto variables = make_shared>(); for (const auto& i : *declaredVars) { variables->insert({i.first, nullptr}); } @@ -473,17 +394,6 @@ namespace Porygon::Evaluation { this->_evaluationScope = evaluator; this->EvaluateBlockStatement(tableExpression->GetBlock()); this->_evaluationScope = currentEvaluator; - return make_shared(variables); - } - - shared_ptr 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; - } + return new TableEvalValue(variables); } } \ No newline at end of file diff --git a/src/Evaluator/Evaluator.hpp b/src/Evaluator/Evaluator.hpp index 6da99b5..045573d 100644 --- a/src/Evaluator/Evaluator.hpp +++ b/src/Evaluator/Evaluator.hpp @@ -10,13 +10,14 @@ #include "EvalValues/StringEvalValue.hpp" #include "EvalValues/ScriptFunctionEvalValue.hpp" #include "EvaluationScope/EvaluationScope.hpp" +#include "EvalValuePointer.hpp" using namespace std; namespace Porygon::Evaluation{ class Evaluator { - shared_ptr _returnValue; - map>* _scriptVariables; + EvalValuePointer _returnValue; + map* _scriptVariables; bool _hasReturned; bool _hasBroken; @@ -35,36 +36,25 @@ namespace Porygon::Evaluation{ void EvaluateGenericForStatement(const BoundGenericForStatement *statement); void EvaluateWhileStatement(const BoundWhileStatement *statement); - shared_ptr EvaluateExpression(const BoundExpression *expression); - shared_ptr EvaluateIntegerExpression(const BoundExpression *expression); - shared_ptr EvaluateBoolExpression(const BoundExpression *expression); - shared_ptr EvaluateStringExpression(const BoundExpression *expression); - shared_ptr EvaluateFunctionExpression(const BoundExpression *expression); - shared_ptr EvaluateNilExpression(const BoundExpression *expression); - shared_ptr EvaluateTableExpression(const BoundExpression *expression); + EvalValuePointer EvaluateExpression(const BoundExpression *expression); + EvalValuePointer EvaluateBinary(const BoundBinaryExpression *expression); + EvalValuePointer EvaluateUnary(const BoundUnaryExpression *expression); - shared_ptr EvaluateIntegerBinary(const BoundBinaryExpression *expression); - shared_ptr EvaluateBooleanBinary(const BoundBinaryExpression *expression); - shared_ptr EvaluateStringBinary(const BoundBinaryExpression *expression); + EvalValuePointer EvaluateFunctionCallExpression(const BoundExpression *expression); + EvalValuePointer EvaluateIndexExpression(const BoundExpression *expression); + EvalValuePointer EvaluatePeriodIndexExpression(const BoundExpression *expression); + EvalValuePointer EvaluateNumericTableExpression(const BoundExpression *expression); + EvalValuePointer EvaluateComplexTableExpression(const BoundExpression *expression); - shared_ptr EvaluateIntegerUnary(const BoundUnaryExpression *expression); - shared_ptr EvaluateBooleanUnary(const BoundUnaryExpression *expression); - shared_ptr EvaluateFunctionCallExpression(const BoundExpression *expression); - shared_ptr EvaluateIndexExpression(const BoundExpression *expression); - shared_ptr EvaluatePeriodIndexExpression(const BoundExpression *expression); - shared_ptr EvaluateNumericTableExpression(const BoundExpression *expression); - shared_ptr EvaluateUserDataExpression(const BoundExpression *expression); - shared_ptr EvaluateComplexTableExpression(const BoundExpression *expression); - - shared_ptr GetVariable(const BoundVariableExpression *expression); + EvalValuePointer GetVariable(const BoundVariableExpression *expression); public: - explicit Evaluator(map>* scriptVariables) + explicit Evaluator(map* scriptVariables) : _scriptVariables(scriptVariables), _hasReturned(false), _hasBroken(false), _returnValue(nullptr), _evaluationScope(nullptr){ } - shared_ptr Evaluate(const BoundScriptStatement* statement); - shared_ptr EvaluateFunction(const GenericFunctionEvalValue *function, + const EvalValue* Evaluate(const BoundScriptStatement* statement); + const EvalValue* EvaluateFunction(const GenericFunctionEvalValue *function, const vector ¶meters); }; diff --git a/src/Evaluator/Iterator/Iterator.hpp b/src/Evaluator/Iterator/Iterator.hpp index 3016f4a..ff32dbd 100644 --- a/src/Evaluator/Iterator/Iterator.hpp +++ b/src/Evaluator/Iterator/Iterator.hpp @@ -10,7 +10,7 @@ using namespace std; namespace Porygon::Evaluation{ class Iterator { public: - virtual shared_ptr GetCurrent() = 0; + virtual EvalValue* GetCurrent() = 0; virtual bool MoveNext() = 0; virtual void Reset() = 0; virtual ~Iterator(){} diff --git a/src/Evaluator/Iterator/NumericalKeyIterator.hpp b/src/Evaluator/Iterator/NumericalKeyIterator.hpp index db8d18d..ca95f8b 100644 --- a/src/Evaluator/Iterator/NumericalKeyIterator.hpp +++ b/src/Evaluator/Iterator/NumericalKeyIterator.hpp @@ -9,15 +9,15 @@ namespace Porygon::Evaluation{ class NumericalKeyIterator : public Iterator{ - const shared_ptr>> _vec; + const shared_ptr> _vec; const size_t _size; long _position = 0; public: explicit NumericalKeyIterator(const NumericalTableEvalValue* table) : _vec(table->GetTable()), _size(_vec->size() + 1){} - inline shared_ptr GetCurrent() final{ - return make_shared(_position); + inline EvalValue* GetCurrent() final{ + return new IntegerEvalValue(_position); } inline bool MoveNext() final{ diff --git a/src/Evaluator/Iterator/SimpleKeyIterator.hpp b/src/Evaluator/Iterator/SimpleKeyIterator.hpp index 5641ca0..d8208f1 100644 --- a/src/Evaluator/Iterator/SimpleKeyIterator.hpp +++ b/src/Evaluator/Iterator/SimpleKeyIterator.hpp @@ -8,15 +8,15 @@ namespace Porygon::Evaluation{ class TableKeyIterator : public Iterator{ - _Rb_tree_const_iterator>> _iterator; - _Rb_tree_const_iterator>> _end; + _Rb_tree_const_iterator> _iterator; + _Rb_tree_const_iterator> _end; bool _hasStarted = false; public: explicit TableKeyIterator(const TableEvalValue* table) : _iterator(table->GetTableIterator()), _end(table->GetTableIteratorEnd()){} - inline shared_ptr GetCurrent() final{ - return make_shared(*_iterator->first.GetString()); + inline EvalValue* GetCurrent() final{ + return new StringEvalValue(*_iterator->first.GetString()); } bool MoveNext() final{ diff --git a/src/Evaluator/UnaryEvaluation.cpp b/src/Evaluator/UnaryEvaluation.cpp deleted file mode 100644 index aba38d8..0000000 --- a/src/Evaluator/UnaryEvaluation.cpp +++ /dev/null @@ -1,36 +0,0 @@ - -#include "EvalValues/NumericEvalValue.hpp" -#include "Evaluator.hpp" -#include "EvaluationException.hpp" -#include "../Script.hpp" - -namespace Porygon::Evaluation { - shared_ptr 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(-f); - } else { - long l = operandValue->EvaluateInteger(); - return make_shared(-l); - } - } - default: - throw; - } - } - - shared_ptr Evaluator::EvaluateBooleanUnary(const BoundUnaryExpression *expression) { - switch (expression->GetOperation()) { - case BoundUnaryOperation::LogicalNegation: { - auto val = EvaluateBoolExpression(expression->GetOperand()); - bool b = val->EvaluateBool(); - return make_shared(!b); - } - default: - throw; - } - } -} diff --git a/src/Script.cpp b/src/Script.cpp index 8516500..3b05707 100644 --- a/src/Script.cpp +++ b/src/Script.cpp @@ -24,13 +24,13 @@ Porygon::Script *Porygon::Script::Create(const string &script) { Porygon::Script::Script(const u16string& s) : Diagnostics(make_shared(s)), _boundScript(nullptr), - _scriptVariables(new map>()) + _scriptVariables(new map()) { _evaluator = new Evaluator(this -> _scriptVariables); this -> Parse(s); } -shared_ptr Porygon::Script::Evaluate() { +EvalValuePointer Porygon::Script::Evaluate() { return _evaluator->Evaluate(_boundScript.get()); } @@ -62,8 +62,8 @@ void Porygon::Script::Parse(const u16string& script) { delete parseResult; } -const EvalValue *Porygon::Script::GetVariable(const u16string &key) { - return _scriptVariables -> at(HashedString::CreateLookup(key)).get(); +const EvalValue* Porygon::Script::GetVariable(const u16string &key) { + return _scriptVariables -> at(HashedString::CreateLookup(key)).Clone(); } 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; } -shared_ptr Porygon::Script::CallFunction(const u16string &key, const vector& variables) { +const EvalValue* Porygon::Script::CallFunction(const u16string &key, const vector& variables) { auto var = (GenericFunctionEvalValue*)GetVariable(key); return this->_evaluator->EvaluateFunction(var, variables); } @@ -98,7 +98,7 @@ Porygon::Script::Script(shared_ptr boundScript, shared_ptr diagnostics) : _boundScript(std::move(boundScript)), Diagnostics(std::move(diagnostics)), - _scriptVariables(new map>()) + _scriptVariables(new map()) { _evaluator = new Evaluator(_scriptVariables); } @@ -111,8 +111,7 @@ extern "C" { const EvalValue* EvaluateScript(Porygon::Script* script){ auto result = script -> Evaluate(); - auto resultPtr = result.get(); - return resultPtr; + return result.Clone(); } 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){ std::vector v(parameters, parameters + parameterCount); - return script->CallFunction(key, v).get(); + return script->CallFunction(key, v); } } \ No newline at end of file diff --git a/src/Script.hpp b/src/Script.hpp index 1b3685f..04f59a1 100644 --- a/src/Script.hpp +++ b/src/Script.hpp @@ -17,7 +17,7 @@ using namespace Porygon::Evaluation; namespace Porygon{ class Script { Evaluator* _evaluator; - map>* _scriptVariables; + map* _scriptVariables; shared_ptr _boundScript; shared_ptr _returnType; @@ -41,14 +41,12 @@ namespace Porygon{ _returnType = t; } - shared_ptr Evaluate(); - - //const EvalValue* GetLastValue(); + EvalValuePointer Evaluate(); const EvalValue* GetVariable(const u16string& key); bool HasVariable(const u16string& key); - shared_ptr CallFunction(const u16string& key, const vector& variables); + const EvalValue* CallFunction(const u16string& key, const vector& variables); bool HasFunction(const u16string& key); }; diff --git a/src/StandardLibraries/BasicLibrary.hpp b/src/StandardLibraries/BasicLibrary.hpp index 8705749..9d84a65 100644 --- a/src/StandardLibraries/BasicLibrary.hpp +++ b/src/StandardLibraries/BasicLibrary.hpp @@ -74,10 +74,10 @@ namespace Porygon::StandardLibraries{ } - static shared_ptr GetFuncEvalValue( - const Evaluation::EvalValue* (*func)(void* obj, const Evaluation::EvalValue* parameters[], int parameterCount), - const shared_ptr& type, size_t optionLength){ - auto f = make_shared(type, rand()); + static Evaluation::EvalValue* GetFuncEvalValue( + const Evaluation::EvalValue* (*func)(void* obj, const Evaluation::EvalValue* parameters[], int parameterCount), + const shared_ptr& type, size_t optionLength){ + auto f = new Evaluation::GenericFunctionEvalValue(type, rand()); for (size_t i = 0; i < optionLength; i++){ auto funcOption = new UserData::UserDataFunction(func, nullptr); f->RegisterOption(funcOption); @@ -88,7 +88,7 @@ namespace Porygon::StandardLibraries{ public: static void RegisterVariables(std::map* bound, - std::map>* values){ + std::map* values){ // Register error function auto errorFuncType = BasicLibrary::GetErrorFuncType(); auto errorLookup = Utilities::HashedString::CreateLookup(u"error"); diff --git a/src/StandardLibraries/StaticScope.hpp b/src/StandardLibraries/StaticScope.hpp index 64a276a..75cbd34 100644 --- a/src/StandardLibraries/StaticScope.hpp +++ b/src/StandardLibraries/StaticScope.hpp @@ -19,7 +19,7 @@ namespace Porygon::StandardLibraries{ class InternalScope{ public: map _boundVariables; - map> _variables; + map _variables; InternalScope(){ BasicLibrary::RegisterVariables(&_boundVariables, &_variables); @@ -29,6 +29,9 @@ namespace Porygon::StandardLibraries{ for (const auto& b: _boundVariables){ delete b.second; } + for (const auto& v: _variables){ + delete v.second; + } } }; @@ -36,7 +39,7 @@ namespace Porygon::StandardLibraries{ public: static void RegisterVariable(const Utilities::HashedString& identifier, shared_ptr type, Evaluation::EvalValue* value){ _internal._boundVariables.insert({identifier, new Binder::BoundVariable(std::move(type))}); - _internal._variables.insert({identifier, shared_ptr(value)}); + _internal._variables.insert({identifier, value}); } static Binder::BoundVariable* GetBoundVariable(const Utilities::HashedString &identifier){ @@ -47,8 +50,8 @@ namespace Porygon::StandardLibraries{ return nullptr; } - inline static shared_ptr GetVariable(const Utilities::HashedString &identifier){ - return _internal._variables[identifier]; + inline static Evaluation::EvalValuePointer GetVariable(const Utilities::HashedString &identifier){ + return _internal._variables[identifier]->Clone(); } }; } diff --git a/src/UserData/UserDataValue.hpp b/src/UserData/UserDataValue.hpp index e89b64b..5ac057b 100644 --- a/src/UserData/UserDataValue.hpp +++ b/src/UserData/UserDataValue.hpp @@ -34,8 +34,8 @@ namespace Porygon::UserData { } [[nodiscard]] - inline shared_ptr Clone() const final { - return make_shared(_userData, _obj); + inline Evaluation::EvalValue* Clone() const final { + return new UserDataValue(_userData, _obj); } [[nodiscard]] @@ -43,22 +43,23 @@ namespace Porygon::UserData { return reinterpret_cast(_obj); } - shared_ptr IndexValue(const EvalValue *val) const final { + const Evaluation::EvalValue* IndexValue(const EvalValue *val) const final { auto fieldId = val->GetHashCode(); auto field = _userData->GetField(fieldId); - return shared_ptr(field->Get(_obj)); + return field->Get(_obj); } [[nodiscard]] - inline shared_ptr IndexValue(uint32_t hash) const final { + inline const EvalValue* IndexValue(uint32_t hash) const final { auto field = _userData->GetField(hash); - return shared_ptr(field->Get(_obj)); + return field->Get(_obj); } - void SetIndexValue(const EvalValue *key, const shared_ptr &value) const final { + void SetIndexValue(const EvalValue *key, const EvalValue* value) const final { auto fieldId = key->GetHashCode(); auto field = _userData->GetField(fieldId); - field->Set(_obj, value.get()); + field->Set(_obj, value); + delete value; } inline void* GetObjectPointer(){ diff --git a/tests/integration/ConditionalTests.cpp b/tests/integration/ConditionalTests.cpp index 78846c6..15c3b12 100644 --- a/tests/integration/ConditionalTests.cpp +++ b/tests/integration/ConditionalTests.cpp @@ -14,6 +14,7 @@ TEST_CASE( "Basic conditional", "[integration]" ) { REQUIRE(variable != nullptr); REQUIRE(variable->EvaluateBool()); delete script; + delete variable; } TEST_CASE( "If then, else", "[integration]" ) { @@ -26,6 +27,7 @@ TEST_CASE( "If then, else", "[integration]" ) { REQUIRE(variable != nullptr); REQUIRE(variable->EvaluateBool()); delete script; + delete variable; } TEST_CASE( "If then, else if", "[integration]" ) { @@ -38,6 +40,7 @@ TEST_CASE( "If then, else if", "[integration]" ) { REQUIRE(variable != nullptr); REQUIRE(variable->EvaluateBool()); delete script; + delete variable; } diff --git a/tests/integration/FunctionsTests.cpp b/tests/integration/FunctionsTests.cpp index 60afdf2..385da70 100644 --- a/tests/integration/FunctionsTests.cpp +++ b/tests/integration/FunctionsTests.cpp @@ -12,6 +12,7 @@ TEST_CASE( "Define script function", "[integration]" ) { REQUIRE(variable != nullptr); REQUIRE(variable->GetTypeClass() == TypeClass::Function); delete script; + delete variable; } 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->EvaluateInteger() == 3); delete script; + delete variable; + delete result; } 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->EvaluateInteger() == 5); delete script; + delete variable; + delete result; } 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->EvaluateInteger() == 11); delete script; + delete result; } TEST_CASE( "Define script function and return", "[integration]" ) { @@ -84,6 +90,8 @@ TEST_CASE( "Define script function and return", "[integration]" ) { REQUIRE(variable->EvaluateInteger() == 0); delete script; + delete variable; + delete result; } TEST_CASE( "Functions can call themselves", "[integration]" ) { @@ -106,6 +114,7 @@ end REQUIRE(variable->EvaluateInteger() == 5); delete script; + delete variable; } TEST_CASE( "Functions respect scope", "[integration]" ) { @@ -134,6 +143,7 @@ test() REQUIRE(variable->EvaluateInteger() == 50); delete script; + delete variable; } TEST_CASE( "Return doesn't parse next line expression", "[integration]" ) { @@ -174,8 +184,9 @@ stringResult = add('foo', 'bar') REQUIRE(stringVar != nullptr); CHECK(stringVar->EvaluateString() == u"foobar"); - delete script; + delete intVar; + delete stringVar; } diff --git a/tests/integration/LoopTests.cpp b/tests/integration/LoopTests.cpp index a844bfb..8171ddc 100644 --- a/tests/integration/LoopTests.cpp +++ b/tests/integration/LoopTests.cpp @@ -15,6 +15,7 @@ end auto var = script->GetVariable(u"result"); REQUIRE(var->EvaluateInteger() == 33); delete script; + delete var; } TEST_CASE( "Numerical for loop with step", "[integration]" ) { @@ -29,6 +30,7 @@ end auto var = script->GetVariable(u"result"); REQUIRE(var->EvaluateInteger() == 12); delete script; + delete var; } TEST_CASE( "Numerical for loop with negative step", "[integration]" ) { @@ -43,6 +45,7 @@ end auto var = script->GetVariable(u"result"); REQUIRE(var->EvaluateInteger() == 33); delete script; + delete var; } @@ -58,6 +61,7 @@ end auto var = script->GetVariable(u"result"); REQUIRE(var->EvaluateInteger() == 15); delete script; + delete var; } TEST_CASE( "Numerical for loop, break", "[integration]" ) { @@ -73,6 +77,7 @@ end auto var = script->GetVariable(u"result"); REQUIRE(var->EvaluateInteger() == 6); delete script; + delete var; } @@ -89,6 +94,7 @@ end auto var = script->GetVariable(u"result"); REQUIRE(var->EvaluateInteger() == 15); delete script; + delete var; } TEST_CASE( "Generic for loop over simple numerical table, get values", "[integration]" ) { @@ -104,6 +110,7 @@ end auto var = script->GetVariable(u"result"); REQUIRE(var->EvaluateInteger() == 25); delete script; + delete var; } TEST_CASE( "Generic for loop over simple numerical table, break", "[integration]" ) { @@ -120,6 +127,7 @@ end auto var = script->GetVariable(u"result"); REQUIRE(var->EvaluateInteger() == 9); delete script; + delete var; } TEST_CASE( "While loop", "[integration]" ) { @@ -134,6 +142,7 @@ end auto var = script->GetVariable(u"result"); REQUIRE(var->EvaluateInteger() == 5); delete script; + delete var; } TEST_CASE( "While loop break", "[integration]" ) { @@ -149,6 +158,7 @@ end auto var = script->GetVariable(u"result"); REQUIRE(var->EvaluateInteger() == 5); delete script; + delete var; } #endif diff --git a/tests/integration/TablesTests.cpp b/tests/integration/TablesTests.cpp index 926099f..ad49ab3 100644 --- a/tests/integration/TablesTests.cpp +++ b/tests/integration/TablesTests.cpp @@ -11,6 +11,7 @@ TEST_CASE( "Create empty table", "[integration]" ) { auto variable = script->GetVariable(u"table"); REQUIRE(variable != nullptr); delete script; + delete variable; } TEST_CASE( "Create simple integer table", "[integration]" ) { @@ -20,6 +21,7 @@ TEST_CASE( "Create simple integer table", "[integration]" ) { auto variable = script->GetVariable(u"table"); REQUIRE(variable != nullptr); delete script; + delete variable; } TEST_CASE( "Create simple string table", "[integration]" ) { @@ -29,6 +31,7 @@ TEST_CASE( "Create simple string table", "[integration]" ) { auto variable = script->GetVariable(u"table"); REQUIRE(variable != nullptr); delete script; + delete variable; } TEST_CASE( "Index string table", "[integration]" ) { @@ -39,7 +42,7 @@ return table[3] )"); REQUIRE(!script->Diagnostics -> HasErrors()); auto variable = script->Evaluate(); - REQUIRE(variable != nullptr); + REQUIRE(variable.Get() != nullptr); REQUIRE(variable->EvaluateString() == u"foo"); delete script; } @@ -57,9 +60,14 @@ table = { auto variable = script->GetVariable(u"table"); REQUIRE(variable != nullptr); auto table = (TableEvalValue*)variable; - CHECK(table->IndexValue("foo")->EvaluateString() == u"test"); - CHECK(table->IndexValue("bar")->EvaluateInteger() == 100); + auto res = table->IndexValue("foo"); + auto res2 = table->IndexValue("bar"); + CHECK(res->EvaluateString() == u"test"); + CHECK(res2->EvaluateInteger() == 100); delete script; + delete table; + delete res; + delete res2; } TEST_CASE( "Complex table with function", "[integration]" ) { @@ -75,7 +83,7 @@ return table["getFoo"]() )"); REQUIRE(!script->Diagnostics -> HasErrors()); auto variable = script->Evaluate(); - REQUIRE(variable != nullptr); + REQUIRE(variable.Get() != nullptr); delete script; } diff --git a/tests/integration/UserDataTests.cpp b/tests/integration/UserDataTests.cpp index 5ea73d9..917c120 100644 --- a/tests/integration/UserDataTests.cpp +++ b/tests/integration/UserDataTests.cpp @@ -54,6 +54,7 @@ end delete par; delete parameter; delete script; + delete variable; UserDataStorage::ClearTypes(); } @@ -92,6 +93,7 @@ end delete script; delete obj; delete parameter; + delete result; UserDataStorage::ClearTypes(); } @@ -111,6 +113,7 @@ end delete script; delete obj; delete parameter; + delete result; UserDataStorage::ClearTypes(); } diff --git a/tests/integration/VariablesTests.cpp b/tests/integration/VariablesTests.cpp index ee67248..f40f0e7 100644 --- a/tests/integration/VariablesTests.cpp +++ b/tests/integration/VariablesTests.cpp @@ -13,6 +13,7 @@ TEST_CASE( "Create script variable", "[integration]" ) { REQUIRE(variable != nullptr); REQUIRE(variable->EvaluateBool()); delete script; + delete variable; } TEST_CASE( "Create local variable", "[integration]" ) { @@ -32,6 +33,7 @@ TEST_CASE( "Create script variable and use", "[integration]" ) { REQUIRE(variable != nullptr); CHECK(variable->EvaluateBool()); delete script; + delete variable; } TEST_CASE( "Create local variable and use", "[integration]" ) { @@ -43,6 +45,7 @@ TEST_CASE( "Create local variable and use", "[integration]" ) { REQUIRE(variable != nullptr); CHECK(variable->EvaluateBool()); delete script; + delete variable; } TEST_CASE( "Local variables in upmost scope persist", "[integration]" ) { @@ -62,6 +65,7 @@ end REQUIRE(variable != nullptr); CHECK(variable->EvaluateInteger() == 2); delete script; + delete variable; } TEST_CASE( "Able to use emoji", "[integration]" ) { @@ -75,6 +79,7 @@ TEST_CASE( "Able to use emoji", "[integration]" ) { REQUIRE(variable != nullptr); CHECK(variable->EvaluateString() == u"LJ"); delete script; + delete variable; } #endif