Implements initial math library, several reworks for Userdata memory management
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
13b382def2
commit
5e96250d96
|
@ -65,6 +65,13 @@ namespace Porygon {
|
||||||
this -> RegisterFunctionOption(option);
|
this -> RegisterFunctionOption(option);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
explicit GenericFunctionScriptType(const vector<GenericFunctionOption*>& options)
|
||||||
|
: ScriptType(Porygon::TypeClass::Function){
|
||||||
|
for (auto option: options){
|
||||||
|
this -> RegisterFunctionOption(option);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
~GenericFunctionScriptType() final{
|
~GenericFunctionScriptType() final{
|
||||||
for (auto o: *_options){
|
for (auto o: *_options){
|
||||||
delete o;
|
delete o;
|
||||||
|
@ -72,9 +79,10 @@ namespace Porygon {
|
||||||
delete _options;
|
delete _options;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterFunctionOption (GenericFunctionOption * opt) const{
|
const GenericFunctionScriptType* RegisterFunctionOption (GenericFunctionOption * opt) const{
|
||||||
opt->SetOption(_options->size());
|
opt->SetOption(_options->size());
|
||||||
_options->push_back(opt);
|
_options->push_back(opt);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericFunctionOption* GetFunctionOption(const vector<shared_ptr<const ScriptType>>& parameters) const{
|
GenericFunctionOption* GetFunctionOption(const vector<shared_ptr<const ScriptType>>& parameters) const{
|
||||||
|
|
|
@ -46,7 +46,8 @@ namespace Porygon::StandardLibraries{
|
||||||
throw Evaluation::EvaluationException(conv);
|
throw Evaluation::EvaluationException(conv);
|
||||||
}
|
}
|
||||||
static shared_ptr<GenericFunctionScriptType> GetErrorFuncType(){
|
static shared_ptr<GenericFunctionScriptType> GetErrorFuncType(){
|
||||||
return GetFuncType(make_shared<ScriptType>(TypeClass::Nil), {{make_shared<StringScriptType>(false, 0)}});
|
return GetFuncType(make_shared<ScriptType>(TypeClass::Nil),
|
||||||
|
{{make_shared<StringScriptType>(false, 0)}});
|
||||||
}
|
}
|
||||||
//endregion
|
//endregion
|
||||||
//region Print
|
//region Print
|
||||||
|
@ -206,7 +207,7 @@ namespace Porygon::StandardLibraries{
|
||||||
values->insert({typeLookup, typeFunc});
|
values->insert({typeLookup, typeFunc});
|
||||||
|
|
||||||
// Register IsFloat function
|
// Register IsFloat function
|
||||||
auto isFloatFuncType = BasicLibrary::GetTypeFuncType();
|
auto isFloatFuncType = BasicLibrary::GetIsFloatFuncType();
|
||||||
auto isFloatLookup = Utilities::HashedString::CreateLookup(u"isfloat");
|
auto isFloatLookup = Utilities::HashedString::CreateLookup(u"isfloat");
|
||||||
auto isFloatFunc = BasicLibrary::GetFuncEvalValue(_isFloat, isFloatFuncType, 1);
|
auto isFloatFunc = BasicLibrary::GetFuncEvalValue(_isFloat, isFloatFuncType, 1);
|
||||||
bound->insert({isFloatLookup, new Binder::BoundVariable(isFloatFuncType)});
|
bound->insert({isFloatLookup, new Binder::BoundVariable(isFloatFuncType)});
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
#ifndef PORYGONLANG_MATHLIBRARY_HPP
|
||||||
|
#define PORYGONLANG_MATHLIBRARY_HPP
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "../Evaluator/EvalValues/EvalValue.hpp"
|
||||||
|
#include "../Evaluator/EvalValues/NumericEvalValue.hpp"
|
||||||
|
|
||||||
|
#include "../UserData/UserDataScriptType.hpp"
|
||||||
|
#include "../ScriptTypes/FunctionScriptType.hpp"
|
||||||
|
#include "../ScriptTypes/ScriptType.hpp"
|
||||||
|
#include "../UserData/UserDataFunctionType.hpp"
|
||||||
|
#include "../Evaluator/EvalValues/ScriptFunctionEvalValue.hpp"
|
||||||
|
#include "../UserData/UserDataFunction.hpp"
|
||||||
|
#include "../Utilities/Random.hpp"
|
||||||
|
|
||||||
|
namespace Porygon::StandardLibraries {
|
||||||
|
using namespace Porygon::Evaluation;
|
||||||
|
using namespace Porygon::Utilities;
|
||||||
|
class MathLibrary {
|
||||||
|
|
||||||
|
//region templates
|
||||||
|
|
||||||
|
#define FLOAT_TYPE new NumericScriptType(true, true)
|
||||||
|
#define INTEGER_TYPE new NumericScriptType(true, false)
|
||||||
|
#define FUNCTION(fieldName) \
|
||||||
|
[](void* obj) -> const Porygon::Evaluation::EvalValue* { \
|
||||||
|
auto t = new Porygon::Evaluation::GenericFunctionEvalValue(make_shared<GenericFunctionScriptType>(), \
|
||||||
|
Porygon::Utilities::Random::Get()); \
|
||||||
|
t->RegisterOption(new Porygon::UserData::UserDataFunction(fieldName, nullptr)); \
|
||||||
|
return t;}, \
|
||||||
|
nullptr
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
static const EvalValue* _abs(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||||
|
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
|
||||||
|
if (parameter->IsFloat()){
|
||||||
|
return new FloatEvalValue(std::abs(parameter->EvaluateFloat()));
|
||||||
|
} else{
|
||||||
|
return new IntegerEvalValue(std::abs(parameter->EvaluateInteger()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static UserData::UserDataFunctionOption* CreateFunctionOption(ScriptType* returnType, std::vector<ScriptType*> params){
|
||||||
|
return UserData::UserDataFunctionOption::FromRawPointers(returnType, std::move(params));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
static UserData::UserData* CreateUserData(){
|
||||||
|
return new UserData::UserData({
|
||||||
|
{HashedString::ConstHash("abs"),
|
||||||
|
new UserData::UserDataField(
|
||||||
|
(new GenericFunctionScriptType())
|
||||||
|
->RegisterFunctionOption(CreateFunctionOption(INTEGER_TYPE, {INTEGER_TYPE}))
|
||||||
|
->RegisterFunctionOption(CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
|
||||||
|
, FUNCTION(_abs))}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //PORYGONLANG_MATHLIBRARY_HPP
|
|
@ -1,3 +1,3 @@
|
||||||
#include "StaticScope.hpp"
|
#include "StaticScope.hpp"
|
||||||
|
|
||||||
Porygon::StandardLibraries::StaticScope::InternalScope Porygon::StandardLibraries::StaticScope::_internal;
|
Porygon::StandardLibraries::StaticScope::InternalScope* Porygon::StandardLibraries::StaticScope::_internal = nullptr;
|
|
@ -1,13 +1,16 @@
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#ifndef PORYGONLANG_STATICSCOPE_HPP
|
#ifndef PORYGONLANG_STATICSCOPE_HPP
|
||||||
#define PORYGONLANG_STATICSCOPE_HPP
|
#define PORYGONLANG_STATICSCOPE_HPP
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
|
#include "BasicLibrary.hpp"
|
||||||
|
#include "MathLibrary.hpp"
|
||||||
#include "../Utilities/HashedString.hpp"
|
#include "../Utilities/HashedString.hpp"
|
||||||
#include "../Binder/BoundVariables/BoundVariable.hpp"
|
#include "../Binder/BoundVariables/BoundVariable.hpp"
|
||||||
#include "../Evaluator/EvalValues/EvalValue.hpp"
|
#include "../Evaluator/EvalValues/EvalValue.hpp"
|
||||||
#include "BasicLibrary.hpp"
|
#include "../UserData/UserDataStorage.hpp"
|
||||||
|
#include "../UserData/UserDataValue.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
namespace Porygon::StandardLibraries{
|
namespace Porygon::StandardLibraries{
|
||||||
|
@ -23,6 +26,11 @@ namespace Porygon::StandardLibraries{
|
||||||
|
|
||||||
InternalScope(){
|
InternalScope(){
|
||||||
BasicLibrary::RegisterVariables(&_boundVariables, &_variables);
|
BasicLibrary::RegisterVariables(&_boundVariables, &_variables);
|
||||||
|
auto mathData = MathLibrary::CreateUserData();
|
||||||
|
UserData::UserDataStorage::RegisterType(Utilities::HashedString::ConstHash("__math__"), mathData);
|
||||||
|
auto mathHash = Utilities::HashedString(new u16string(u"math"));
|
||||||
|
_boundVariables.insert({mathHash, new Binder::BoundVariable(make_shared<UserData::UserDataScriptType>(mathData))});
|
||||||
|
_variables.insert({mathHash, new UserData::UserDataValue(mathData, nullptr)});
|
||||||
}
|
}
|
||||||
|
|
||||||
~InternalScope(){
|
~InternalScope(){
|
||||||
|
@ -35,23 +43,35 @@ namespace Porygon::StandardLibraries{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static InternalScope _internal;
|
static InternalScope* _internal;
|
||||||
|
|
||||||
|
inline static InternalScope* GetScope(){
|
||||||
|
if (!_internal)
|
||||||
|
_internal = new InternalScope();
|
||||||
|
return _internal;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
~StaticScope(){
|
||||||
|
delete _internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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))});
|
GetScope()->_boundVariables.insert({identifier, new Binder::BoundVariable(std::move(type))});
|
||||||
_internal._variables.insert({identifier, value});
|
GetScope()->_variables.insert({identifier, value});
|
||||||
}
|
}
|
||||||
|
|
||||||
static Binder::BoundVariable* GetBoundVariable(const Utilities::HashedString &identifier){
|
static Binder::BoundVariable* GetBoundVariable(const Utilities::HashedString &identifier){
|
||||||
auto found = _internal._boundVariables.find(identifier);
|
auto found = GetScope()->_boundVariables.find(identifier);
|
||||||
if (found != _internal._boundVariables.end()) {
|
if (found != GetScope()->_boundVariables.end()) {
|
||||||
return found->second;
|
return found->second;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static Evaluation::EvalValuePointer GetVariable(const Utilities::HashedString &identifier){
|
inline static Evaluation::EvalValuePointer GetVariable(const Utilities::HashedString &identifier){
|
||||||
return _internal._variables[identifier]->Clone();
|
return GetScope()->_variables[identifier]->Clone();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace Porygon::UserData {
|
namespace Porygon::UserData {
|
||||||
class UserData {
|
class UserData {
|
||||||
std::unordered_map<uint32_t, UserDataField *> _fields;
|
std::unordered_map<uint32_t, unique_ptr<UserDataField>> _fields;
|
||||||
|
|
||||||
// Binary operations
|
// Binary operations
|
||||||
UserDataBinaryOperation* _addition = nullptr;
|
UserDataBinaryOperation* _addition = nullptr;
|
||||||
|
@ -27,14 +27,15 @@ namespace Porygon::UserData {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit UserData(std::unordered_map<uint32_t, UserDataField *> fields)
|
explicit UserData(std::unordered_map<uint32_t, UserDataField *> fields)
|
||||||
: _fields(std::move(fields))
|
|
||||||
{
|
{
|
||||||
|
for (auto f: fields){
|
||||||
|
_fields.insert({f.first, unique_ptr<UserDataField>(f.second)});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~UserData(){
|
~UserData(){
|
||||||
for (auto f: _fields){
|
_fields.clear();
|
||||||
delete f.second;
|
|
||||||
}
|
|
||||||
delete _addition;
|
delete _addition;
|
||||||
delete _subtraction;
|
delete _subtraction;
|
||||||
delete _multiplication;
|
delete _multiplication;
|
||||||
|
@ -57,11 +58,11 @@ namespace Porygon::UserData {
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline UserDataField *GetField(uint32_t fieldId) const {
|
inline UserDataField *GetField(uint32_t fieldId) const {
|
||||||
return _fields.at(fieldId);
|
return _fields.at(fieldId).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CreateField(uint32_t fieldId, UserDataField *field) {
|
inline void CreateField(uint32_t fieldId, UserDataField *field) {
|
||||||
_fields.insert({fieldId, field});
|
_fields.insert({fieldId, unique_ptr<UserDataField>(field)});
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
#include "UserDataStorage.hpp"
|
#include "UserDataStorage.hpp"
|
||||||
|
|
||||||
namespace Porygon::UserData {
|
namespace Porygon::UserData {
|
||||||
UserDataStorage::_internalDataStorage UserDataStorage::_internal = UserDataStorage::_internalDataStorage();
|
UserDataStorage::_internalDataStorage UserDataStorage::_internal;
|
||||||
std::mutex UserDataStorage::_userDataMutex;
|
std::mutex UserDataStorage::_userDataMutex;
|
||||||
}
|
}
|
|
@ -11,16 +11,17 @@ namespace Porygon::UserData {
|
||||||
private:
|
private:
|
||||||
class _internalDataStorage {
|
class _internalDataStorage {
|
||||||
public:
|
public:
|
||||||
std::unordered_map<uint32_t, UserData*> _userData;
|
std::unordered_map<uint32_t, std::unique_ptr<UserData>> _userData;
|
||||||
|
|
||||||
|
_internalDataStorage()
|
||||||
|
: _userData(std::unordered_map<uint32_t, std::unique_ptr<UserData>>(0))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
~_internalDataStorage(){
|
~_internalDataStorage(){
|
||||||
for (auto u: _userData){
|
|
||||||
delete u.second;
|
|
||||||
}
|
|
||||||
_userData.clear();
|
_userData.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
_internalDataStorage() = default;
|
|
||||||
_internalDataStorage( const UserDataStorage& ) = delete; // non construction-copyable
|
_internalDataStorage( const UserDataStorage& ) = delete; // non construction-copyable
|
||||||
_internalDataStorage& operator=( const UserDataStorage& ) = delete; // non copyable
|
_internalDataStorage& operator=( const UserDataStorage& ) = delete; // non copyable
|
||||||
|
|
||||||
|
@ -28,19 +29,14 @@ namespace Porygon::UserData {
|
||||||
|
|
||||||
static _internalDataStorage _internal;
|
static _internalDataStorage _internal;
|
||||||
static std::mutex _userDataMutex;
|
static std::mutex _userDataMutex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void RegisterType(uint32_t i, UserData *ud) {
|
static void RegisterType(uint32_t i, UserData *ud) {
|
||||||
std::lock_guard<std::mutex> guard(_userDataMutex);
|
std::lock_guard<std::mutex> guard(_userDataMutex);
|
||||||
UserDataStorage::_internal._userData.insert({i, ud});
|
UserDataStorage::_internal._userData.insert({i, std::unique_ptr<UserData>(ud)});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ClearTypes(){
|
static void RemoveType(uint32_t key){
|
||||||
std::lock_guard<std::mutex> guard(_userDataMutex);
|
_internal._userData.erase(key);
|
||||||
for (auto u: _internal._userData){
|
|
||||||
delete u.second;
|
|
||||||
}
|
|
||||||
_internal._userData.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static bool HasUserDataType(uint32_t i) {
|
inline static bool HasUserDataType(uint32_t i) {
|
||||||
|
@ -48,7 +44,7 @@ namespace Porygon::UserData {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static UserData* GetUserDataType(uint32_t i) {
|
inline static UserData* GetUserDataType(uint32_t i) {
|
||||||
return UserDataStorage::_internal._userData[i];
|
return UserDataStorage::_internal._userData.at(i).get();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,20 @@ class ModuleHandler{
|
||||||
MODULES.clear();
|
MODULES.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static Internal _internal;
|
static Internal* _internal;
|
||||||
|
|
||||||
|
static Internal* GetInternal(){
|
||||||
|
if (!_internal)
|
||||||
|
_internal = new Internal();
|
||||||
|
return _internal;
|
||||||
|
}
|
||||||
|
|
||||||
inline static bool DoesModuleExist(const string& moduleName){
|
inline static bool DoesModuleExist(const string& moduleName){
|
||||||
return _internal.MODULES.find(moduleName) != _internal.MODULES.end();
|
return GetInternal()->MODULES.find(moduleName) != GetInternal()->MODULES.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static Script* ResolveModule(const string& moduleName){
|
inline static Script* ResolveModule(const string& moduleName){
|
||||||
return _internal.MODULES[moduleName];
|
return GetInternal()->MODULES[moduleName];
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -39,7 +45,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ModuleHandler::Internal ModuleHandler::_internal;
|
ModuleHandler::Internal* ModuleHandler::_internal = nullptr;
|
||||||
|
|
||||||
TEST_CASE( "Require simple return script", "[integration]" ) {
|
TEST_CASE( "Require simple return script", "[integration]" ) {
|
||||||
ModuleHandler::Initialize();
|
ModuleHandler::Initialize();
|
||||||
|
|
|
@ -65,7 +65,7 @@ end
|
||||||
delete parameter;
|
delete parameter;
|
||||||
delete script;
|
delete script;
|
||||||
delete variable;
|
delete variable;
|
||||||
UserDataStorage::ClearTypes();
|
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Sets UserData value", "[integration]" ) {
|
TEST_CASE( "Sets UserData value", "[integration]" ) {
|
||||||
|
@ -84,7 +84,7 @@ end
|
||||||
REQUIRE(obj->foo == 5000);
|
REQUIRE(obj->foo == 5000);
|
||||||
delete obj;
|
delete obj;
|
||||||
delete parameter;
|
delete parameter;
|
||||||
UserDataStorage::ClearTypes();
|
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Calls UserData function", "[integration]" ) {
|
TEST_CASE( "Calls UserData function", "[integration]" ) {
|
||||||
|
@ -104,7 +104,7 @@ end
|
||||||
delete obj;
|
delete obj;
|
||||||
delete parameter;
|
delete parameter;
|
||||||
delete result;
|
delete result;
|
||||||
UserDataStorage::ClearTypes();
|
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Calls UserData function with parameters", "[integration]" ) {
|
TEST_CASE( "Calls UserData function with parameters", "[integration]" ) {
|
||||||
|
@ -124,7 +124,7 @@ end
|
||||||
delete obj;
|
delete obj;
|
||||||
delete parameter;
|
delete parameter;
|
||||||
delete result;
|
delete result;
|
||||||
UserDataStorage::ClearTypes();
|
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Gets userdata vector value", "[integration]" ) {
|
TEST_CASE( "Gets userdata vector value", "[integration]" ) {
|
||||||
|
@ -148,7 +148,7 @@ end
|
||||||
delete result;
|
delete result;
|
||||||
delete script;
|
delete script;
|
||||||
delete func;
|
delete func;
|
||||||
UserDataStorage::ClearTypes();
|
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Sets userdata vector value", "[integration]" ) {
|
TEST_CASE( "Sets userdata vector value", "[integration]" ) {
|
||||||
|
@ -170,7 +170,7 @@ end
|
||||||
delete parameter;
|
delete parameter;
|
||||||
delete script;
|
delete script;
|
||||||
delete func;
|
delete func;
|
||||||
UserDataStorage::ClearTypes();
|
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Iterate over userdata vector keys", "[integration]" ) {
|
TEST_CASE( "Iterate over userdata vector keys", "[integration]" ) {
|
||||||
|
@ -197,7 +197,7 @@ end
|
||||||
delete script;
|
delete script;
|
||||||
delete func;
|
delete func;
|
||||||
delete result;
|
delete result;
|
||||||
UserDataStorage::ClearTypes();
|
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Iterate over userdata vector values", "[integration]" ) {
|
TEST_CASE( "Iterate over userdata vector values", "[integration]" ) {
|
||||||
|
@ -224,7 +224,7 @@ end
|
||||||
delete script;
|
delete script;
|
||||||
delete func;
|
delete func;
|
||||||
delete result;
|
delete result;
|
||||||
UserDataStorage::ClearTypes();
|
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifdef TESTS_BUILD
|
||||||
|
#include <catch.hpp>
|
||||||
|
#include "../src/Script.hpp"
|
||||||
|
#include "../../src/ScriptOptions.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using namespace Porygon;
|
||||||
|
|
||||||
|
TEST_CASE( "Abs positive returns positive", "[integration]" ) {
|
||||||
|
Script* script = Script::Create(u"return math.abs(684)");
|
||||||
|
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||||
|
auto result = script -> Evaluate();
|
||||||
|
CHECK(result->EvaluateInteger() == 684);
|
||||||
|
delete script;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "Abs negative returns positive", "[integration]" ) {
|
||||||
|
Script* script = Script::Create(u"return math.abs(-684)");
|
||||||
|
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||||
|
auto result = script -> Evaluate();
|
||||||
|
CHECK(result->EvaluateInteger() == 684);
|
||||||
|
delete script;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue