Implemented generic for loops
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2019-06-26 16:19:34 +02:00
parent cfd558b718
commit d86e9ba8ae
18 changed files with 325 additions and 44 deletions

View File

@@ -46,6 +46,8 @@ namespace Porygon::Binder {
return this->BindConditionalStatement(statement);
case ParsedStatementKind::NumericalFor:
return this->BindNumericalForStatement(statement);
case ParsedStatementKind::GenericFor:
return this -> BindGenericForStatement(statement);
case ParsedStatementKind::Bad:
return new BoundBadStatement();
}
@@ -105,7 +107,7 @@ namespace Porygon::Binder {
return new BoundIndexAssignmentStatement(indexable, valueExpression);
}
std::shared_ptr<ScriptType> ParseTypeIdentifier(HashedString s) {
std::shared_ptr<ScriptType> ParseTypeIdentifier(const HashedString& s) {
auto hash = s.GetHash();
switch (hash) {
case HashedString::ConstHash("number"):
@@ -253,6 +255,46 @@ namespace Porygon::Binder {
return new BoundNumericalForStatement(variableKey.GetKey(), start, end, step, block);
}
BoundStatement *Binder::BindGenericForStatement(const ParsedStatement *statement) {
auto genericFor = (ParsedGenericForStatement*) statement;
auto boundIterator = BindExpression(genericFor -> GetIteratorExpression());
const auto& itType = boundIterator -> GetType();
if (!itType -> CanBeIterated()){
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantIterateExpression, statement->GetStartPosition(),
statement->GetLength());
return new BoundBadStatement();
}
auto keyType = itType -> GetIteratorKeyType();
auto keyIdentifier = genericFor -> GetKeyIdentifier();
this -> _scope -> GoInnerScope();
auto keyVariableAssignment = this -> _scope -> CreateExplicitLocal(keyIdentifier, keyType);
if (keyVariableAssignment.GetResult() != VariableAssignmentResult::Ok){
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
statement->GetLength());
return new BoundBadStatement();
}
auto keyVariable = keyVariableAssignment.GetKey();
auto valueIdentifier = genericFor -> GetValueIdentifier();
auto isValueVariableDefined = valueIdentifier.GetHash() != 0;
BoundVariableKey* valueVariable = nullptr;
if (isValueVariableDefined){
auto valueType = itType -> GetIndexedType(keyType.get());
auto valueVariableAssignment = this -> _scope -> CreateExplicitLocal(valueIdentifier, valueType);
if (valueVariableAssignment.GetResult() != VariableAssignmentResult::Ok){
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
statement->GetLength());
return new BoundBadStatement();
}
valueVariable = valueVariableAssignment.GetKey();
}
auto boundBlock = this -> BindBlockStatement(genericFor -> GetBlock());
this -> _scope -> GoOuterScope();
return new BoundGenericForStatement(keyVariable, valueVariable, boundIterator, boundBlock);
}
/////////////////
// Expressions //
/////////////////
@@ -629,5 +671,4 @@ namespace Porygon::Binder {
return new BoundTableExpression((BoundBlockStatement *) block, tableType, expression->GetStartPosition(),
expression->GetLength());
}
}