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 UserData::UserDataBinaryOperation* _operation;
|
||||
public:
|
||||
BoundUserdataBinaryExpression(BoundExpression *left, BoundExpression *right, UserData::UserDataBinaryOperation* op,
|
||||
BoundUserdataBinaryExpression(BoundExpression *left, BoundExpression *right, const UserData::UserDataBinaryOperation* op,
|
||||
shared_ptr<const ScriptType> result,
|
||||
unsigned int start, unsigned int length)
|
||||
: BoundExpression(start, length, std::move(result)),
|
||||
|
|
|
@ -3,21 +3,22 @@
|
|||
#define PORYGONLANG_BOUNDOPERATORS_HPP
|
||||
|
||||
namespace Porygon::Binder {
|
||||
enum class BoundBinaryOperation {
|
||||
Addition,
|
||||
Subtraction,
|
||||
Multiplication,
|
||||
Division,
|
||||
Equality,
|
||||
Inequality,
|
||||
LessThan,
|
||||
LessThanEquals,
|
||||
GreaterThan,
|
||||
GreaterThanEquals,
|
||||
enum class BoundBinaryOperation : char
|
||||
{
|
||||
Addition = 0,
|
||||
Subtraction = 1,
|
||||
Multiplication = 2,
|
||||
Division = 3,
|
||||
Equality = 4,
|
||||
Inequality = 5,
|
||||
LessThan = 6,
|
||||
LessThanEquals = 7,
|
||||
GreaterThan = 8,
|
||||
GreaterThanEquals = 9,
|
||||
|
||||
LogicalAnd,
|
||||
LogicalOr,
|
||||
Concatenation
|
||||
LogicalAnd = 10,
|
||||
LogicalOr = 11,
|
||||
Concatenation = 12
|
||||
};
|
||||
|
||||
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
|
|
@ -5,13 +5,13 @@
|
|||
namespace Porygon::Parser {
|
||||
enum class BinaryOperatorKind {
|
||||
// Math
|
||||
Addition,
|
||||
Addition,
|
||||
Subtraction,
|
||||
Multiplication,
|
||||
Division,
|
||||
|
||||
// Equality
|
||||
Equality,
|
||||
Equality,
|
||||
Inequality,
|
||||
Less,
|
||||
LessOrEquals,
|
||||
|
@ -19,7 +19,7 @@ namespace Porygon::Parser {
|
|||
GreaterOrEquals,
|
||||
|
||||
// Logical
|
||||
LogicalAnd,
|
||||
LogicalAnd,
|
||||
LogicalOr,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,5 +29,10 @@ namespace Porygon::UserData {
|
|||
auto ud = UserDataStorage::GetUserDataType(typeId);
|
||||
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 "UserDataOperation.hpp"
|
||||
#include "../Parser/BinaryOperatorKind.hpp"
|
||||
#include "../Exception.hpp"
|
||||
|
||||
namespace Porygon::UserData {
|
||||
class UserData {
|
||||
|
@ -15,16 +16,16 @@ namespace Porygon::UserData {
|
|||
std::mutex _mutex;
|
||||
|
||||
// Binary operations
|
||||
std::vector<UserDataBinaryOperation*> _addition = {};
|
||||
std::vector<UserDataBinaryOperation*> _subtraction = {};
|
||||
std::vector<UserDataBinaryOperation*> _multiplication = {};
|
||||
std::vector<UserDataBinaryOperation*> _division = {};
|
||||
std::vector<UserDataBinaryOperation*> _equality = {};
|
||||
std::vector<UserDataBinaryOperation*> _inequality = {};
|
||||
std::vector<UserDataBinaryOperation*> _lessThan = {};
|
||||
std::vector<UserDataBinaryOperation*> _lessThanEquals = {};
|
||||
std::vector<UserDataBinaryOperation*> _greaterThan = {};
|
||||
std::vector<UserDataBinaryOperation*> _greaterThanEquals = {};
|
||||
std::vector<const UserDataBinaryOperation*> _addition = {};
|
||||
std::vector<const UserDataBinaryOperation*> _subtraction = {};
|
||||
std::vector<const UserDataBinaryOperation*> _multiplication = {};
|
||||
std::vector<const UserDataBinaryOperation*> _division = {};
|
||||
std::vector<const UserDataBinaryOperation*> _equality = {};
|
||||
std::vector<const UserDataBinaryOperation*> _inequality = {};
|
||||
std::vector<const UserDataBinaryOperation*> _lessThan = {};
|
||||
std::vector<const UserDataBinaryOperation*> _lessThanEquals = {};
|
||||
std::vector<const UserDataBinaryOperation*> _greaterThan = {};
|
||||
std::vector<const UserDataBinaryOperation*> _greaterThanEquals = {};
|
||||
|
||||
bool (*_isCastable)(const ScriptType* type, bool explicitCast);
|
||||
Evaluation::EvalValue* (*_cast)(void* obj, const ScriptType* castType);
|
||||
|
@ -95,25 +96,28 @@ namespace Porygon::UserData {
|
|||
return _cast(obj, castType);
|
||||
}
|
||||
|
||||
void AddBinaryOperation(Binder::BoundBinaryOperation kind, UserDataBinaryOperation* op){
|
||||
void AddBinaryOperation(Binder::BoundBinaryOperation kind, const UserDataBinaryOperation* op){
|
||||
switch (kind){
|
||||
|
||||
case Binder::BoundBinaryOperation::Addition: _addition.push_back(op);
|
||||
case Binder::BoundBinaryOperation::Subtraction: _subtraction.push_back(op);
|
||||
case Binder::BoundBinaryOperation::Multiplication: _multiplication.push_back(op);
|
||||
case Binder::BoundBinaryOperation::Division: _division.push_back(op);
|
||||
case Binder::BoundBinaryOperation::Equality: _equality.push_back(op);
|
||||
case Binder::BoundBinaryOperation::Inequality: _inequality.push_back(op);
|
||||
case Binder::BoundBinaryOperation::LessThan: _lessThan.push_back(op);
|
||||
case Binder::BoundBinaryOperation::LessThanEquals: _lessThanEquals.push_back(op);
|
||||
case Binder::BoundBinaryOperation::GreaterThan: _greaterThan.push_back(op);
|
||||
case Binder::BoundBinaryOperation::GreaterThanEquals: _greaterThanEquals.push_back(op);
|
||||
default: throw exception();
|
||||
case Binder::BoundBinaryOperation::Addition: return _addition.push_back(op);
|
||||
case Binder::BoundBinaryOperation::Subtraction: return _subtraction.push_back(op);
|
||||
case Binder::BoundBinaryOperation::Multiplication: return _multiplication.push_back(op);
|
||||
case Binder::BoundBinaryOperation::Division: return _division.push_back(op);
|
||||
case Binder::BoundBinaryOperation::Equality: return _equality.push_back(op);
|
||||
case Binder::BoundBinaryOperation::Inequality: return _inequality.push_back(op);
|
||||
case Binder::BoundBinaryOperation::LessThan: return _lessThan.push_back(op);
|
||||
case Binder::BoundBinaryOperation::LessThanEquals: return _lessThanEquals.push_back(op);
|
||||
case Binder::BoundBinaryOperation::GreaterThan: return _greaterThan.push_back(op);
|
||||
case Binder::BoundBinaryOperation::GreaterThanEquals: return _greaterThanEquals.push_back(op);
|
||||
default:
|
||||
stringstream err;
|
||||
err << "Unknown binary operation kind: " << static_cast<int>(kind);
|
||||
throw Exception(err.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
if (o->IsValid(b)){
|
||||
return o;
|
||||
|
@ -124,7 +128,7 @@ namespace Porygon::UserData {
|
|||
|
||||
public:
|
||||
[[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){
|
||||
|
||||
case Parser::BinaryOperatorKind::Addition: return ResolveBinaryOperation(_addition, b);
|
||||
|
|
|
@ -1 +1,11 @@
|
|||
#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;
|
||||
public:
|
||||
UserDataBinaryOperation(Evaluation::EvalValue *(*func)(void *, const Evaluation::EvalValue *),
|
||||
shared_ptr<ScriptType> secondParameter,
|
||||
shared_ptr<ScriptType> returnType)
|
||||
shared_ptr<const ScriptType> secondParameter,
|
||||
shared_ptr<const ScriptType> returnType)
|
||||
: _func(func), _secondParameter(std::move(secondParameter)),
|
||||
_returnType(std::move(returnType)) {}
|
||||
|
||||
|
@ -21,18 +21,13 @@ namespace Porygon::UserData {
|
|||
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)){
|
||||
return true;
|
||||
}
|
||||
return v->CastableTo(_secondParameter, true) != CastResult::InvalidCast;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline shared_ptr<const ScriptType> GetSecondParameterType() const{
|
||||
return _secondParameter;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline shared_ptr<const ScriptType> GetReturnType() const{
|
||||
return _returnType;
|
||||
|
|
Loading…
Reference in New Issue