PorygonLang/src/UserData/UserDataCollections/UserDataCollectionValue.hpp

107 lines
3.7 KiB
C++

#ifndef PORYGONLANG_USERDATACOLLECTIONVALUE_HPP
#define PORYGONLANG_USERDATACOLLECTIONVALUE_HPP
#include <utility>
#include "UserDataCollectionType.hpp"
#include "../../Evaluator/EvalValues/EvalValue.hpp"
#include "../../Utilities/Random.hpp"
#include "../../Evaluator/EvalValues/NumericEvalValue.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*);
size_t (*_getLength)(void*);
public:
UserDataCollectionHelper(void* parentObject,
const EvalValue* (*get)(void*, const EvalValue*),
void (*set)(void*, const EvalValue*, const EvalValue*),
Iterator* (*getIterator)(void*), size_t (*getLength)(void*))
: _parentObject(parentObject), _get(get), _set(set), _getIterator(getIterator),
_getLength(getLength){}
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);
}
[[nodiscard]] size_t GetLength() const{
return _getLength(_parentObject);
}
};
class UserDataCollectionValue : public Evaluation::EvalValue{
shared_ptr<const UserDataCollectionType> _type;
shared_ptr<const UserDataCollectionHelper> _helper;
const size_t _hash;
UserDataCollectionValue(shared_ptr<const UserDataCollectionType> type,
shared_ptr<const UserDataCollectionHelper> helper, size_t hash)
: _type(std::move(type)), _helper(std::move(helper)), _hash(hash)
{
}
public:
UserDataCollectionValue(const shared_ptr<const ScriptType>& type, const UserDataCollectionHelper* helper)
: _type(dynamic_pointer_cast<const 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;
}
bool operator!=(const EvalValue *b) const override {
return !operator==(b);
}
[[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;
}
[[nodiscard]] EvalValue *UnaryOperation(Binder::BoundUnaryOperation operation) const override {
if (operation == Binder::BoundUnaryOperation::Count){
return new NumericEvalValue(static_cast<int64_t>(_helper->GetLength()));
}
return EvalValue::UnaryOperation(operation);
}
};
}
#endif //PORYGONLANG_USERDATACOLLECTIONVALUE_HPP