This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
#include <utility>
|
||||
|
||||
#ifndef PORYGONLANG_USERDATA_HPP
|
||||
#define PORYGONLANG_USERDATA_HPP
|
||||
|
||||
@@ -52,10 +50,12 @@ namespace Porygon::UserData {
|
||||
delete _concatenation;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool ContainsField(uint32_t fieldId) const{
|
||||
return _fields.find(fieldId) != _fields.end();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline UserDataField *GetField(uint32_t fieldId) const {
|
||||
return _fields.at(fieldId);
|
||||
}
|
||||
@@ -64,10 +64,12 @@ namespace Porygon::UserData {
|
||||
_fields.insert({fieldId, field});
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline int32_t GetFieldCount() const{
|
||||
return _fields.size();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
UserDataBinaryOperation* GetBinaryOperation(Binder::BoundBinaryOperation op){
|
||||
switch (op){
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
namespace Porygon::UserData {
|
||||
extern "C" {
|
||||
UserDataField *
|
||||
CreateUserDataField(ScriptType *type, Evaluation::EvalValue *(*getter)(void *obj), void (*setter)(void *obj, Evaluation::EvalValue *val)) {
|
||||
CreateUserDataField(ScriptType *type,
|
||||
const Evaluation::EvalValue *(*getter)(void *),
|
||||
void (*setter)(void *, const Evaluation::EvalValue *)) {
|
||||
return new UserDataField(type, getter, setter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,31 +8,35 @@
|
||||
|
||||
namespace Porygon::UserData{
|
||||
class UserDataField {
|
||||
shared_ptr<ScriptType> _type;
|
||||
Evaluation::EvalValue* (*_get)(void* obj);
|
||||
void (*_set)(void* obj, Evaluation::EvalValue* val);
|
||||
shared_ptr<const ScriptType> _type;
|
||||
const Evaluation::EvalValue* (*_get)(void* obj);
|
||||
void (*_set)(void* obj, const Evaluation::EvalValue* val);
|
||||
public:
|
||||
UserDataField(ScriptType* type, Evaluation::EvalValue* (*getter)(void* obj), void (*setter)(void* obj, Evaluation::EvalValue* val))
|
||||
: _type(shared_ptr<ScriptType>(type)), _get(getter), _set(setter){
|
||||
UserDataField(const ScriptType* type, const Evaluation::EvalValue* (*getter)(void* obj), void (*setter)(void* obj, const Evaluation::EvalValue* val))
|
||||
: _type(shared_ptr<const ScriptType>(type)), _get(getter), _set(setter){
|
||||
}
|
||||
|
||||
inline shared_ptr<ScriptType> GetType(){
|
||||
[[nodiscard]]
|
||||
inline shared_ptr<const ScriptType> GetType(){
|
||||
return _type;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool HasGetter(){
|
||||
return _get != nullptr;
|
||||
}
|
||||
|
||||
inline Evaluation::EvalValue* Get(void* obj){
|
||||
[[nodiscard]]
|
||||
inline const Evaluation::EvalValue* Get(void* obj){
|
||||
return this ->_get(obj);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool HasSetter(){
|
||||
return _set != nullptr;
|
||||
}
|
||||
|
||||
inline void Set(void* obj, Evaluation::EvalValue* val){
|
||||
inline void Set(void* obj, const Evaluation::EvalValue* val){
|
||||
this->_set(obj, val);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ using namespace Porygon::Evaluation;
|
||||
|
||||
namespace Porygon::UserData{
|
||||
extern "C" {
|
||||
EvalValue * CreateFunctionEvalValue(Evaluation::EvalValue* (*func)(void* , EvalValue* [], int ), void* obj) {
|
||||
const EvalValue * CreateFunctionEvalValue(const Evaluation::EvalValue* (*func)(void* , const EvalValue* [], int ), void* obj) {
|
||||
auto opt = new UserDataFunction(func, obj);
|
||||
auto t = new GenericFunctionEvalValue(make_shared<GenericFunctionScriptType>(), rand());
|
||||
t->RegisterOption(opt);
|
||||
|
||||
@@ -1,33 +1,31 @@
|
||||
#ifndef PORYGONLANG_USERDATAFUNCTION_HPP
|
||||
#define PORYGONLANG_USERDATAFUNCTION_HPP
|
||||
|
||||
#include <utility>
|
||||
#include "../Evaluator/EvalValues/ScriptFunctionEvalValue.hpp"
|
||||
#include "UserDataFunctionType.hpp"
|
||||
#include "../FunctionScriptType.hpp"
|
||||
|
||||
namespace Porygon::UserData{
|
||||
class UserDataFunction : public Evaluation::GenericFunctionOption {
|
||||
Evaluation::EvalValue* (*_call)(void* obj, Evaluation::EvalValue* parameters[], int parameterCount);
|
||||
const Evaluation::EvalValue* (*_call)(void* obj, const Evaluation::EvalValue* parameters[], int parameterCount);
|
||||
void *_obj;
|
||||
|
||||
UserDataFunction(Evaluation::EvalValue* (*call)(void* obj, Evaluation::EvalValue* parameters[], int parameterCount), void* obj,
|
||||
shared_ptr<GenericFunctionScriptType> type, size_t hash) : GenericFunctionOption(){
|
||||
UserDataFunction(const Evaluation::EvalValue* (*call)(void* obj, const Evaluation::EvalValue* parameters[], int parameterCount), void* obj,
|
||||
const shared_ptr<GenericFunctionScriptType>& type, size_t hash) : GenericFunctionOption(){
|
||||
_call = call;
|
||||
_obj = obj;
|
||||
}
|
||||
public:
|
||||
UserDataFunction(Evaluation::EvalValue* (*call)(void* obj, Evaluation::EvalValue* parameters[], int parameterCount), void* obj) :
|
||||
UserDataFunction(const Evaluation::EvalValue* (*call)(void* obj, const Evaluation::EvalValue* parameters[], int parameterCount), void* obj) :
|
||||
GenericFunctionOption(){
|
||||
_call = call;
|
||||
_obj = obj;
|
||||
}
|
||||
|
||||
~UserDataFunction() final{
|
||||
~UserDataFunction() final = default;
|
||||
|
||||
}
|
||||
|
||||
inline Evaluation::EvalValue* Call(Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
[[nodiscard]]
|
||||
inline const Evaluation::EvalValue* Call(const Evaluation::EvalValue* parameters[], int parameterCount) const{
|
||||
return _call(_obj, parameters, parameterCount);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Porygon::UserData{
|
||||
static UserDataFunctionOption* FromRawPointers(ScriptType* returnType, vector<ScriptType*> parameterTypes){
|
||||
auto rt = shared_ptr<ScriptType>(returnType);
|
||||
auto p = vector<shared_ptr<ScriptType>>(parameterTypes.size());
|
||||
for (int i = 0; i < parameterTypes.size(); i++){
|
||||
for (size_t i = 0; i < parameterTypes.size(); i++){
|
||||
p[i] = shared_ptr<ScriptType>(parameterTypes[i]);
|
||||
}
|
||||
return new UserDataFunctionOption(rt, p);
|
||||
@@ -26,10 +26,7 @@ namespace Porygon::UserData{
|
||||
return new UserDataFunctionOption(rt, {});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline const bool IsScriptFunction() const final{
|
||||
[[nodiscard]] inline bool IsScriptFunction() const final{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,8 +9,8 @@ namespace Porygon::UserData {
|
||||
class UserDataBinaryOperation {
|
||||
void* _parent;
|
||||
Evaluation::EvalValue *(*_func)(void *obj, Evaluation::EvalValue *b);
|
||||
const shared_ptr<ScriptType> _secondParameter;
|
||||
const shared_ptr<ScriptType> _returnType;
|
||||
const shared_ptr<const ScriptType> _secondParameter;
|
||||
const shared_ptr<const ScriptType> _returnType;
|
||||
public:
|
||||
UserDataBinaryOperation(void *parent,
|
||||
Evaluation::EvalValue *(*func)(void *, Evaluation::EvalValue *),
|
||||
@@ -23,11 +23,13 @@ namespace Porygon::UserData {
|
||||
return _func(_parent, b);
|
||||
}
|
||||
|
||||
inline const shared_ptr<ScriptType> GetSecondParameterType() const{
|
||||
[[nodiscard]]
|
||||
inline shared_ptr<const ScriptType> GetSecondParameterType() const{
|
||||
return _secondParameter;
|
||||
}
|
||||
|
||||
inline const shared_ptr<ScriptType> GetReturnType() const{
|
||||
[[nodiscard]]
|
||||
inline shared_ptr<const ScriptType> GetReturnType() const{
|
||||
return _returnType;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -20,33 +20,33 @@ namespace Porygon::UserData {
|
||||
_userData = ud;
|
||||
}
|
||||
|
||||
const bool CanBeIndexedWith(ScriptType *indexer) const final {
|
||||
bool CanBeIndexedWith(const ScriptType *indexer) const final {
|
||||
if (indexer->GetClass() != TypeClass::String) {
|
||||
return false;
|
||||
}
|
||||
auto str = dynamic_cast<StringScriptType*>(indexer);
|
||||
auto str = dynamic_cast<const StringScriptType*>(indexer);
|
||||
if (!str->IsKnownAtBind())
|
||||
return false;
|
||||
return _userData->ContainsField(str->GetHashValue());
|
||||
}
|
||||
|
||||
inline const bool CanBeIndexedWithIdentifier(uint32_t hash) const final {
|
||||
[[nodiscard]] inline bool CanBeIndexedWithIdentifier(uint32_t hash) const final {
|
||||
return _userData -> ContainsField(hash);
|
||||
}
|
||||
|
||||
inline UserDataField *GetField(uint32_t id) {
|
||||
[[nodiscard]] inline UserDataField *GetField(uint32_t id) const{
|
||||
return _userData->GetField(id);
|
||||
}
|
||||
|
||||
const shared_ptr<ScriptType> GetIndexedType(ScriptType *indexer) const final {
|
||||
auto stringKey = dynamic_cast<StringScriptType*>(indexer);
|
||||
shared_ptr<const ScriptType> GetIndexedType(const ScriptType *indexer) const final {
|
||||
auto stringKey = dynamic_cast<const StringScriptType*>(indexer);
|
||||
if (stringKey->IsKnownAtBind()) {
|
||||
return _userData->GetField(stringKey->GetHashValue())->GetType();
|
||||
}
|
||||
throw "TODO: indexing with dynamic keys";
|
||||
}
|
||||
|
||||
inline const shared_ptr<ScriptType> GetIndexedType(uint32_t hash) const final {
|
||||
[[nodiscard]] inline shared_ptr<const ScriptType> GetIndexedType(uint32_t hash) const final {
|
||||
return _userData->GetField(hash)->GetType();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
{ \
|
||||
Porygon::Utilities::HashedString::ConstHash(#fieldName), \
|
||||
new Porygon::UserData::UserDataField(fieldType, \
|
||||
[](void* obj) -> Porygon::Evaluation::EvalValue* { return new getterHelper;}, \
|
||||
[](void* obj, Porygon::Evaluation::EvalValue* val) { ((T_USERDATA*)obj)->fieldName = setterHelper;} \
|
||||
[](void* obj) -> const Porygon::Evaluation::EvalValue* { return new getterHelper;}, \
|
||||
[](void* obj, const Porygon::Evaluation::EvalValue* val) { ((T_USERDATA*)obj)->fieldName = setterHelper;} \
|
||||
) \
|
||||
}, \
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
#define PORYGON_INTEGER_FIELD(fieldName) \
|
||||
PORYGON_FIELD(fieldName, PORYGON_INTEGER_TYPE, \
|
||||
Porygon::Evaluation::IntegerEvalValue(((T_USERDATA*)obj)->fieldName), val->EvaluateInteger())
|
||||
const Porygon::Evaluation::IntegerEvalValue(((T_USERDATA*)obj)->fieldName), val->EvaluateInteger())
|
||||
|
||||
#define PORYGON_READONLY_INTEGER_FIELD(fieldName) \
|
||||
PORYGON_READONLY_FIELD(fieldName, PORYGON_INTEGER_TYPE, \
|
||||
@@ -72,11 +72,11 @@
|
||||
Porygon::UserData::UserDataFunctionOption::FromRawPointers(returnType, {__VA_ARGS__} )), \
|
||||
\
|
||||
\
|
||||
[](void* obj) -> Porygon::Evaluation::EvalValue* { \
|
||||
[](void* obj) -> const Porygon::Evaluation::EvalValue* { \
|
||||
auto t = new Porygon::Evaluation::GenericFunctionEvalValue(make_shared<GenericFunctionScriptType>(), rand()); \
|
||||
t->RegisterOption(new Porygon::UserData::UserDataFunction( \
|
||||
[](void* obj, Porygon::Evaluation::EvalValue* par[], int parameterCount) \
|
||||
-> Porygon::Evaluation::EvalValue*{return ((T_USERDATA*)obj)->invoke__##fieldName(obj, par, parameterCount);}, \
|
||||
[](void* obj, const Porygon::Evaluation::EvalValue* par[], int parameterCount) \
|
||||
-> const Porygon::Evaluation::EvalValue*{return ((const T_USERDATA*)obj)->invoke__##fieldName(obj, par, parameterCount);}, \
|
||||
obj)); \
|
||||
return t;}, \
|
||||
nullptr) \
|
||||
@@ -96,7 +96,7 @@
|
||||
\returns An invokable function.
|
||||
*/
|
||||
#define PORYGON_PREPARE_FUNCTION(userDataTypeName, fieldName, returnType, ...) \
|
||||
static Porygon::Evaluation::EvalValue* invoke__##fieldName(void* obj, Porygon::Evaluation::EvalValue* par[], int parameterCount){ \
|
||||
static const Porygon::Evaluation::EvalValue* invoke__##fieldName(void* obj, const Porygon::Evaluation::EvalValue* par[], int parameterCount){ \
|
||||
return Porygon::Evaluation::EvalValueHelper::Create(((userDataTypeName*)obj)->fieldName( \
|
||||
__VA_ARGS__ \
|
||||
));}
|
||||
|
||||
@@ -22,36 +22,40 @@ namespace Porygon::UserData {
|
||||
_obj = obj;
|
||||
}
|
||||
|
||||
inline const TypeClass GetTypeClass() const final {
|
||||
[[nodiscard]]
|
||||
inline TypeClass GetTypeClass() const final {
|
||||
return TypeClass::UserData;
|
||||
}
|
||||
|
||||
const bool operator==(EvalValue *b) const final {
|
||||
bool operator==(const EvalValue *b) const final {
|
||||
if (b->GetTypeClass() != TypeClass::UserData)
|
||||
return false;
|
||||
return _obj == ((UserDataValue *) b)->_obj;
|
||||
}
|
||||
|
||||
inline const shared_ptr<EvalValue> Clone() const final {
|
||||
[[nodiscard]]
|
||||
inline shared_ptr<const EvalValue> Clone() const final {
|
||||
return make_shared<UserDataValue>(_userData, _obj);
|
||||
}
|
||||
|
||||
inline const std::size_t GetHashCode() const final {
|
||||
[[nodiscard]]
|
||||
inline std::size_t GetHashCode() const final {
|
||||
return reinterpret_cast<intptr_t>(_obj);
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> IndexValue(EvalValue *val) const final {
|
||||
shared_ptr<const EvalValue> IndexValue(const EvalValue *val) const final {
|
||||
auto fieldId = val->GetHashCode();
|
||||
auto field = _userData->GetField(fieldId);
|
||||
return shared_ptr<EvalValue>(field->Get(_obj));
|
||||
return shared_ptr<const EvalValue>(field->Get(_obj));
|
||||
}
|
||||
|
||||
inline const shared_ptr<EvalValue> IndexValue(uint32_t hash) const final {
|
||||
[[nodiscard]]
|
||||
inline shared_ptr<const EvalValue> IndexValue(uint32_t hash) const final {
|
||||
auto field = _userData->GetField(hash);
|
||||
return shared_ptr<EvalValue>(field->Get(_obj));
|
||||
return shared_ptr<const EvalValue>(field->Get(_obj));
|
||||
}
|
||||
|
||||
void SetIndexValue(EvalValue *key, const shared_ptr<EvalValue> &value) const final {
|
||||
void SetIndexValue(const EvalValue *key, const shared_ptr<const EvalValue> &value) const final {
|
||||
auto fieldId = key->GetHashCode();
|
||||
auto field = _userData->GetField(fieldId);
|
||||
field->Set(_obj, value.get());
|
||||
|
||||
Reference in New Issue
Block a user