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,6 +44,8 @@ namespace Porygon::Parser {
return this->ParseReturnStatement(current);
case TokenKind::IfKeyword:
return this->ParseIfStatement(current);
case TokenKind ::ForKeyword:
return this->ParseForStatement(current);
default:
break;
}
@@ -191,7 +193,6 @@ namespace Porygon::Parser {
}
ParsedStatement *Parser::ParseReturnStatement(const IToken *current) {
//TODO: if next token is on a different line, don't parse it as return expression.
auto start = current->GetStartPosition();
auto startLine = this -> ScriptData -> Diagnostics ->GetLineFromPosition(start);
if (startLine != this -> ScriptData -> Diagnostics -> GetLineFromPosition(this -> Peek() -> GetStartPosition())){
@@ -224,6 +225,55 @@ namespace Porygon::Parser {
return new ParsedConditionalStatement(condition, block, start, block->GetEndPosition() - start);
}
ParsedStatement *Parser::ParseForStatement(const IToken *current) {
auto identifier = this -> Next();
if (this -> Peek()->GetKind() == TokenKind::AssignmentToken){
return ParseNumericForStatement(identifier);
} else {
return ParseGenericForStatement(identifier);
}
}
ParsedStatement *Parser::ParseNumericForStatement(const IToken *current) {
auto identifier = (IdentifierToken*)current;
this->Next(); // consume assignment token
bool hasErrors = false;
auto start = this ->ParseExpression(this ->Next());
auto comma = this -> Next(); // consume comma token
if (comma->GetKind() != TokenKind::CommaToken){
hasErrors = true;
this->ScriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::UnexpectedToken, comma->GetStartPosition(),
comma->GetLength());
}
auto end = this -> ParseExpression(this -> Next());
ParsedExpression *step = nullptr;
if (this -> Peek()->GetKind() == TokenKind::CommaToken){
this -> Next();
step = this -> ParseExpression(this -> Next());
}
auto doToken = this ->Next();
if (doToken->GetKind() != TokenKind::DoKeyword && !hasErrors){
hasErrors = true;
this->ScriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::UnexpectedToken, doToken->GetStartPosition(),
doToken->GetLength());
}
auto block = this -> ParseBlock({TokenKind ::EndKeyword});
auto startPos = current->GetStartPosition();
if (hasErrors){
return new ParsedBadStatement(startPos, block -> GetEndPosition() - startPos);
}
return new ParsedNumericalForStatement(identifier->GetValue(), start, end, step, block, startPos, block->GetEndPosition() - startPos);
}
ParsedStatement *Parser::ParseGenericForStatement(const IToken *current) {
return nullptr;
}
/////////////////
// Expressions //
/////////////////
ParsedExpression *Parser::ParseExpression(const IToken *current) {
auto expression = this->ParseBinaryExpression(current, OperatorPrecedence::No);
auto peekKind = this->Peek()->GetKind();