Implements indexing with period identifier style (`foo.bar`)
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2019-06-17 15:45:33 +02:00
parent d06b04cae9
commit d91caa7f32
17 changed files with 207 additions and 32 deletions

View File

@@ -73,15 +73,21 @@ BoundStatement* Binder::BindAssignmentStatement(const ParsedStatement *statement
BoundStatement *Binder::BindIndexAssignmentStatement(const ParsedStatement *statement) {
auto s = (ParsedIndexAssignmentStatement*) statement;
auto boundIndexExpression = this -> BindIndexExpression((IndexExpression*)s->GetIndexExpression(), true);
auto indexExp = s -> GetIndexExpression();
const BoundExpression* indexable;
if (indexExp->GetKind() == ParsedExpressionKind::Indexer){
indexable = this -> BindIndexExpression((IndexExpression*)indexExp, true);
} else{
indexable = this -> BindPeriodIndexExpression((PeriodIndexExpression*)indexExp, true);
}
auto valueExpression = this -> BindExpression(s->GetValueExpression());
auto boundIndexType = boundIndexExpression -> GetType();
auto boundIndexType = indexable -> GetType();
if (boundIndexType ->GetClass() != TypeClass ::Error && boundIndexType->operator!=(valueExpression->GetType().get())){
this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::InvalidTableValueType, statement->GetStartPosition(), statement->GetLength());
return new BoundBadStatement();
}
return new BoundIndexAssignmentStatement(boundIndexExpression, valueExpression);
return new BoundIndexAssignmentStatement(indexable, valueExpression);
}
std::shared_ptr<ScriptType> ParseTypeIdentifier(HashedString s){
@@ -209,6 +215,8 @@ BoundExpression* Binder::BindExpression(const ParsedExpression* expression){
case ParsedExpressionKind ::Indexer:
return this->BindIndexExpression((IndexExpression*)expression, false);
case ParsedExpressionKind::PeriodIndexer:
return this -> BindPeriodIndexExpression((PeriodIndexExpression*)expression, false);
case ParsedExpressionKind::NumericalTable:
return this -> BindNumericalTableExpression((ParsedNumericalTableExpression*)expression);
case ParsedExpressionKind ::Table:
@@ -449,6 +457,37 @@ BoundExpression *Binder::BindIndexExpression(const IndexExpression *expression,
return new BoundIndexExpression(indexer, index, resultType, expression->GetStartPosition(), expression->GetLength());
}
BoundExpression* Binder::BindPeriodIndexExpression(const PeriodIndexExpression* expression, bool setter){
auto indexer = this->BindExpression(expression->GetIndexer());
const auto& identifier = expression->GetIndex();
const auto& indexerType = indexer -> GetType();
if (!indexerType -> CanBeIndexedWithIdentifier(identifier.GetHash())){
this->_scriptData->Diagnostics->LogError(DiagnosticCode::CantIndex, expression->GetStartPosition(),
expression->GetLength());
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
}
if (indexerType -> GetClass() == TypeClass::UserData){
auto field = dynamic_pointer_cast<UserDataScriptType>(indexerType) -> GetField(identifier . GetHash());
if (!setter){
if (!field->HasGetter()){
this->_scriptData->Diagnostics->LogError(DiagnosticCode::UserDataFieldNoGetter, expression->GetStartPosition(),
expression->GetLength());
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
}
} else{
if (!field->HasSetter()){
this->_scriptData->Diagnostics->LogError(DiagnosticCode::UserDataFieldNoSetter, expression->GetStartPosition(),
expression->GetLength());
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
}
}
}
auto resultType = indexer->GetType()->GetIndexedType(identifier . GetHash());
return new BoundPeriodIndexExpression(indexer, identifier, resultType, expression->GetStartPosition(), expression->GetLength());
}
BoundExpression* Binder::BindNumericalTableExpression(const ParsedNumericalTableExpression* expression){
auto expressions = expression->GetExpressions();
auto boundExpressions = vector<BoundExpression*>(expressions-> size());