Handling for when userdata is not defined yet, but might be defined later
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
5b7da77027
commit
4c97a7c811
|
@ -29,6 +29,8 @@ namespace Porygon::Parser {
|
||||||
|
|
||||||
inline const Token *Parser::Next() {
|
inline const Token *Parser::Next() {
|
||||||
this->_position++;
|
this->_position++;
|
||||||
|
if (_position > _tokens.size())
|
||||||
|
return nullptr;
|
||||||
return this->_tokens[_position - 1];
|
return this->_tokens[_position - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,11 +185,14 @@ namespace Porygon::Parser {
|
||||||
auto block = this->ParseBlock({TokenKind::EndKeyword});
|
auto block = this->ParseBlock({TokenKind::EndKeyword});
|
||||||
|
|
||||||
auto start = current->GetStartPosition();
|
auto start = current->GetStartPosition();
|
||||||
|
auto end = block->GetEndPosition();
|
||||||
if (hasErrors) {
|
if (hasErrors) {
|
||||||
return new ParsedBadStatement(start, block->GetEndPosition() - start);
|
delete block;
|
||||||
|
return new ParsedBadStatement(start, end - start);
|
||||||
}
|
}
|
||||||
if (block->GetKind() == ParsedStatementKind::Bad) {
|
if (block->GetKind() == ParsedStatementKind::Bad) {
|
||||||
return new ParsedBadStatement(start, block->GetEndPosition() - start);
|
delete block;
|
||||||
|
return new ParsedBadStatement(start, end - start);
|
||||||
}
|
}
|
||||||
auto functionIdentifier = dynamic_cast<const IdentifierToken*>(functionIdentifierToken)->GetValue();
|
auto functionIdentifier = dynamic_cast<const IdentifierToken*>(functionIdentifierToken)->GetValue();
|
||||||
return new ParsedFunctionDeclarationStatement(HashedString(functionIdentifier), parameters,
|
return new ParsedFunctionDeclarationStatement(HashedString(functionIdentifier), parameters,
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
#include "RetrievedUserData.hpp"
|
||||||
|
#include "UserDataStorage.hpp"
|
||||||
|
|
||||||
|
Porygon::UserData::UserData * Porygon::UserData::RetrievedUserData::Get() {
|
||||||
|
if (_ud == nullptr){
|
||||||
|
_ud = UserDataStorage::GetUserDataTypeRaw(_key);
|
||||||
|
}
|
||||||
|
return _ud;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef PORYGONLANG_RETRIEVEDUSERDATA_HPP
|
||||||
|
#define PORYGONLANG_RETRIEVEDUSERDATA_HPP
|
||||||
|
|
||||||
|
#include "UserData.hpp"
|
||||||
|
|
||||||
|
namespace Porygon::UserData{
|
||||||
|
class RetrievedUserData{
|
||||||
|
UserData* _ud;
|
||||||
|
uint32_t _key;
|
||||||
|
public:
|
||||||
|
explicit RetrievedUserData(UserData* ud) : _ud(ud), _key(0){}
|
||||||
|
explicit RetrievedUserData(uint32_t id) : _ud(nullptr), _key(id){}
|
||||||
|
|
||||||
|
UserData * Get();
|
||||||
|
|
||||||
|
inline uint32_t GetKey() const{
|
||||||
|
return _key;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //PORYGONLANG_RETRIEVEDUSERDATA_HPP
|
|
@ -11,12 +11,12 @@ namespace Porygon::UserData {
|
||||||
|
|
||||||
void RegisterUserDataField(uint32_t typeId, uint32_t fieldId, UserDataField *field) {
|
void RegisterUserDataField(uint32_t typeId, uint32_t fieldId, UserDataField *field) {
|
||||||
auto ud = UserDataStorage::GetUserDataType(typeId);
|
auto ud = UserDataStorage::GetUserDataType(typeId);
|
||||||
ud->CreateField(fieldId, field);
|
ud->Get()->CreateField(fieldId, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t GetUserDataFieldCount(uint32_t typeId) {
|
int32_t GetUserDataFieldCount(uint32_t typeId) {
|
||||||
auto ud = UserDataStorage::GetUserDataType(typeId);
|
auto ud = UserDataStorage::GetUserDataType(typeId);
|
||||||
return ud->GetFieldCount();
|
return ud->Get()->GetFieldCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,14 +10,19 @@
|
||||||
|
|
||||||
namespace Porygon::UserData {
|
namespace Porygon::UserData {
|
||||||
class UserDataScriptType : public ScriptType {
|
class UserDataScriptType : public ScriptType {
|
||||||
UserData* _userData;
|
RetrievedUserData* _userData;
|
||||||
public:
|
public:
|
||||||
explicit UserDataScriptType(uint32_t id) : ScriptType(TypeClass::UserData) {
|
explicit UserDataScriptType(uint32_t id) :
|
||||||
_userData = UserDataStorage::GetUserDataType(id);
|
_userData(UserDataStorage::GetUserDataType(id)),
|
||||||
|
ScriptType(TypeClass::UserData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit UserDataScriptType(UserData* ud) : ScriptType(TypeClass::UserData) {
|
explicit UserDataScriptType(UserData* ud) :
|
||||||
_userData = ud;
|
_userData(new RetrievedUserData(ud)),
|
||||||
|
ScriptType(TypeClass::UserData) {}
|
||||||
|
|
||||||
|
~UserDataScriptType() final{
|
||||||
|
delete _userData;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanBeIndexedWith(const ScriptType *indexer) const final {
|
bool CanBeIndexedWith(const ScriptType *indexer) const final {
|
||||||
|
@ -27,27 +32,27 @@ namespace Porygon::UserData {
|
||||||
auto str = dynamic_cast<const StringScriptType*>(indexer);
|
auto str = dynamic_cast<const StringScriptType*>(indexer);
|
||||||
if (!str->IsKnownAtBind())
|
if (!str->IsKnownAtBind())
|
||||||
return false;
|
return false;
|
||||||
return _userData->ContainsField(str->GetHashValue());
|
return _userData->Get()->ContainsField(str->GetHashValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline bool CanBeIndexedWithIdentifier(uint32_t hash) const final {
|
[[nodiscard]] inline bool CanBeIndexedWithIdentifier(uint32_t hash) const final {
|
||||||
return _userData -> ContainsField(hash);
|
return _userData->Get() -> ContainsField(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline UserDataField *GetField(uint32_t id) const{
|
[[nodiscard]] inline UserDataField *GetField(uint32_t id) const{
|
||||||
return _userData->GetField(id);
|
return _userData->Get()->GetField(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const ScriptType> GetIndexedType(const ScriptType *indexer) const final {
|
shared_ptr<const ScriptType> GetIndexedType(const ScriptType *indexer) const final {
|
||||||
auto stringKey = dynamic_cast<const StringScriptType*>(indexer);
|
auto stringKey = dynamic_cast<const StringScriptType*>(indexer);
|
||||||
if (stringKey->IsKnownAtBind()) {
|
if (stringKey->IsKnownAtBind()) {
|
||||||
return _userData->GetField(stringKey->GetHashValue())->GetType();
|
return _userData->Get()->GetField(stringKey->GetHashValue())->GetType();
|
||||||
}
|
}
|
||||||
throw "TODO: indexing with dynamic keys";
|
throw "TODO: indexing with dynamic keys";
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline shared_ptr<const ScriptType> GetIndexedType(uint32_t hash) const final {
|
[[nodiscard]] inline shared_ptr<const ScriptType> GetIndexedType(uint32_t hash) const final {
|
||||||
return _userData->GetField(hash)->GetType();
|
return _userData->Get()->GetField(hash)->GetType();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
#define PORYGONLANG_USERDATASTORAGE_HPP
|
#define PORYGONLANG_USERDATASTORAGE_HPP
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "UserData.hpp"
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include "UserData.hpp"
|
||||||
|
#include "RetrievedUserData.hpp"
|
||||||
|
|
||||||
namespace Porygon::UserData {
|
namespace Porygon::UserData {
|
||||||
class UserDataStorage {
|
class UserDataStorage {
|
||||||
|
@ -43,8 +44,15 @@ namespace Porygon::UserData {
|
||||||
return UserDataStorage::_internal._userData.find(i) != UserDataStorage::_internal._userData.end();
|
return UserDataStorage::_internal._userData.find(i) != UserDataStorage::_internal._userData.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static UserData* GetUserDataType(uint32_t i) {
|
inline static RetrievedUserData* GetUserDataType(uint32_t i){
|
||||||
return UserDataStorage::_internal._userData.at(i).get();
|
if (UserDataStorage::_internal._userData.count(i))
|
||||||
|
return new RetrievedUserData(UserDataStorage::_internal._userData.at(i).get());
|
||||||
|
return new RetrievedUserData(i);
|
||||||
|
}
|
||||||
|
inline static UserData* GetUserDataTypeRaw(uint32_t i){
|
||||||
|
if (UserDataStorage::_internal._userData.count(i))
|
||||||
|
return UserDataStorage::_internal._userData.at(i).get();
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
|
|
||||||
namespace Porygon::UserData {
|
namespace Porygon::UserData {
|
||||||
class UserDataValue : public Evaluation::EvalValue {
|
class UserDataValue : public Evaluation::EvalValue {
|
||||||
const UserData* _userData;
|
RetrievedUserData* _userData;
|
||||||
void *_obj;
|
void *_obj;
|
||||||
public:
|
public:
|
||||||
UserDataValue(const UserData* userData, void *obj)
|
UserDataValue(UserData* userData, void *obj)
|
||||||
: _userData(userData) {
|
: _userData(new RetrievedUserData(userData)) {
|
||||||
_obj = obj;
|
_obj = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,10 @@ namespace Porygon::UserData {
|
||||||
_obj = obj;
|
_obj = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~UserDataValue(){
|
||||||
|
delete _userData;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline TypeClass GetTypeClass() const final {
|
inline TypeClass GetTypeClass() const final {
|
||||||
return TypeClass::UserData;
|
return TypeClass::UserData;
|
||||||
|
@ -35,7 +39,11 @@ namespace Porygon::UserData {
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline Evaluation::EvalValue* Clone() const final {
|
inline Evaluation::EvalValue* Clone() const final {
|
||||||
return new UserDataValue(_userData, _obj);
|
auto ud = _userData->Get();
|
||||||
|
if (ud == nullptr){
|
||||||
|
return new UserDataValue(_userData->GetKey(), _obj);
|
||||||
|
}
|
||||||
|
return new UserDataValue(ud, _obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
@ -45,19 +53,19 @@ namespace Porygon::UserData {
|
||||||
|
|
||||||
const Evaluation::EvalValue* IndexValue(const EvalValue *val) const final {
|
const Evaluation::EvalValue* IndexValue(const EvalValue *val) const final {
|
||||||
auto fieldId = val->GetHashCode();
|
auto fieldId = val->GetHashCode();
|
||||||
auto field = _userData->GetField(fieldId);
|
auto field = _userData->Get()->GetField(fieldId);
|
||||||
return field->Get(_obj);
|
return field->Get(_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline const EvalValue* IndexValue(uint32_t hash) const final {
|
inline const EvalValue* IndexValue(uint32_t hash) const final {
|
||||||
auto field = _userData->GetField(hash);
|
auto field = _userData->Get()->GetField(hash);
|
||||||
return field->Get(_obj);
|
return field->Get(_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIndexValue(const EvalValue *key, const EvalValue* value) const final {
|
void SetIndexValue(const EvalValue *key, const EvalValue* value) const final {
|
||||||
auto fieldId = key->GetHashCode();
|
auto fieldId = key->GetHashCode();
|
||||||
auto field = _userData->GetField(fieldId);
|
auto field = _userData->Get()->GetField(fieldId);
|
||||||
field->Set(_obj, value);
|
field->Set(_obj, value);
|
||||||
delete value;
|
delete value;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue