Implements parsing function declarations

This commit is contained in:
2019-05-31 15:00:14 +02:00
parent 6fad5a0a7d
commit c407ba2f50
8 changed files with 191 additions and 15 deletions

View File

@@ -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) {