Allows userdata binary operations to be set externally
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
b94c811e94
commit
bd343c1b7e
|
@ -312,7 +312,7 @@ namespace Porygon::Binder {
|
||||||
const BoundExpression* _right;
|
const BoundExpression* _right;
|
||||||
const UserData::UserDataBinaryOperation* _operation;
|
const UserData::UserDataBinaryOperation* _operation;
|
||||||
public:
|
public:
|
||||||
BoundUserdataBinaryExpression(BoundExpression *left, BoundExpression *right, UserData::UserDataBinaryOperation* op,
|
BoundUserdataBinaryExpression(BoundExpression *left, BoundExpression *right, const UserData::UserDataBinaryOperation* op,
|
||||||
shared_ptr<const ScriptType> result,
|
shared_ptr<const ScriptType> result,
|
||||||
unsigned int start, unsigned int length)
|
unsigned int start, unsigned int length)
|
||||||
: BoundExpression(start, length, std::move(result)),
|
: BoundExpression(start, length, std::move(result)),
|
||||||
|
|
|
@ -3,21 +3,22 @@
|
||||||
#define PORYGONLANG_BOUNDOPERATORS_HPP
|
#define PORYGONLANG_BOUNDOPERATORS_HPP
|
||||||
|
|
||||||
namespace Porygon::Binder {
|
namespace Porygon::Binder {
|
||||||
enum class BoundBinaryOperation {
|
enum class BoundBinaryOperation : char
|
||||||
Addition,
|
{
|
||||||
Subtraction,
|
Addition = 0,
|
||||||
Multiplication,
|
Subtraction = 1,
|
||||||
Division,
|
Multiplication = 2,
|
||||||
Equality,
|
Division = 3,
|
||||||
Inequality,
|
Equality = 4,
|
||||||
LessThan,
|
Inequality = 5,
|
||||||
LessThanEquals,
|
LessThan = 6,
|
||||||
GreaterThan,
|
LessThanEquals = 7,
|
||||||
GreaterThanEquals,
|
GreaterThan = 8,
|
||||||
|
GreaterThanEquals = 9,
|
||||||
|
|
||||||
LogicalAnd,
|
LogicalAnd = 10,
|
||||||
LogicalOr,
|
LogicalOr = 11,
|
||||||
Concatenation
|
Concatenation = 12
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BoundUnaryOperation {
|
enum class BoundUnaryOperation {
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef PORYGONLANG_EXCEPTION_HPP
|
||||||
|
#define PORYGONLANG_EXCEPTION_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
class Exception : public std::exception{
|
||||||
|
const std::string _err;
|
||||||
|
public:
|
||||||
|
explicit Exception(const char* err) :_err(std::string(err)){ }
|
||||||
|
|
||||||
|
[[nodiscard]] const char *what() const noexcept final {
|
||||||
|
return _err.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //PORYGONLANG_EXCEPTION_HPP
|
|
@ -29,5 +29,10 @@ namespace Porygon::UserData {
|
||||||
auto ud = UserDataStorage::GetUserDataType(typeId);
|
auto ud = UserDataStorage::GetUserDataType(typeId);
|
||||||
ud->Get()->SetCastFunc(cast);
|
ud->Get()->SetCastFunc(cast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddUserdataBinaryOperation(uint32_t typeId, char kind, const UserDataBinaryOperation* operation){
|
||||||
|
auto ud = UserDataStorage::GetUserDataType(typeId);
|
||||||
|
ud->Get()->AddBinaryOperation(static_cast<Binder::BoundBinaryOperation >(kind), operation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
#include "UserDataField.hpp"
|
#include "UserDataField.hpp"
|
||||||
#include "UserDataOperation.hpp"
|
#include "UserDataOperation.hpp"
|
||||||
#include "../Parser/BinaryOperatorKind.hpp"
|
#include "../Parser/BinaryOperatorKind.hpp"
|
||||||
|
#include "../Exception.hpp"
|
||||||
|
|
||||||
namespace Porygon::UserData {
|
namespace Porygon::UserData {
|
||||||
class UserData {
|
class UserData {
|
||||||
|
@ -15,16 +16,16 @@ namespace Porygon::UserData {
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
|
|
||||||
// Binary operations
|
// Binary operations
|
||||||
std::vector<UserDataBinaryOperation*> _addition = {};
|
std::vector<const UserDataBinaryOperation*> _addition = {};
|
||||||
std::vector<UserDataBinaryOperation*> _subtraction = {};
|
std::vector<const UserDataBinaryOperation*> _subtraction = {};
|
||||||
std::vector<UserDataBinaryOperation*> _multiplication = {};
|
std::vector<const UserDataBinaryOperation*> _multiplication = {};
|
||||||
std::vector<UserDataBinaryOperation*> _division = {};
|
std::vector<const UserDataBinaryOperation*> _division = {};
|
||||||
std::vector<UserDataBinaryOperation*> _equality = {};
|
std::vector<const UserDataBinaryOperation*> _equality = {};
|
||||||
std::vector<UserDataBinaryOperation*> _inequality = {};
|
std::vector<const UserDataBinaryOperation*> _inequality = {};
|
||||||
std::vector<UserDataBinaryOperation*> _lessThan = {};
|
std::vector<const UserDataBinaryOperation*> _lessThan = {};
|
||||||
std::vector<UserDataBinaryOperation*> _lessThanEquals = {};
|
std::vector<const UserDataBinaryOperation*> _lessThanEquals = {};
|
||||||
std::vector<UserDataBinaryOperation*> _greaterThan = {};
|
std::vector<const UserDataBinaryOperation*> _greaterThan = {};
|
||||||
std::vector<UserDataBinaryOperation*> _greaterThanEquals = {};
|
std::vector<const UserDataBinaryOperation*> _greaterThanEquals = {};
|
||||||
|
|
||||||
bool (*_isCastable)(const ScriptType* type, bool explicitCast);
|
bool (*_isCastable)(const ScriptType* type, bool explicitCast);
|
||||||
Evaluation::EvalValue* (*_cast)(void* obj, const ScriptType* castType);
|
Evaluation::EvalValue* (*_cast)(void* obj, const ScriptType* castType);
|
||||||
|
@ -95,25 +96,28 @@ namespace Porygon::UserData {
|
||||||
return _cast(obj, castType);
|
return _cast(obj, castType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddBinaryOperation(Binder::BoundBinaryOperation kind, UserDataBinaryOperation* op){
|
void AddBinaryOperation(Binder::BoundBinaryOperation kind, const UserDataBinaryOperation* op){
|
||||||
switch (kind){
|
switch (kind){
|
||||||
|
case Binder::BoundBinaryOperation::Addition: return _addition.push_back(op);
|
||||||
case Binder::BoundBinaryOperation::Addition: _addition.push_back(op);
|
case Binder::BoundBinaryOperation::Subtraction: return _subtraction.push_back(op);
|
||||||
case Binder::BoundBinaryOperation::Subtraction: _subtraction.push_back(op);
|
case Binder::BoundBinaryOperation::Multiplication: return _multiplication.push_back(op);
|
||||||
case Binder::BoundBinaryOperation::Multiplication: _multiplication.push_back(op);
|
case Binder::BoundBinaryOperation::Division: return _division.push_back(op);
|
||||||
case Binder::BoundBinaryOperation::Division: _division.push_back(op);
|
case Binder::BoundBinaryOperation::Equality: return _equality.push_back(op);
|
||||||
case Binder::BoundBinaryOperation::Equality: _equality.push_back(op);
|
case Binder::BoundBinaryOperation::Inequality: return _inequality.push_back(op);
|
||||||
case Binder::BoundBinaryOperation::Inequality: _inequality.push_back(op);
|
case Binder::BoundBinaryOperation::LessThan: return _lessThan.push_back(op);
|
||||||
case Binder::BoundBinaryOperation::LessThan: _lessThan.push_back(op);
|
case Binder::BoundBinaryOperation::LessThanEquals: return _lessThanEquals.push_back(op);
|
||||||
case Binder::BoundBinaryOperation::LessThanEquals: _lessThanEquals.push_back(op);
|
case Binder::BoundBinaryOperation::GreaterThan: return _greaterThan.push_back(op);
|
||||||
case Binder::BoundBinaryOperation::GreaterThan: _greaterThan.push_back(op);
|
case Binder::BoundBinaryOperation::GreaterThanEquals: return _greaterThanEquals.push_back(op);
|
||||||
case Binder::BoundBinaryOperation::GreaterThanEquals: _greaterThanEquals.push_back(op);
|
default:
|
||||||
default: throw exception();
|
stringstream err;
|
||||||
|
err << "Unknown binary operation kind: " << static_cast<int>(kind);
|
||||||
|
throw Exception(err.str().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static UserDataBinaryOperation* ResolveBinaryOperation(const vector<UserDataBinaryOperation*>& v, const shared_ptr<const ScriptType>& b){
|
static const UserDataBinaryOperation* ResolveBinaryOperation(const vector<const UserDataBinaryOperation*>& v,
|
||||||
|
const shared_ptr<const ScriptType>& b){
|
||||||
for (auto o: v){
|
for (auto o: v){
|
||||||
if (o->IsValid(b)){
|
if (o->IsValid(b)){
|
||||||
return o;
|
return o;
|
||||||
|
@ -124,7 +128,7 @@ namespace Porygon::UserData {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
UserDataBinaryOperation* GetBinaryOperation(Parser::BinaryOperatorKind op, const shared_ptr<const ScriptType>& b){
|
const UserDataBinaryOperation* GetBinaryOperation(Parser::BinaryOperatorKind op, const shared_ptr<const ScriptType>& b){
|
||||||
switch (op){
|
switch (op){
|
||||||
|
|
||||||
case Parser::BinaryOperatorKind::Addition: return ResolveBinaryOperation(_addition, b);
|
case Parser::BinaryOperatorKind::Addition: return ResolveBinaryOperation(_addition, b);
|
||||||
|
|
|
@ -1 +1,11 @@
|
||||||
#include "UserDataOperation.hpp"
|
#include "UserDataOperation.hpp"
|
||||||
|
|
||||||
|
namespace Porygon::UserData{
|
||||||
|
extern "C" {
|
||||||
|
UserDataBinaryOperation* CreateUserdataBinaryOperation(Evaluation::EvalValue *(*func)(void *, const Evaluation::EvalValue *),
|
||||||
|
ScriptType* secondParameter, ScriptType* returnType){
|
||||||
|
return new UserDataBinaryOperation(func, shared_ptr<const ScriptType>(secondParameter),
|
||||||
|
shared_ptr<const ScriptType>(returnType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ namespace Porygon::UserData {
|
||||||
const shared_ptr<const ScriptType> _returnType;
|
const shared_ptr<const ScriptType> _returnType;
|
||||||
public:
|
public:
|
||||||
UserDataBinaryOperation(Evaluation::EvalValue *(*func)(void *, const Evaluation::EvalValue *),
|
UserDataBinaryOperation(Evaluation::EvalValue *(*func)(void *, const Evaluation::EvalValue *),
|
||||||
shared_ptr<ScriptType> secondParameter,
|
shared_ptr<const ScriptType> secondParameter,
|
||||||
shared_ptr<ScriptType> returnType)
|
shared_ptr<const ScriptType> returnType)
|
||||||
: _func(func), _secondParameter(std::move(secondParameter)),
|
: _func(func), _secondParameter(std::move(secondParameter)),
|
||||||
_returnType(std::move(returnType)) {}
|
_returnType(std::move(returnType)) {}
|
||||||
|
|
||||||
|
@ -21,18 +21,13 @@ namespace Porygon::UserData {
|
||||||
return _func(a, b);
|
return _func(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValid(const shared_ptr<const ScriptType>& v){
|
[[nodiscard]] bool IsValid(const shared_ptr<const ScriptType>& v) const{
|
||||||
if (v->operator==(_secondParameter)){
|
if (v->operator==(_secondParameter)){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return v->CastableTo(_secondParameter, true) != CastResult::InvalidCast;
|
return v->CastableTo(_secondParameter, true) != CastResult::InvalidCast;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
inline shared_ptr<const ScriptType> GetSecondParameterType() const{
|
|
||||||
return _secondParameter;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<const ScriptType> GetReturnType() const{
|
inline shared_ptr<const ScriptType> GetReturnType() const{
|
||||||
return _returnType;
|
return _returnType;
|
||||||
|
|
Loading…
Reference in New Issue