Implements indexing with period identifier style (`foo.bar`)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -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());
|
||||
|
||||
@@ -36,6 +36,7 @@ class Binder {
|
||||
public:
|
||||
static BoundScriptStatement* Bind(Script* script, const ParsedScriptStatement* s, BoundScope* scriptScope);
|
||||
|
||||
BoundExpression *BindPeriodIndexExpression(const PeriodIndexExpression *expression, bool setter);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ enum class BoundExpressionKind{
|
||||
Binary,
|
||||
FunctionCall,
|
||||
Index,
|
||||
PeriodIndex,
|
||||
NumericalTable,
|
||||
Table,
|
||||
};
|
||||
@@ -279,6 +280,31 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class BoundPeriodIndexExpression : public BoundExpression {
|
||||
BoundExpression* _indexableExpression;
|
||||
HashedString _index;
|
||||
public:
|
||||
BoundPeriodIndexExpression(BoundExpression* indexableExpression, HashedString index, shared_ptr<ScriptType> result,
|
||||
unsigned int start, unsigned int length)
|
||||
: BoundExpression(start, length, std::move(result)), _indexableExpression(indexableExpression), _index(index) {}
|
||||
|
||||
~BoundPeriodIndexExpression() final{
|
||||
delete _indexableExpression;
|
||||
}
|
||||
|
||||
const BoundExpressionKind GetKind() const final{
|
||||
return BoundExpressionKind ::PeriodIndex;
|
||||
}
|
||||
|
||||
const BoundExpression* GetIndexableExpression() const{
|
||||
return _indexableExpression;
|
||||
}
|
||||
|
||||
const HashedString GetIndex() const{
|
||||
return _index;
|
||||
}
|
||||
};
|
||||
|
||||
class BoundNumericalTableExpression : public BoundExpression{
|
||||
const vector<BoundExpression*> _expressions;
|
||||
public:
|
||||
|
||||
@@ -129,7 +129,7 @@ class BoundIndexAssignmentStatement : public BoundStatement{
|
||||
const BoundExpression* _indexExpression;
|
||||
const BoundExpression* _valueExpression;
|
||||
public:
|
||||
BoundIndexAssignmentStatement(BoundExpression* index, BoundExpression* value)
|
||||
BoundIndexAssignmentStatement(const BoundExpression* index, BoundExpression* value)
|
||||
: _indexExpression(index), _valueExpression(value)
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user