Improved performance when binding by reusing many common scripttype objects
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Deukhoofd 2019-09-01 15:35:45 +02:00
parent 79873d9d6a
commit a3e77f650a
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
14 changed files with 141 additions and 113 deletions

View File

@ -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(),

View File

@ -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),

View File

@ -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));

View File

@ -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)) {
}

View File

@ -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;

View File

@ -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;
}
};
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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{

View File

@ -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));
}
}
}

View File

@ -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())
{
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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__ )
/*!