Implements if, elseif and else statements
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:
@@ -16,7 +16,8 @@ enum class ParsedStatementKind{
|
||||
Expression,
|
||||
Assignment,
|
||||
FunctionDeclaration,
|
||||
Return
|
||||
Return,
|
||||
Conditional
|
||||
};
|
||||
|
||||
class ParsedStatement {
|
||||
@@ -187,4 +188,47 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class ParsedConditionalStatement : public ParsedStatement{
|
||||
ParsedExpression* _condition;
|
||||
ParsedStatement* _block;
|
||||
// This can be either else if or else
|
||||
ParsedStatement* _elseStatement;
|
||||
public:
|
||||
ParsedConditionalStatement(ParsedExpression* condition, ParsedStatement* block, unsigned int start, unsigned int length)
|
||||
: ParsedStatement(start, length){
|
||||
_condition = condition;
|
||||
_block = block;
|
||||
_elseStatement = nullptr;
|
||||
}
|
||||
|
||||
ParsedConditionalStatement(ParsedExpression* condition, ParsedStatement* block, ParsedStatement* nextStatement, unsigned int start, unsigned int length)
|
||||
: ParsedStatement(start, length){
|
||||
_condition = condition;
|
||||
_block = block;
|
||||
_elseStatement = nextStatement;
|
||||
}
|
||||
|
||||
~ParsedConditionalStatement() final{
|
||||
delete _condition;
|
||||
delete _block;
|
||||
delete _elseStatement;
|
||||
}
|
||||
|
||||
ParsedStatementKind GetKind() final{
|
||||
return ParsedStatementKind ::Conditional;
|
||||
}
|
||||
|
||||
ParsedExpression* GetCondition(){
|
||||
return _condition;
|
||||
}
|
||||
|
||||
ParsedStatement* GetBlock(){
|
||||
return _block;
|
||||
}
|
||||
|
||||
ParsedStatement* GetElseStatement(){
|
||||
return _elseStatement;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //PORYGONLANG_PARSEDSTATEMENT_HPP
|
||||
|
||||
@@ -23,6 +23,10 @@ IToken *Parser::Peek() {
|
||||
return this -> _tokens[_position];
|
||||
}
|
||||
|
||||
IToken *Parser::PeekAt(int offset) {
|
||||
return this -> _tokens[_position + offset];
|
||||
}
|
||||
|
||||
IToken *Parser::Next() {
|
||||
this -> _position++;
|
||||
return this -> _tokens[_position - 1];
|
||||
@@ -34,6 +38,7 @@ ParsedStatement* Parser::ParseStatement(IToken* current){
|
||||
case TokenKind ::LocalKeyword: return this -> ParseAssignment(current);
|
||||
case TokenKind ::FunctionKeyword: return this -> ParseFunctionDeclaration(current);
|
||||
case TokenKind ::ReturnKeyword: return this->ParseReturnStatement(current);
|
||||
case TokenKind ::IfKeyword: return this -> ParseIfStatement(current, false);
|
||||
default: break;
|
||||
}
|
||||
if (this->Peek()->GetKind() == TokenKind::AssignmentToken){
|
||||
@@ -144,6 +149,26 @@ ParsedStatement* Parser::ParseReturnStatement(IToken* current){
|
||||
return new ParsedReturnStatement(expression, start, expression->GetEndPosition() - start);
|
||||
}
|
||||
|
||||
ParsedStatement* Parser::ParseIfStatement(IToken* current, bool isElseIf){
|
||||
auto condition = this->ParseExpression(this->Next());
|
||||
auto next = this -> Next();
|
||||
if (next->GetKind() != TokenKind::ThenKeyword){
|
||||
this -> ScriptData -> Diagnostics -> LogError(DiagnosticCode::UnexpectedToken, next->GetStartPosition(), next->GetLength());
|
||||
return new ParsedBadStatement(next->GetStartPosition(), next->GetLength());
|
||||
}
|
||||
auto block = this -> ParseBlock({TokenKind ::EndKeyword, TokenKind ::ElseKeyword, TokenKind ::ElseIfKeyword});
|
||||
auto closeToken = this->PeekAt(-1);
|
||||
auto start = current->GetStartPosition();
|
||||
if (closeToken->GetKind() == TokenKind::ElseIfKeyword){
|
||||
auto elseIfStatement = this -> ParseIfStatement(closeToken, true);
|
||||
return new ParsedConditionalStatement(condition, block, elseIfStatement, start, elseIfStatement->GetEndPosition() - start);
|
||||
} else if (closeToken->GetKind() == TokenKind::ElseKeyword){
|
||||
auto elseStatement = this -> ParseBlock({TokenKind ::EndKeyword});
|
||||
return new ParsedConditionalStatement(condition, block, elseStatement, start, elseStatement->GetEndPosition() - start);
|
||||
}
|
||||
return new ParsedConditionalStatement(condition, block, start, block->GetEndPosition() - start);
|
||||
}
|
||||
|
||||
ParsedExpression* Parser::ParseExpression(IToken* current){
|
||||
auto expression = this -> ParseBinaryExpression(current, OperatorPrecedence::No);
|
||||
auto peekKind = this->Peek()->GetKind();
|
||||
|
||||
@@ -30,6 +30,7 @@ class Parser {
|
||||
ParsedStatement *ParseBlock(const vector<TokenKind>& endTokens);
|
||||
ParsedStatement* ParseFunctionDeclaration(IToken* current);
|
||||
ParsedStatement *ParseReturnStatement(IToken *current);
|
||||
ParsedStatement *ParseIfStatement(IToken *current, bool isElseIf);
|
||||
|
||||
ParsedExpression* ParseExpression(IToken* current);
|
||||
ParsedExpression* ParseBinaryExpression(IToken* current, OperatorPrecedence parentPrecedence);
|
||||
@@ -46,6 +47,8 @@ public:
|
||||
ScriptData = scriptData;
|
||||
}
|
||||
|
||||
|
||||
IToken *PeekAt(int offset);
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user