Support having no getter/setters on a userdata field
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
7c345d85e8
commit
5cd05053e1
|
@ -73,12 +73,13 @@ BoundStatement* Binder::BindAssignmentStatement(const ParsedStatement *statement
|
||||||
|
|
||||||
BoundStatement *Binder::BindIndexAssignmentStatement(const ParsedStatement *statement) {
|
BoundStatement *Binder::BindIndexAssignmentStatement(const ParsedStatement *statement) {
|
||||||
auto s = (ParsedIndexAssignmentStatement*) statement;
|
auto s = (ParsedIndexAssignmentStatement*) statement;
|
||||||
auto boundIndexExpression = this -> BindIndexExpression((IndexExpression*)s->GetIndexExpression());
|
auto boundIndexExpression = this -> BindIndexExpression((IndexExpression*)s->GetIndexExpression(), true);
|
||||||
auto valueExpression = this -> BindExpression(s->GetValueExpression());
|
auto valueExpression = this -> BindExpression(s->GetValueExpression());
|
||||||
if (boundIndexExpression->GetType()->operator!=(valueExpression->GetType().get())){
|
if (boundIndexExpression->GetType()->operator!=(valueExpression->GetType().get())){
|
||||||
this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::InvalidTableValueType, statement->GetStartPosition(), statement->GetLength());
|
this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::InvalidTableValueType, statement->GetStartPosition(), statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BoundIndexAssignmentStatement(boundIndexExpression, valueExpression);
|
return new BoundIndexAssignmentStatement(boundIndexExpression, valueExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +207,7 @@ BoundExpression* Binder::BindExpression(const ParsedExpression* expression){
|
||||||
return this->BindFunctionCall((FunctionCallExpression*)expression);
|
return this->BindFunctionCall((FunctionCallExpression*)expression);
|
||||||
|
|
||||||
case ParsedExpressionKind ::Indexer:
|
case ParsedExpressionKind ::Indexer:
|
||||||
return this->BindIndexExpression((IndexExpression*)expression);
|
return this->BindIndexExpression((IndexExpression*)expression, false);
|
||||||
case ParsedExpressionKind::NumericalTable:
|
case ParsedExpressionKind::NumericalTable:
|
||||||
return this -> BindNumericalTableExpression((ParsedNumericalTableExpression*)expression);
|
return this -> BindNumericalTableExpression((ParsedNumericalTableExpression*)expression);
|
||||||
case ParsedExpressionKind ::Table:
|
case ParsedExpressionKind ::Table:
|
||||||
|
@ -415,15 +416,34 @@ BoundExpression* Binder::BindFunctionCall(const FunctionCallExpression* expressi
|
||||||
expression->GetStartPosition(), expression->GetLength());
|
expression->GetStartPosition(), expression->GetLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundExpression *Binder::BindIndexExpression(const IndexExpression *expression) {
|
BoundExpression *Binder::BindIndexExpression(const IndexExpression *expression, bool setter) {
|
||||||
auto indexer = this->BindExpression(expression->GetIndexer());
|
auto indexer = this->BindExpression(expression->GetIndexer());
|
||||||
auto index = this->BindExpression(expression->GetIndex());
|
auto index = this->BindExpression(expression->GetIndex());
|
||||||
|
|
||||||
if (!indexer->GetType()->CanBeIndexedWith(index->GetType().get())){
|
auto indexerType = indexer -> GetType();
|
||||||
|
if (!indexerType->CanBeIndexedWith(index->GetType().get())){
|
||||||
this->_scriptData->Diagnostics->LogError(DiagnosticCode::CantIndex, index->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(DiagnosticCode::CantIndex, index->GetStartPosition(),
|
||||||
index->GetLength());
|
index->GetLength());
|
||||||
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||||
}
|
}
|
||||||
|
if (indexerType -> GetClass() == TypeClass::UserData){
|
||||||
|
auto stringKey = dynamic_pointer_cast<StringScriptType>(index -> GetType());
|
||||||
|
auto field = dynamic_pointer_cast<UserDataScriptType>(indexerType) -> GetField(stringKey->GetHashValue());
|
||||||
|
if (!setter){
|
||||||
|
if (!field->HasGetter()){
|
||||||
|
this->_scriptData->Diagnostics->LogError(DiagnosticCode::UserDataFieldNoGetter, index->GetStartPosition(),
|
||||||
|
index->GetLength());
|
||||||
|
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
if (!field->HasSetter()){
|
||||||
|
this->_scriptData->Diagnostics->LogError(DiagnosticCode::UserDataFieldNoSetter, index->GetStartPosition(),
|
||||||
|
index->GetLength());
|
||||||
|
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto resultType = indexer->GetType()->GetIndexedType(index->GetType().get());
|
auto resultType = indexer->GetType()->GetIndexedType(index->GetType().get());
|
||||||
return new BoundIndexExpression(indexer, index, resultType, expression->GetStartPosition(), expression->GetLength());
|
return new BoundIndexExpression(indexer, index, resultType, expression->GetStartPosition(), expression->GetLength());
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ class Binder {
|
||||||
BoundExpression *BindBinaryOperator(const BinaryExpression *expression);
|
BoundExpression *BindBinaryOperator(const BinaryExpression *expression);
|
||||||
BoundExpression *BindUnaryOperator(const UnaryExpression *expression);
|
BoundExpression *BindUnaryOperator(const UnaryExpression *expression);
|
||||||
BoundExpression *BindFunctionCall(const FunctionCallExpression *expression);
|
BoundExpression *BindFunctionCall(const FunctionCallExpression *expression);
|
||||||
BoundExpression *BindIndexExpression(const IndexExpression *expression);
|
BoundExpression *BindIndexExpression(const IndexExpression *expression, bool setter);
|
||||||
BoundExpression *BindNumericalTableExpression(const ParsedNumericalTableExpression *expression);
|
BoundExpression *BindNumericalTableExpression(const ParsedNumericalTableExpression *expression);
|
||||||
BoundExpression *BindTableExpression(const ParsedTableExpression * expression);
|
BoundExpression *BindTableExpression(const ParsedTableExpression * expression);
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -23,6 +23,8 @@ enum class DiagnosticCode{
|
||||||
ConditionNotABool,
|
ConditionNotABool,
|
||||||
InvalidTableValueType,
|
InvalidTableValueType,
|
||||||
InvalidTypeName,
|
InvalidTypeName,
|
||||||
|
UserDataFieldNoGetter,
|
||||||
|
UserDataFieldNoSetter
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //PORYGONLANG_DIAGNOSTICCODE_HPP
|
#endif //PORYGONLANG_DIAGNOSTICCODE_HPP
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
class UserDataField {
|
class UserDataField {
|
||||||
shared_ptr<ScriptType> _type;
|
shared_ptr<ScriptType> _type;
|
||||||
EvalValue* (*_get)(void* obj);
|
EvalValue* (*_get)(void* obj);
|
||||||
void (*_set)(void* obj, EvalValue*);
|
void (*_set)(void* obj, EvalValue* val);
|
||||||
public:
|
public:
|
||||||
UserDataField(ScriptType* type, EvalValue* (*getter)(void* obj), void (*setter)(void* obj, EvalValue*)){
|
UserDataField(ScriptType* type, EvalValue* (*getter)(void* obj), void (*setter)(void* obj, EvalValue* val)){
|
||||||
_type = shared_ptr<ScriptType>(type);
|
_type = shared_ptr<ScriptType>(type);
|
||||||
_get = getter;
|
_get = getter;
|
||||||
_set = setter;
|
_set = setter;
|
||||||
|
@ -21,10 +21,18 @@ public:
|
||||||
return _type;
|
return _type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HasGetter(){
|
||||||
|
return _get != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
EvalValue* Get(void* obj){
|
EvalValue* Get(void* obj){
|
||||||
return this ->_get(obj);
|
return this ->_get(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HasSetter(){
|
||||||
|
return _set != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void Set(void* obj, EvalValue* val){
|
void Set(void* obj, EvalValue* val){
|
||||||
this->_set(obj, val);
|
this->_set(obj, val);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,10 @@ public:
|
||||||
return _userData->ContainsField(str->GetHashValue());
|
return _userData->ContainsField(str->GetHashValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UserDataField* GetField(uint32_t id){
|
||||||
|
return _userData -> GetField(id);
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<ScriptType> GetIndexedType(ScriptType* indexer) final{
|
shared_ptr<ScriptType> GetIndexedType(ScriptType* indexer) final{
|
||||||
auto stringKey = (StringScriptType*)indexer;
|
auto stringKey = (StringScriptType*)indexer;
|
||||||
if (stringKey->IsKnownAtBind()){
|
if (stringKey->IsKnownAtBind()){
|
||||||
|
|
Loading…
Reference in New Issue