Implements numeric for loops
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:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user