Implements iterator for user data collection
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2019-08-15 11:43:08 +02:00
parent 5387cd15ff
commit 471dbac3b9
15 changed files with 151 additions and 14 deletions

View File

@@ -0,0 +1 @@
#include "UserDataCollectionIterator.hpp"

View File

@@ -0,0 +1,33 @@
#ifndef PORYGONLANG_USERDATACOLLECTIONITERATOR_HPP
#define PORYGONLANG_USERDATACOLLECTIONITERATOR_HPP
#include "../../Evaluator/Iterator/Iterator.hpp"
namespace Porygon::UserData{
class UserDataCollectionIterator : public Evaluation::Iterator{
const Evaluation::EvalValue* (*_getCurrent)();
const Evaluation::EvalValue* (*_moveNext)();
const Evaluation::EvalValue* (*_reset)();
public:
UserDataCollectionIterator(const Evaluation::EvalValue* (*getCurrent)(),
const Evaluation::EvalValue* (*moveNext)(),
const Evaluation::EvalValue* (*reset)()){
_getCurrent = getCurrent;
_moveNext = moveNext;
_reset = reset;
}
const Evaluation::EvalValue* GetCurrent() final{
return _getCurrent();
}
bool MoveNext() final{
_moveNext();
}
void Reset() final{
_reset();
}
};
}
#endif //PORYGONLANG_USERDATACOLLECTIONITERATOR_HPP

View File

@@ -0,0 +1 @@
#include "UserDataCollectionRangeIterator.hpp"

View File

@@ -0,0 +1,33 @@
#ifndef PORYGONLANG_USERDATACOLLECTIONRANGEITERATOR_HPP
#define PORYGONLANG_USERDATACOLLECTIONRANGEITERATOR_HPP
#include "../../Evaluator/Iterator/Iterator.hpp"
#include "../../Evaluator/EvalValues/NumericEvalValue.hpp"
namespace Porygon::UserData{
class UserDataCollectionRangeIterator : public Evaluation::Iterator{
size_t _start;
size_t _end;
size_t _current;
public:
UserDataCollectionRangeIterator(size_t start, size_t end){
_start = start;
_end = end;
_current = start;
}
const Evaluation::EvalValue* GetCurrent() final{
return new Evaluation::IntegerEvalValue(_current);
}
bool MoveNext() final{
_current ++;
return _current <= _end;
}
void Reset() final{
_current = _start;
}
};
}
#endif //PORYGONLANG_USERDATACOLLECTIONRANGEITERATOR_HPP

View File

@@ -0,0 +1 @@
#include "UserDataCollectionType.hpp"

View File

@@ -0,0 +1,61 @@
#ifndef PORYGONLANG_USERDATACOLLECTIONTYPE_HPP
#define PORYGONLANG_USERDATACOLLECTIONTYPE_HPP
#include <utility>
#include "../../ScriptTypes/ScriptType.hpp"
namespace Porygon::UserData {
class UserDataCollectionType : public ScriptType {
shared_ptr<const ScriptType> _keyType;
shared_ptr<const ScriptType> _valueType;
const bool _indexable;
const bool _iterable;
public:
UserDataCollectionType(shared_ptr<const ScriptType> keyType, shared_ptr<const ScriptType> valueType,
bool indexable, bool iterable)
: ScriptType(TypeClass::Table),
_keyType(std::move(keyType)),
_valueType(std::move(valueType)),
_indexable(indexable),
_iterable(iterable)
{}
static shared_ptr<UserDataCollectionType> CreateIndexable(const shared_ptr<const ScriptType>& keyType, const shared_ptr<const ScriptType>& valueType){
return make_shared<UserDataCollectionType>(keyType, valueType, true, true);
}
static UserDataCollectionType* CreateIndexable(const ScriptType* keyType, const ScriptType* valueType){
return new UserDataCollectionType(shared_ptr<const ScriptType>(keyType),
shared_ptr<const ScriptType>(valueType), true, true);
}
static shared_ptr<UserDataCollectionType> CreateIterable(const shared_ptr<const ScriptType>& valueType){
return make_shared<UserDataCollectionType>(nullptr, valueType, false, true);
}
bool CanBeIndexedWith(const ScriptType* indexer) const final{
if (!_indexable){
return false;
}
return indexer->operator==(_keyType.get());
}
[[nodiscard]] shared_ptr<const ScriptType> GetIndexedType(const ScriptType* indexer) const final{
return _valueType;
}
[[nodiscard]] bool CanBeIterated() const final{
return _iterable;
}
[[nodiscard]] shared_ptr<const ScriptType> GetIteratorKeyType() const final{
if (_indexable){
return _keyType;
} else{
return _valueType;
}
}
};
}
#endif //PORYGONLANG_USERDATACOLLECTIONTYPE_HPP

View File

@@ -0,0 +1 @@
#include "UserDataCollectionValue.hpp"

View File

@@ -0,0 +1,88 @@
#ifndef PORYGONLANG_USERDATACOLLECTIONVALUE_HPP
#define PORYGONLANG_USERDATACOLLECTIONVALUE_HPP
#include <utility>
#include "UserDataCollectionType.hpp"
#include "../../Evaluator/EvalValues/EvalValue.hpp"
#include "../../Utilities/Random.hpp"
using namespace Porygon::Evaluation;
namespace Porygon::UserData {
class UserDataCollectionHelper{
void* _parentObject;
const EvalValue* (*_get)(void*, const EvalValue*);
void (*_set)(void*, const EvalValue* , const EvalValue*);
Iterator* (*_getIterator)(void*);
public:
UserDataCollectionHelper(void* parentObject,
const EvalValue* (*get)(void*, const EvalValue*),
void (*set)(void*, const EvalValue*, const EvalValue*),
Iterator* (*getIterator)(void*))
: _parentObject(parentObject), _get(get), _set(set), _getIterator(getIterator){}
const EvalValue* Get(const EvalValue* key) const{
return _get(_parentObject, key);
}
void Set(const EvalValue* key, const EvalValue* value) const{
_set(_parentObject, key, value);
}
[[nodiscard]] Iterator* GetIterator() const{
return _getIterator(_parentObject);
}
};
class UserDataCollectionValue : public Evaluation::EvalValue{
shared_ptr<UserDataCollectionType> _type;
shared_ptr<const UserDataCollectionHelper> _helper;
const size_t _hash;
UserDataCollectionValue(shared_ptr<UserDataCollectionType> type,
shared_ptr<const UserDataCollectionHelper> helper, size_t hash)
: _type(std::move(type)), _helper(std::move(helper)), _hash(hash)
{
}
public:
UserDataCollectionValue(ScriptType* type, const UserDataCollectionHelper* helper)
: _type(dynamic_cast<UserDataCollectionType*>(type)), _helper(helper), _hash(Utilities::Random::Get())
{
}
[[nodiscard]] TypeClass GetTypeClass() const final{
return TypeClass ::Table;
}
bool operator==(const EvalValue *b) const final{
return b->GetHashCode() == _hash;
}
[[nodiscard]] EvalValue* Clone() const final{
return new UserDataCollectionValue(_type, _helper, _hash);
}
[[nodiscard]] std::size_t GetHashCode() const final{
return _hash;
}
const EvalValue* IndexValue(const EvalValue *val) const final{
return _helper->Get(val);
}
[[nodiscard]]
Iterator * GetKeyIterator() const final{
return _helper->GetIterator();
}
void SetIndexValue(const EvalValue *key, const EvalValue* value) const final{
_helper->Set(key, value);
delete value;
}
};
}
#endif //PORYGONLANG_USERDATACOLLECTIONVALUE_HPP