Implements parsing function declarations
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "Parser.hpp"
|
||||
#include "UnaryOperatorKind.hpp"
|
||||
#include "BinaryOperatorKind.hpp"
|
||||
#include "TypedVariableIdentifier.hpp"
|
||||
|
||||
|
||||
ParsedScriptStatement* Parser::Parse() {
|
||||
@@ -11,9 +12,6 @@ ParsedScriptStatement* Parser::Parse() {
|
||||
if (next->GetKind() == TokenKind::EndOfFile){
|
||||
break;
|
||||
}
|
||||
if (next->GetKind() == TokenKind::WhiteSpace){
|
||||
continue;
|
||||
}
|
||||
statements.push_back(this -> ParseStatement(next));
|
||||
}
|
||||
return new ParsedScriptStatement(statements);
|
||||
@@ -29,9 +27,13 @@ IToken *Parser::Next() {
|
||||
}
|
||||
|
||||
ParsedStatement* Parser::ParseStatement(IToken* current){
|
||||
if (current->GetKind() == TokenKind::LocalKeyword){
|
||||
return ParseAssignment(current);
|
||||
} else if (this->Peek()->GetKind() == TokenKind::AssignmentToken){
|
||||
auto currentKind = current->GetKind();
|
||||
switch (currentKind){
|
||||
case TokenKind ::LocalKeyword: return this -> ParseAssignment(current);
|
||||
case TokenKind ::FunctionKeyword: return this -> ParseFunctionDeclaration(current);
|
||||
default: break;
|
||||
}
|
||||
if (this->Peek()->GetKind() == TokenKind::AssignmentToken){
|
||||
return ParseAssignment(current);
|
||||
}
|
||||
return new ParsedExpressionStatement(this -> ParseExpression(current));
|
||||
@@ -62,8 +64,83 @@ ParsedStatement *Parser::ParseAssignment(IToken *current) {
|
||||
return new ParsedAssignmentStatement(isLocal, ((IdentifierToken*)identifier) -> Value, expression, start, expression->GetEndPosition() - start);
|
||||
}
|
||||
|
||||
ParsedStatement *Parser::ParseBlock(vector<TokenKind> endTokens) {
|
||||
vector<ParsedStatement*> statements;
|
||||
while (true){
|
||||
auto next = this -> Next();
|
||||
auto nextKind = next->GetKind();
|
||||
if (std::find(endTokens.begin(), endTokens.end(), nextKind) != endTokens.end()){
|
||||
break;
|
||||
}
|
||||
if (nextKind == TokenKind::EndOfFile){
|
||||
this->ScriptData->Diagnostics->LogError(DiagnosticCode::UnexpectedToken, next->GetStartPosition(), next->GetLength());
|
||||
break;
|
||||
}
|
||||
statements.push_back(this -> ParseStatement(next));
|
||||
}
|
||||
return new ParsedBlockStatement(statements);
|
||||
}
|
||||
|
||||
ParsedStatement *Parser::ParseFunctionDeclaration(IToken *current) {
|
||||
auto functionIdentifierToken = this->Next();
|
||||
auto openParenthesis = this->Next();
|
||||
vector<TypedVariableIdentifier*> parameters;
|
||||
bool hasErrors = false;
|
||||
if (functionIdentifierToken->GetKind() != TokenKind::Identifier){
|
||||
this->ScriptData->Diagnostics->LogError(DiagnosticCode::UnexpectedToken, functionIdentifierToken->GetStartPosition(), functionIdentifierToken->GetLength());
|
||||
hasErrors = true;
|
||||
}
|
||||
if (openParenthesis->GetKind() != TokenKind::OpenParenthesis && !hasErrors){
|
||||
this->ScriptData->Diagnostics->LogError(DiagnosticCode::UnexpectedToken, openParenthesis->GetStartPosition(), openParenthesis->GetLength());
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
while (true){
|
||||
auto type = this->Next();
|
||||
auto identifier = this->Next();
|
||||
auto next = this->Next();
|
||||
if (type->GetKind() != TokenKind::Identifier &&!hasErrors){
|
||||
this->ScriptData->Diagnostics->LogError(DiagnosticCode::UnexpectedToken, type->GetStartPosition(), type->GetLength());
|
||||
hasErrors = true;
|
||||
continue;
|
||||
}
|
||||
if (identifier->GetKind() != TokenKind::Identifier &&!hasErrors){
|
||||
this->ScriptData->Diagnostics->LogError(DiagnosticCode::UnexpectedToken, identifier->GetStartPosition(), identifier->GetLength());
|
||||
hasErrors = true;
|
||||
continue;
|
||||
}
|
||||
auto typeToken = (IdentifierToken*)type;
|
||||
auto identifierToken = (IdentifierToken*)identifier;
|
||||
parameters.push_back(new TypedVariableIdentifier(HashedString(typeToken->Value), HashedString(identifierToken->Value)));
|
||||
|
||||
auto nextKind = next->GetKind();
|
||||
if (nextKind == TokenKind::CloseParenthesis || nextKind == TokenKind::EndOfFile){
|
||||
break;
|
||||
} else if (nextKind != TokenKind::CommaToken && !hasErrors){
|
||||
this->ScriptData->Diagnostics->LogError(DiagnosticCode::UnexpectedToken, next->GetStartPosition(), next->GetLength());
|
||||
hasErrors = true;
|
||||
}
|
||||
}
|
||||
auto block = this -> ParseBlock({TokenKind ::EndKeyword});
|
||||
|
||||
auto start = current->GetStartPosition();
|
||||
if (hasErrors){
|
||||
return new ParsedBadStatement(start, block->GetEndPosition() - start);
|
||||
}
|
||||
if (block->GetKind() == ParsedStatementKind::Bad){
|
||||
return new ParsedBadStatement(start, block->GetEndPosition() - start);
|
||||
}
|
||||
auto functionIdentifier = ((IdentifierToken*) functionIdentifierToken)->Value;
|
||||
return new ParsedFunctionDeclarationStatement(HashedString(functionIdentifier), parameters, (ParsedBlockStatement*)block, start, block->GetEndPosition() - start);
|
||||
|
||||
}
|
||||
|
||||
ParsedExpression* Parser::ParseExpression(IToken* current){
|
||||
return this -> ParseBinaryExpression(current, OperatorPrecedence::No);
|
||||
auto expression = this -> ParseBinaryExpression(current, OperatorPrecedence::No);
|
||||
if (this -> Peek() -> GetKind() == TokenKind::OpenParenthesis){
|
||||
//TODO: Function Evaluation
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
OperatorPrecedence GetUnaryPrecedence(TokenKind kind){
|
||||
@@ -175,3 +252,5 @@ ParsedExpression *Parser::ParseParenthesizedExpression(IToken *current) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user