Implements numeric for loops
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2019-06-22 17:35:33 +02:00
parent 694b0ac0c0
commit e472dcec1c
16 changed files with 311 additions and 23 deletions

View File

@@ -44,7 +44,8 @@ namespace Porygon::Binder {
return this->BindReturnStatement(statement);
case ParsedStatementKind::Conditional:
return this->BindConditionalStatement(statement);
case ParsedStatementKind::NumericalFor:
return this->BindNumericalForStatement(statement);
case ParsedStatementKind::Bad:
return new BoundBadStatement();
}
@@ -214,6 +215,48 @@ namespace Porygon::Binder {
return new BoundConditionalStatement(boundCondition, boundBlock, elseStatement);
}
BoundStatement *Binder::BindNumericalForStatement(const ParsedStatement *statement) {
auto forStatement = (ParsedNumericalForStatement*) statement;
auto identifier = forStatement->GetIdentifier();
auto start = this -> BindExpression(forStatement->GetStart());
auto end = this -> BindExpression(forStatement->GetEnd());
auto parsedStep = forStatement -> GetStep();
BoundExpression* step = nullptr;
if (parsedStep != nullptr){
step = this -> BindExpression(parsedStep);
}
if (start -> GetType()->GetClass() != TypeClass::Number){
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NumericalForArgumentNotANumber, start->GetStartPosition(),
start->GetLength());
return new BoundBadStatement();
}
if (end -> GetType()->GetClass() != TypeClass::Number){
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NumericalForArgumentNotANumber, end->GetStartPosition(),
end->GetLength());
return new BoundBadStatement();
}
if (step != nullptr && step -> GetType()->GetClass() != TypeClass::Number){
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NumericalForArgumentNotANumber, step->GetStartPosition(),
step->GetLength());
return new BoundBadStatement();
}
this -> _scope ->GoInnerScope();
auto variableKey = this -> _scope ->CreateExplicitLocal(identifier.GetHash(), make_shared<NumericScriptType>(true, false));
if (variableKey.GetResult() != VariableAssignmentResult::Ok){
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
statement->GetLength());
return new BoundBadStatement();
}
auto block = this -> BindBlockStatement(forStatement->GetBlock());
this -> _scope ->GoOuterScope();
return new BoundNumericalForStatement(variableKey.GetKey(), start, end, step, block);
}
/////////////////
// Expressions //
/////////////////
BoundExpression *Binder::BindExpression(const ParsedExpression *expression) {
switch (expression->GetKind()) {
case ParsedExpressionKind::LiteralInteger:
@@ -586,4 +629,5 @@ namespace Porygon::Binder {
return new BoundTableExpression((BoundBlockStatement *) block, tableType, expression->GetStartPosition(),
expression->GetLength());
}
}