Improved performance when binding by reusing many common scripttype objects
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
79873d9d6a
commit
a3e77f650a
|
@ -106,7 +106,7 @@ namespace Porygon::Binder {
|
|||
auto valueExpression = this->BindExpression(s->GetValueExpression());
|
||||
auto boundIndexType = indexable->GetType();
|
||||
if (boundIndexType->GetClass() != TypeClass::Error &&
|
||||
boundIndexType->operator!=(valueExpression->GetType().get())) {
|
||||
boundIndexType->operator!=(valueExpression->GetType())) {
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidTableValueType,
|
||||
statement->GetStartPosition(), statement->GetLength());
|
||||
return new BoundBadStatement();
|
||||
|
@ -115,15 +115,15 @@ namespace Porygon::Binder {
|
|||
return new BoundIndexAssignmentStatement(indexable, valueExpression);
|
||||
}
|
||||
|
||||
std::shared_ptr<ScriptType> ParseTypeIdentifier(const HashedString *s) {
|
||||
std::shared_ptr<const ScriptType> ParseTypeIdentifier(const HashedString *s) {
|
||||
auto hash = s->GetHash();
|
||||
switch (hash) {
|
||||
case HashedString::ConstHash("number"):
|
||||
return std::make_shared<NumericScriptType>(false, false);
|
||||
return NumericScriptType::Unaware;
|
||||
case HashedString::ConstHash("bool"):
|
||||
return std::make_shared<ScriptType>(TypeClass::Bool);
|
||||
return ScriptType::BoolType;
|
||||
case HashedString::ConstHash("string"):
|
||||
return std::make_shared<StringScriptType>(false, 0);
|
||||
return StringScriptType::Dynamic;
|
||||
default:
|
||||
if (!UserData::UserDataStorage::HasUserDataType(hash)) {
|
||||
return nullptr;
|
||||
|
@ -135,7 +135,7 @@ namespace Porygon::Binder {
|
|||
BoundStatement *Binder::BindFunctionDeclarationStatement(const ParsedStatement *statement) {
|
||||
auto functionStatement = (ParsedFunctionDeclarationStatement *) statement;
|
||||
auto parameters = functionStatement->GetParameters();
|
||||
auto parameterTypes = vector<shared_ptr<ScriptType>>(parameters->size());
|
||||
auto parameterTypes = vector<shared_ptr<const ScriptType>>(parameters->size());
|
||||
auto parameterKeys = vector<shared_ptr<const BoundVariableKey>>(parameters->size());
|
||||
|
||||
this->_scope->GoInnerScope();
|
||||
|
@ -159,7 +159,7 @@ namespace Porygon::Binder {
|
|||
}
|
||||
|
||||
auto identifier = functionStatement->GetIdentifier();
|
||||
auto returnType = make_shared<ScriptType>(TypeClass::Nil);
|
||||
auto returnType = ScriptType::NilType;
|
||||
auto option = new ScriptFunctionOption(returnType, parameterTypes, parameterKeys);
|
||||
this->_currentFunction = option;
|
||||
|
||||
|
@ -211,7 +211,7 @@ namespace Porygon::Binder {
|
|||
statement->GetLength());
|
||||
return new BoundBadStatement();
|
||||
} else if (expression == nullptr) {
|
||||
currentReturnType = make_shared<ScriptType>(TypeClass::Nil);
|
||||
currentReturnType = ScriptType::NilType;
|
||||
return new BoundReturnStatement(nullptr);
|
||||
}
|
||||
auto boundExpression = this->BindExpression(expression);
|
||||
|
@ -224,7 +224,7 @@ namespace Porygon::Binder {
|
|||
}
|
||||
return new BoundReturnStatement(boundExpression);
|
||||
}
|
||||
if (currentReturnType.get()->operator!=(expresionType.get())) {
|
||||
if (currentReturnType.get()->operator!=(expresionType)) {
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidReturnType,
|
||||
statement->GetStartPosition(),
|
||||
statement->GetLength());
|
||||
|
@ -280,7 +280,7 @@ namespace Porygon::Binder {
|
|||
}
|
||||
|
||||
this->_scope->GoInnerScope();
|
||||
auto variableKey = this->_scope->CreateExplicitLocal(identifier, make_shared<NumericScriptType>(true, false));
|
||||
auto variableKey = this->_scope->CreateExplicitLocal(identifier, NumericScriptType::AwareInt);
|
||||
if (variableKey.GetResult() != VariableAssignmentResult::Ok) {
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable,
|
||||
statement->GetStartPosition(),
|
||||
|
@ -424,19 +424,18 @@ namespace Porygon::Binder {
|
|||
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()) {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight,
|
||||
BoundBinaryOperation::Addition,
|
||||
std::make_shared<NumericScriptType>(true,
|
||||
NumericScriptType::ResolveType(true,
|
||||
leftNumeric->IsFloat() ||
|
||||
rightNumeric->IsFloat()),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
} else {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Addition,
|
||||
std::make_shared<NumericScriptType>(false, false),
|
||||
NumericScriptType::Unaware,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
} else if (boundLeftType->GetClass() == TypeClass::String) {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Concatenation,
|
||||
std::make_shared<StringScriptType>(false,
|
||||
0),
|
||||
StringScriptType::Dynamic,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
break;
|
||||
|
@ -447,13 +446,13 @@ namespace Porygon::Binder {
|
|||
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()) {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight,
|
||||
BoundBinaryOperation::Subtraction,
|
||||
std::make_shared<NumericScriptType>(true,
|
||||
NumericScriptType::ResolveType(true,
|
||||
leftNumeric->IsFloat() ||
|
||||
rightNumeric->IsFloat()),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
} else {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Subtraction,
|
||||
std::make_shared<NumericScriptType>(false, false),
|
||||
NumericScriptType::Unaware,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
}
|
||||
|
@ -465,13 +464,13 @@ namespace Porygon::Binder {
|
|||
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()) {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight,
|
||||
BoundBinaryOperation::Multiplication,
|
||||
std::make_shared<NumericScriptType>(true,
|
||||
NumericScriptType::ResolveType(true,
|
||||
leftNumeric->IsFloat() ||
|
||||
rightNumeric->IsFloat()),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
} else {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Multiplication,
|
||||
std::make_shared<NumericScriptType>(false, false),
|
||||
NumericScriptType::Unaware,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
}
|
||||
|
@ -483,63 +482,63 @@ namespace Porygon::Binder {
|
|||
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()) {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight,
|
||||
BoundBinaryOperation::Division,
|
||||
std::make_shared<NumericScriptType>(true,
|
||||
NumericScriptType::ResolveType(true,
|
||||
leftNumeric->IsFloat() ||
|
||||
rightNumeric->IsFloat()),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
} else {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Division,
|
||||
std::make_shared<NumericScriptType>(false, false),
|
||||
NumericScriptType::Unaware,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BinaryOperatorKind::Equality:
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Equality,
|
||||
std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
ScriptType::BoolType,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
case BinaryOperatorKind::Inequality:
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Inequality,
|
||||
std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
ScriptType::BoolType,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
case BinaryOperatorKind::Less:
|
||||
if (boundLeft->GetType()->GetClass() == TypeClass::Number &&
|
||||
boundRight->GetType()->GetClass() == TypeClass::Number) {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::LessThan,
|
||||
std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
ScriptType::BoolType,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
case BinaryOperatorKind::LessOrEquals:
|
||||
if (boundLeft->GetType()->GetClass() == TypeClass::Number &&
|
||||
boundRight->GetType()->GetClass() == TypeClass::Number) {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::LessThanEquals,
|
||||
std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
ScriptType::BoolType,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
case BinaryOperatorKind::Greater:
|
||||
if (boundLeft->GetType()->GetClass() == TypeClass::Number &&
|
||||
boundRight->GetType()->GetClass() == TypeClass::Number) {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::GreaterThan,
|
||||
std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
ScriptType::BoolType,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
case BinaryOperatorKind::GreaterOrEquals:
|
||||
if (boundLeft->GetType()->GetClass() == TypeClass::Number &&
|
||||
boundRight->GetType()->GetClass() == TypeClass::Number) {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::GreaterThanEquals,
|
||||
std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
ScriptType::BoolType,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
case BinaryOperatorKind::LogicalAnd:
|
||||
if (boundLeftType->GetClass() == TypeClass::Bool && boundRightType->GetClass() == TypeClass::Bool)
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::LogicalAnd,
|
||||
std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
ScriptType::BoolType,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
break;
|
||||
case BinaryOperatorKind::LogicalOr:
|
||||
if (boundLeftType->GetClass() == TypeClass::Bool && boundRightType->GetClass() == TypeClass::Bool)
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::LogicalOr,
|
||||
std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
ScriptType::BoolType,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
break;
|
||||
}
|
||||
|
@ -563,7 +562,7 @@ namespace Porygon::Binder {
|
|||
if (operandType->GetClass() == TypeClass::Number) {
|
||||
auto innerType = std::dynamic_pointer_cast<const NumericScriptType>(operandType);
|
||||
return new BoundUnaryExpression(operand, BoundUnaryOperation::Negation,
|
||||
std::make_shared<NumericScriptType>(
|
||||
NumericScriptType::ResolveType(
|
||||
innerType.get()->IsAwareOfFloat(),
|
||||
innerType.get()->IsFloat()),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
|
@ -572,7 +571,7 @@ namespace Porygon::Binder {
|
|||
case UnaryOperatorKind::LogicalNegation:
|
||||
if (operandType->GetClass() == TypeClass::Bool) {
|
||||
return new BoundUnaryExpression(operand, BoundUnaryOperation::LogicalNegation,
|
||||
std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
ScriptType::BoolType,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
break;
|
||||
|
@ -778,7 +777,7 @@ namespace Porygon::Binder {
|
|||
valueType = boundExpressions[0]->GetType();
|
||||
for (size_t i = 1; i < expressions->size(); i++) {
|
||||
boundExpressions[i] = this->BindExpression(expressions->at(i));
|
||||
if (boundExpressions[i]->GetType().get()->operator!=(valueType.get())) {
|
||||
if (boundExpressions[i]->GetType()->operator!=(valueType)) {
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidTableValueType,
|
||||
boundExpressions[i]->GetStartPosition(),
|
||||
boundExpressions[i]->GetLength());
|
||||
|
@ -786,7 +785,7 @@ namespace Porygon::Binder {
|
|||
}
|
||||
}
|
||||
if (valueType == nullptr) {
|
||||
valueType = std::make_shared<const ScriptType>(TypeClass::Nil);
|
||||
valueType = ScriptType::NilType;
|
||||
}
|
||||
auto tableType = std::make_shared<const NumericalTableScriptType>(valueType);
|
||||
return new BoundNumericalTableExpression(boundExpressions, tableType, expression->GetStartPosition(),
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace Porygon::Binder {
|
|||
const int64_t _value;
|
||||
public:
|
||||
BoundLiteralIntegerExpression(int64_t value, unsigned int start, unsigned int length)
|
||||
: BoundExpression(start, length, make_shared<NumericScriptType>(true, false)),
|
||||
: BoundExpression(start, length, NumericScriptType::AwareInt),
|
||||
_value(value) {
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ namespace Porygon::Binder {
|
|||
const double _value;
|
||||
public:
|
||||
BoundLiteralFloatExpression(double value, unsigned int start, unsigned int length)
|
||||
: BoundExpression(start, length, make_shared<NumericScriptType>(true, true)),
|
||||
: BoundExpression(start, length, NumericScriptType::AwareFloat),
|
||||
_value(value) {
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ namespace Porygon::Binder {
|
|||
const bool _value;
|
||||
public:
|
||||
BoundLiteralBoolExpression(bool value, unsigned int start, unsigned int length)
|
||||
: BoundExpression(start, length, make_shared<ScriptType>(TypeClass::Bool)),
|
||||
: BoundExpression(start, length, ScriptType::BoolType),
|
||||
_value(value) {
|
||||
}
|
||||
|
||||
|
@ -182,7 +182,7 @@ namespace Porygon::Binder {
|
|||
const BoundBinaryOperation _operation;
|
||||
public:
|
||||
BoundBinaryExpression(BoundExpression *left, BoundExpression *right, BoundBinaryOperation op,
|
||||
shared_ptr<ScriptType> result,
|
||||
shared_ptr<const ScriptType> result,
|
||||
unsigned int start, unsigned int length)
|
||||
: BoundExpression(start, length, std::move(result)),
|
||||
_left(left),
|
||||
|
@ -220,7 +220,7 @@ namespace Porygon::Binder {
|
|||
const BoundExpression *_operand;
|
||||
const BoundUnaryOperation _operation;
|
||||
public:
|
||||
BoundUnaryExpression(BoundExpression *operand, BoundUnaryOperation op, shared_ptr<ScriptType> result,
|
||||
BoundUnaryExpression(BoundExpression *operand, BoundUnaryOperation op, shared_ptr<const ScriptType> result,
|
||||
unsigned int start, unsigned int length)
|
||||
: BoundExpression(start, length, std::move(result)),
|
||||
_operand(operand),
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace Porygon::Binder {
|
|||
} else {
|
||||
// Assigning
|
||||
auto var = this->GetVariable(exists, identifier);
|
||||
if (var->GetType().get()->operator!=(type.get())) {
|
||||
if (var->GetType()->operator!=(type)) {
|
||||
return VariableAssignment(VariableAssignmentResult::VariableDefinedWithDifferentType, nullptr);
|
||||
}
|
||||
return VariableAssignment(VariableAssignmentResult::Ok, new BoundVariableKey(identifier, exists, false));
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
namespace Porygon {
|
||||
class GenericFunctionOption{
|
||||
shared_ptr<const ScriptType> _returnType;
|
||||
vector<shared_ptr<ScriptType>> _parameterTypes;
|
||||
vector<shared_ptr<const ScriptType>> _parameterTypes;
|
||||
size_t _option = 0;
|
||||
public:
|
||||
GenericFunctionOption(shared_ptr<ScriptType> returnType, vector<shared_ptr<ScriptType>> parameterTypes)
|
||||
GenericFunctionOption(shared_ptr<const ScriptType> returnType, vector<shared_ptr<const ScriptType>> parameterTypes)
|
||||
: _returnType(std::move(returnType)), _parameterTypes(std::move(parameterTypes)){
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace Porygon {
|
|||
_returnType = t;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline vector<shared_ptr<ScriptType>> GetParameterTypes() const {
|
||||
[[nodiscard]] inline vector<shared_ptr<const ScriptType>> GetParameterTypes() const {
|
||||
return _parameterTypes;
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ namespace Porygon {
|
|||
continue;
|
||||
auto parameter = parameters->at(i);
|
||||
const auto& parameterType = parameter->GetType();
|
||||
if (parameterType->operator!=(_parameterTypes[i].get())){
|
||||
if (parameterType->operator!=(_parameterTypes[i])){
|
||||
auto castResult = parameterType->CastableTo(_parameterTypes[i], false);
|
||||
if (castResult == CastResult::InvalidCast){
|
||||
return false;
|
||||
|
@ -125,7 +125,7 @@ namespace Porygon {
|
|||
class ScriptFunctionOption : public GenericFunctionOption {
|
||||
vector<shared_ptr<const Porygon::Binder::BoundVariableKey>> _parameterKeys;
|
||||
public:
|
||||
ScriptFunctionOption(shared_ptr<ScriptType> returnType, vector<shared_ptr<ScriptType>> parameterTypes,
|
||||
ScriptFunctionOption(shared_ptr<const ScriptType> returnType, vector<shared_ptr<const ScriptType>> parameterTypes,
|
||||
vector<shared_ptr<const Porygon::Binder::BoundVariableKey>> parameterKeys)
|
||||
: GenericFunctionOption(move(returnType), std::move(parameterTypes)), _parameterKeys(move(parameterKeys)) {
|
||||
}
|
||||
|
|
|
@ -6,10 +6,14 @@ namespace Porygon{
|
|||
return false;
|
||||
}
|
||||
|
||||
shared_ptr<const ScriptType> ScriptType::BoolType = make_shared<ScriptType>(TypeClass::Bool);
|
||||
shared_ptr<const ScriptType> ScriptType::NilType = make_shared<ScriptType>(TypeClass::Nil);
|
||||
shared_ptr<const NumericScriptType> NumericScriptType::AwareInt = make_shared<NumericScriptType>(true, false);
|
||||
shared_ptr<const NumericScriptType> NumericScriptType::AwareFloat = make_shared<NumericScriptType>(true, true);
|
||||
shared_ptr<const NumericScriptType> NumericScriptType::Unaware = make_shared<NumericScriptType>(false, false);
|
||||
shared_ptr<const StringScriptType> StringScriptType::Dynamic = make_shared<StringScriptType>(false, 0);
|
||||
|
||||
shared_ptr<const ScriptType> ScriptType::GetIndexedType(const ScriptType*) const{
|
||||
if (_class == TypeClass::String){
|
||||
return make_shared<ScriptType>(TypeClass::String);
|
||||
}
|
||||
return make_shared<ScriptType>(TypeClass::Error);
|
||||
}
|
||||
|
||||
|
@ -18,8 +22,13 @@ namespace Porygon{
|
|||
return new ScriptType(t);
|
||||
}
|
||||
|
||||
ScriptType* CreateNumericScriptType(bool isAware, bool isFloat){
|
||||
return new NumericScriptType(isAware, isFloat);
|
||||
const ScriptType* CreateNumericScriptType(bool isAware, bool isFloat){
|
||||
if (isAware){
|
||||
if (isFloat)
|
||||
return NumericScriptType::AwareFloat.get();
|
||||
return NumericScriptType::AwareInt.get();
|
||||
}
|
||||
return NumericScriptType::Unaware.get();
|
||||
}
|
||||
|
||||
ScriptType* CreateStringScriptType(bool knownAtBind, uint32_t hash){
|
||||
|
@ -27,11 +36,11 @@ namespace Porygon{
|
|||
}
|
||||
|
||||
ScriptType* CreateUserDataFunctionScriptType(ScriptType* returnType, ScriptType* parameters[], size_t parameterCount){
|
||||
vector<shared_ptr<ScriptType>> vector(parameterCount);
|
||||
for (int i = 0; i < parameterCount; i++){
|
||||
vector[i] = shared_ptr<ScriptType>(parameters[i]);
|
||||
vector<shared_ptr<const ScriptType>> vector(parameterCount);
|
||||
for (size_t i = 0; i < parameterCount; i++){
|
||||
vector[i] = shared_ptr<const ScriptType>(parameters[i]);
|
||||
}
|
||||
auto option = new UserData::UserDataFunctionOption(shared_ptr<ScriptType>(returnType), vector);
|
||||
auto option = new UserData::UserDataFunctionOption(shared_ptr<const ScriptType>(returnType), vector);
|
||||
auto type = new GenericFunctionScriptType();
|
||||
type->RegisterFunctionOption(option);
|
||||
return type;
|
||||
|
|
|
@ -33,24 +33,19 @@ namespace Porygon{
|
|||
_class = c;
|
||||
}
|
||||
|
||||
static shared_ptr<const ScriptType> BoolType;
|
||||
static shared_ptr<const ScriptType> NilType;
|
||||
virtual ~ScriptType() = default;
|
||||
|
||||
[[nodiscard]] inline TypeClass GetClass() const{
|
||||
return _class;
|
||||
}
|
||||
|
||||
virtual bool operator ==(const ScriptType& b) const{
|
||||
return _class == b._class;
|
||||
};
|
||||
|
||||
virtual bool operator ==(const ScriptType* b) const{
|
||||
virtual bool operator ==(const shared_ptr<const ScriptType>& b) const{
|
||||
return _class == b->_class;
|
||||
};
|
||||
|
||||
virtual bool operator !=(const ScriptType& b) const{
|
||||
return ! (operator==(b));
|
||||
}
|
||||
virtual bool operator !=(const ScriptType* b) const{
|
||||
|
||||
virtual bool operator !=(const shared_ptr<const ScriptType>& b) const{
|
||||
return ! (operator==(b));
|
||||
}
|
||||
|
||||
|
@ -88,7 +83,20 @@ namespace Porygon{
|
|||
bool _awareOfFloat;
|
||||
// Is this value a float?
|
||||
bool _isFloat;
|
||||
|
||||
public:
|
||||
static shared_ptr<const NumericScriptType> AwareInt;
|
||||
static shared_ptr<const NumericScriptType> AwareFloat;
|
||||
static shared_ptr<const NumericScriptType> Unaware;
|
||||
|
||||
static shared_ptr<const NumericScriptType> ResolveType(bool isAware, bool isFloat){
|
||||
if (isAware){
|
||||
if (isFloat) return AwareFloat;
|
||||
return AwareInt;
|
||||
}
|
||||
return Unaware;
|
||||
}
|
||||
|
||||
explicit NumericScriptType(bool floatAware, bool isFloat) : ScriptType(TypeClass::Number){
|
||||
_awareOfFloat = floatAware;
|
||||
_isFloat = isFloat;
|
||||
|
@ -102,22 +110,19 @@ namespace Porygon{
|
|||
return _isFloat;
|
||||
}
|
||||
|
||||
bool operator ==(const ScriptType& b) const final{
|
||||
if (b.GetClass() != TypeClass::Number)
|
||||
bool operator ==(const shared_ptr<const ScriptType>& b) const final{
|
||||
if (b->GetClass() != TypeClass::Number)
|
||||
return false;
|
||||
auto bNum = dynamic_cast<const NumericScriptType&>(b);
|
||||
if (bNum.IsAwareOfFloat() && IsAwareOfFloat()){
|
||||
return bNum.IsFloat() == IsFloat();
|
||||
auto bNum = dynamic_pointer_cast<const NumericScriptType>(b);
|
||||
if (bNum->IsAwareOfFloat() && IsAwareOfFloat()){
|
||||
return bNum->IsFloat() == IsFloat();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
bool operator !=(const ScriptType& b) const final{
|
||||
bool operator !=(const shared_ptr<const ScriptType>& b) const final{
|
||||
return ! (operator==(b));
|
||||
}
|
||||
bool operator !=(const ScriptType* b) const final{
|
||||
return ! (operator==(*b));
|
||||
}
|
||||
|
||||
[[nodiscard]] CastResult CastableTo(const shared_ptr<const ScriptType>& castType, bool explicitCast) const final{
|
||||
if (!explicitCast){
|
||||
|
@ -140,6 +145,8 @@ namespace Porygon{
|
|||
_hashValue = hashValue;
|
||||
}
|
||||
|
||||
static shared_ptr<const StringScriptType> Dynamic;
|
||||
|
||||
[[nodiscard]]
|
||||
bool CanBeIndexedWith(const ScriptType* indexer) const final{
|
||||
if (indexer -> GetClass() != TypeClass::Number)
|
||||
|
@ -149,7 +156,7 @@ namespace Porygon{
|
|||
}
|
||||
|
||||
inline shared_ptr<const ScriptType> GetIndexedType(const ScriptType* indexer) const final{
|
||||
return make_shared<StringScriptType>(false, 0);
|
||||
return StringScriptType::Dynamic;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
|
@ -188,7 +195,7 @@ namespace Porygon{
|
|||
}
|
||||
[[nodiscard]]
|
||||
inline shared_ptr<const ScriptType> GetIteratorKeyType() const final{
|
||||
return make_shared<NumericScriptType>(true, false);
|
||||
return NumericScriptType::AwareInt;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@ namespace Porygon::StandardLibraries{
|
|||
|
||||
static shared_ptr<GenericFunctionScriptType> GetAssertFuncType(){
|
||||
return GetFuncType(make_shared<ScriptType>(TypeClass::Bool),
|
||||
{{make_shared<ScriptType>(TypeClass::Bool)},
|
||||
{make_shared<ScriptType>(TypeClass::Bool), make_shared<StringScriptType>(false, 0)}});
|
||||
{{ScriptType::BoolType},
|
||||
{ScriptType::BoolType, StringScriptType::Dynamic}});
|
||||
}
|
||||
//endregion
|
||||
//region Error
|
||||
|
@ -46,8 +46,7 @@ namespace Porygon::StandardLibraries{
|
|||
throw Evaluation::EvaluationException(conv);
|
||||
}
|
||||
static shared_ptr<GenericFunctionScriptType> GetErrorFuncType(){
|
||||
return GetFuncType(make_shared<ScriptType>(TypeClass::Nil),
|
||||
{{make_shared<StringScriptType>(false, 0)}});
|
||||
return GetFuncType(ScriptType::NilType, {{StringScriptType::Dynamic}});
|
||||
}
|
||||
//endregion
|
||||
//region Print
|
||||
|
@ -58,7 +57,7 @@ namespace Porygon::StandardLibraries{
|
|||
return new Evaluation::NilEvalValue();
|
||||
}
|
||||
static shared_ptr<GenericFunctionScriptType> GetPrintFuncType(){
|
||||
return GetFuncType(make_shared<ScriptType>(TypeClass::Nil), {{make_shared<StringScriptType>(false, 0)}});
|
||||
return GetFuncType(ScriptType::NilType, {{StringScriptType::Dynamic}});
|
||||
}
|
||||
//endregion
|
||||
//region ToInt
|
||||
|
@ -69,7 +68,8 @@ namespace Porygon::StandardLibraries{
|
|||
return new Evaluation::IntegerEvalValue(parsed);
|
||||
}
|
||||
static shared_ptr<GenericFunctionScriptType> GetToIntFuncType(){
|
||||
return GetFuncType(make_shared<NumericScriptType>(true, false), {{make_shared<StringScriptType>(false, 0)}});
|
||||
return GetFuncType(NumericScriptType::AwareInt,
|
||||
{{StringScriptType::Dynamic}});
|
||||
}
|
||||
//endregion
|
||||
//region ToFloat
|
||||
|
@ -80,8 +80,8 @@ namespace Porygon::StandardLibraries{
|
|||
return new Evaluation::FloatEvalValue(parsed);
|
||||
}
|
||||
static shared_ptr<GenericFunctionScriptType> GetToFloatFuncType(){
|
||||
return GetFuncType(make_shared<NumericScriptType>(true, true),
|
||||
{{make_shared<StringScriptType>(false, 0)}});
|
||||
return GetFuncType(NumericScriptType::AwareFloat,
|
||||
{{StringScriptType::Dynamic}});
|
||||
}
|
||||
//endregion
|
||||
//region ToString
|
||||
|
@ -91,8 +91,7 @@ namespace Porygon::StandardLibraries{
|
|||
return new Evaluation::StringEvalValue(parameter);
|
||||
}
|
||||
static shared_ptr<GenericFunctionScriptType> GetToStringFuncType(){
|
||||
return GetFuncType(make_shared<StringScriptType>(false, 0),
|
||||
{{make_shared<ScriptType>(TypeClass::All)}});
|
||||
return GetFuncType(StringScriptType::Dynamic, {{make_shared<ScriptType>(TypeClass::All)}});
|
||||
}
|
||||
//endregion
|
||||
//region Type
|
||||
|
@ -113,8 +112,7 @@ namespace Porygon::StandardLibraries{
|
|||
}
|
||||
}
|
||||
static shared_ptr<GenericFunctionScriptType> GetTypeFuncType(){
|
||||
return GetFuncType(make_shared<StringScriptType>(false, 0),
|
||||
{{make_shared<ScriptType>(TypeClass::All)}});
|
||||
return GetFuncType(StringScriptType::Dynamic,{{make_shared<ScriptType>(TypeClass::All)}});
|
||||
}
|
||||
//endregion
|
||||
//region IsFloat
|
||||
|
@ -124,14 +122,14 @@ namespace Porygon::StandardLibraries{
|
|||
return new Evaluation::BooleanEvalValue(parameter->IsFloat());
|
||||
}
|
||||
static shared_ptr<GenericFunctionScriptType> GetIsFloatFuncType(){
|
||||
return GetFuncType(make_shared<ScriptType>(TypeClass::Bool),
|
||||
{{make_shared<NumericScriptType>(false, false)}});
|
||||
return GetFuncType(ScriptType::BoolType, {{NumericScriptType::Unaware}});
|
||||
}
|
||||
//endregion
|
||||
|
||||
//region Generic handling
|
||||
|
||||
static shared_ptr<GenericFunctionScriptType> GetFuncType(const shared_ptr<ScriptType>& result, const vector<vector<shared_ptr<ScriptType>>>& options){
|
||||
static shared_ptr<GenericFunctionScriptType> GetFuncType(const shared_ptr<const ScriptType>& result,
|
||||
const vector<vector<shared_ptr<const ScriptType>>>& options){
|
||||
auto funcType = make_shared<GenericFunctionScriptType>();
|
||||
for (const auto& o: options){
|
||||
auto option = new UserData::UserDataFunctionOption(result, o);
|
||||
|
|
|
@ -27,9 +27,9 @@ namespace Porygon::StandardLibraries {
|
|||
|
||||
//region templates
|
||||
|
||||
#define FLOAT_TYPE new NumericScriptType(true, true)
|
||||
#define INTEGER_TYPE new NumericScriptType(true, false)
|
||||
#define BOOL_TYPE new ScriptType(TypeClass::Bool)
|
||||
#define FLOAT_TYPE NumericScriptType::AwareFloat
|
||||
#define INTEGER_TYPE NumericScriptType::AwareInt
|
||||
#define BOOL_TYPE ScriptType::BoolType
|
||||
#define FUNCTION(fieldName) \
|
||||
[](void* obj) -> const Porygon::Evaluation::EvalValue* { \
|
||||
auto t = new Porygon::Evaluation::GenericFunctionEvalValue(make_shared<GenericFunctionScriptType>(), \
|
||||
|
@ -150,8 +150,9 @@ namespace Porygon::StandardLibraries {
|
|||
return new BooleanEvalValue(parameter1 < parameter2);
|
||||
}
|
||||
|
||||
static UserData::UserDataFunctionOption* CreateFunctionOption(ScriptType* returnType, std::vector<ScriptType*> params){
|
||||
return UserData::UserDataFunctionOption::FromRawPointers(returnType, std::move(params));
|
||||
static UserData::UserDataFunctionOption* CreateFunctionOption(const shared_ptr<const ScriptType>& returnType,
|
||||
const std::vector<shared_ptr<const ScriptType>>& params){
|
||||
return new UserData::UserDataFunctionOption(returnType, params);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,11 +24,16 @@ namespace Porygon::UserData {
|
|||
return make_shared<UserDataCollectionType>(keyType, valueType, true, true);
|
||||
}
|
||||
|
||||
static UserDataCollectionType* CreateIndexable(const ScriptType* keyType, const ScriptType* valueType){
|
||||
return new UserDataCollectionType(shared_ptr<const ScriptType>(keyType),
|
||||
static shared_ptr<UserDataCollectionType> CreateIndexable(const ScriptType* keyType, const ScriptType* valueType){
|
||||
return make_shared<UserDataCollectionType>(shared_ptr<const ScriptType>(keyType),
|
||||
shared_ptr<const ScriptType>(valueType), true, true);
|
||||
}
|
||||
|
||||
static UserDataCollectionType* CreateIndexableExtern(const ScriptType* keyType, const ScriptType* valueType){
|
||||
return new UserDataCollectionType(shared_ptr<const ScriptType>(keyType),
|
||||
shared_ptr<const ScriptType>(valueType), true, true);
|
||||
}
|
||||
|
||||
static shared_ptr<UserDataCollectionType> CreateIterable(const shared_ptr<const ScriptType>& valueType){
|
||||
return make_shared<UserDataCollectionType>(nullptr, valueType, false, true);
|
||||
}
|
||||
|
@ -42,7 +47,7 @@ namespace Porygon::UserData {
|
|||
if (!_indexable){
|
||||
return false;
|
||||
}
|
||||
return indexer->operator==(_keyType.get());
|
||||
return indexer->operator==(_keyType);
|
||||
}
|
||||
|
||||
[[nodiscard]] shared_ptr<const ScriptType> GetIndexedType(const ScriptType* indexer) const final{
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
namespace Porygon::UserData{
|
||||
extern "C" {
|
||||
UserDataCollectionType* CreateCollectionType(const ScriptType* keyType, const ScriptType* valueType){
|
||||
return UserDataCollectionType::CreateIndexable(keyType, valueType);
|
||||
return UserDataCollectionType::CreateIndexableExtern(keyType, valueType);
|
||||
}
|
||||
UserDataCollectionValue* CreateCollectionValue(UserDataCollectionType* type, void* obj,
|
||||
const EvalValue* (*get)(void*, const EvalValue*),
|
||||
void (*set)(void*, const EvalValue*, const EvalValue*),
|
||||
Iterator* (*getIterator)(void*)){
|
||||
return new UserDataCollectionValue(type, new UserDataCollectionHelper(obj, get, set, getIterator));
|
||||
return new UserDataCollectionValue(shared_ptr<UserDataCollectionType>(type), new UserDataCollectionHelper(obj, get, set, getIterator));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,18 +36,18 @@ namespace Porygon::UserData {
|
|||
};
|
||||
|
||||
class UserDataCollectionValue : public Evaluation::EvalValue{
|
||||
shared_ptr<UserDataCollectionType> _type;
|
||||
shared_ptr<const UserDataCollectionType> _type;
|
||||
shared_ptr<const UserDataCollectionHelper> _helper;
|
||||
const size_t _hash;
|
||||
UserDataCollectionValue(shared_ptr<UserDataCollectionType> type,
|
||||
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(ScriptType* type, const UserDataCollectionHelper* helper)
|
||||
: _type(dynamic_cast<UserDataCollectionType*>(type)), _helper(helper), _hash(Utilities::Random::Get())
|
||||
UserDataCollectionValue(shared_ptr<const ScriptType> type, const UserDataCollectionHelper* helper)
|
||||
: _type(dynamic_pointer_cast<const UserDataCollectionType>(type)), _helper(helper), _hash(Utilities::Random::Get())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#define PORYGONLANG_USERDATAFIELD_HPP
|
||||
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "../Evaluator/EvalValues/EvalValue.hpp"
|
||||
#include "../Evaluator/EvalValues/NumericEvalValue.hpp"
|
||||
|
||||
|
@ -12,10 +14,17 @@ namespace Porygon::UserData{
|
|||
const Evaluation::EvalValue* (*_get)(void* obj);
|
||||
void (*_set)(void* obj, const Evaluation::EvalValue* val);
|
||||
public:
|
||||
UserDataField(const ScriptType* type, const Evaluation::EvalValue* (*getter)(void* obj), void (*setter)(void* obj, const Evaluation::EvalValue* val))
|
||||
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){
|
||||
}
|
||||
|
||||
UserDataField(shared_ptr<const ScriptType> type, const Evaluation::EvalValue* (*getter)(void* obj),
|
||||
void (*setter)(void* obj, const Evaluation::EvalValue* val))
|
||||
: _type(std::move(type)), _get(getter), _set(setter){
|
||||
}
|
||||
|
||||
|
||||
[[nodiscard]]
|
||||
inline shared_ptr<const ScriptType> GetType(){
|
||||
return _type;
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
namespace Porygon::UserData{
|
||||
class UserDataFunctionOption : public GenericFunctionOption{
|
||||
public:
|
||||
UserDataFunctionOption(std::shared_ptr<ScriptType> returnType, vector<shared_ptr<ScriptType>> parameterTypes)
|
||||
UserDataFunctionOption(std::shared_ptr<const ScriptType> returnType, vector<shared_ptr<const ScriptType>> parameterTypes)
|
||||
: GenericFunctionOption(std::move(returnType), std::move(parameterTypes)) {
|
||||
|
||||
}
|
||||
static UserDataFunctionOption* FromRawPointers(ScriptType* returnType, vector<ScriptType*> parameterTypes){
|
||||
auto rt = shared_ptr<ScriptType>(returnType);
|
||||
auto p = vector<shared_ptr<ScriptType>>(parameterTypes.size());
|
||||
static UserDataFunctionOption* FromRawPointers(const ScriptType* returnType, vector<const ScriptType*> parameterTypes){
|
||||
auto rt = shared_ptr<const ScriptType>(returnType);
|
||||
auto p = vector<shared_ptr<const ScriptType>>(parameterTypes.size());
|
||||
for (size_t i = 0; i < parameterTypes.size(); i++){
|
||||
p[i] = shared_ptr<ScriptType>(parameterTypes[i]);
|
||||
p[i] = shared_ptr<const ScriptType>(parameterTypes[i]);
|
||||
}
|
||||
return new UserDataFunctionOption(rt, p);
|
||||
}
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
fields \
|
||||
PORYGON_USERDATA_END()
|
||||
|
||||
#define PORYGON_INTEGER_TYPE ((Porygon::ScriptType*)new Porygon::NumericScriptType(true, false))
|
||||
#define PORYGON_FLOAT_TYPE ((Porygon::ScriptType*)new Porygon::NumericScriptType(true, true))
|
||||
#define PORYGON_INTEGER_TYPE (NumericScriptType::AwareInt)
|
||||
#define PORYGON_FLOAT_TYPE (NumericScriptType::AwareFloat)
|
||||
#define PORYGON_STRING_TYPE ((Porygon::ScriptType*)new Porygon::StringScriptType(false, 0))
|
||||
#define PORYGON_INDEXABLE_TYPE(keyType, valueType) \
|
||||
((Porygon::ScriptType*)Porygon::UserData::UserDataCollectionType::CreateIndexable(keyType, valueType))
|
||||
(Porygon::UserData::UserDataCollectionType::CreateIndexable(keyType, valueType))
|
||||
|
||||
#define PORYGON_FIELD(fieldName, fieldType, getterHelper, setterHelper) \
|
||||
{ \
|
||||
|
@ -101,7 +101,7 @@
|
|||
Porygon::Utilities::HashedString::ConstHash(#fieldName), \
|
||||
new Porygon::UserData::UserDataField( \
|
||||
new Porygon::GenericFunctionScriptType( \
|
||||
Porygon::UserData::UserDataFunctionOption::FromRawPointers(returnType, {__VA_ARGS__} )), \
|
||||
new Porygon::UserData::UserDataFunctionOption(returnType, {__VA_ARGS__} )), \
|
||||
\
|
||||
\
|
||||
[](void* obj) -> const Porygon::Evaluation::EvalValue* { \
|
||||
|
@ -117,7 +117,7 @@
|
|||
|
||||
|
||||
#define PORYGON_INTEGER_FUNCTION(fieldName, ...) \
|
||||
PORYGON_FUNCTION(fieldName, new Porygon::NumericScriptType(true, false), __VA_ARGS__ )
|
||||
PORYGON_FUNCTION(fieldName, Porygon::NumericScriptType::AwareInt, __VA_ARGS__ )
|
||||
|
||||
|
||||
/*!
|
||||
|
|
Loading…
Reference in New Issue