diff --git a/src/Diagnostics/DiagnosticCode.hpp b/src/Diagnostics/DiagnosticCode.hpp index f7a161b..87b7a52 100644 --- a/src/Diagnostics/DiagnosticCode.hpp +++ b/src/Diagnostics/DiagnosticCode.hpp @@ -4,6 +4,7 @@ enum class DiagnosticCode{ UnexpectedCharacter, + UnexpectedToken, }; #endif //PORYGONLANG_DIAGNOSTICCODE_HPP diff --git a/src/Parser/ParsedExpressions/ParsedExpression.hpp b/src/Parser/ParsedExpressions/ParsedExpression.hpp index 9a1d71b..f72b054 100644 --- a/src/Parser/ParsedExpressions/ParsedExpression.hpp +++ b/src/Parser/ParsedExpressions/ParsedExpression.hpp @@ -7,6 +7,8 @@ #include "../BinaryOperatorKind.hpp" enum class ParsedExpressionKind{ + Bad, + LiteralInteger, LiteralFloat, LiteralString, @@ -40,6 +42,15 @@ public: } }; +class BadExpression : public ParsedExpression{ +public: + BadExpression(unsigned int position, unsigned int length) : ParsedExpression(position, length){} + + ParsedExpressionKind GetKind() final{ + return ParsedExpressionKind::Bad; + } +}; + class LiteralIntegerExpression : public ParsedExpression{ long _value; public: diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index da83350..83a3006 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -7,24 +7,24 @@ ParsedScriptStatement* Parser::Parse() { vector statements; while (true){ - auto next = Parser::Next(); + auto next = this -> Next(); if (next->GetKind() == TokenKind::EndOfFile){ break; } if (next->GetKind() == TokenKind::WhiteSpace){ continue; } - statements.push_back(Parser::ParseStatement(next)); + statements.push_back(this -> ParseStatement(next)); } return new ParsedScriptStatement(statements); } ParsedStatement* Parser::ParseStatement(IToken* current){ - return new ParsedExpressionStatement(Parser::ParseExpression(current)); + return new ParsedExpressionStatement(this -> ParseExpression(current)); } ParsedExpression* Parser::ParseExpression(IToken* current){ - return Parser::ParseBinaryExpression(current, OperatorPrecedence::No); + return this -> ParseBinaryExpression(current, OperatorPrecedence::No); } @@ -44,7 +44,7 @@ UnaryOperatorKind GetUnaryOperatorKind(TokenKind kind){ case TokenKind::PlusToken: return UnaryOperatorKind::Identity; case TokenKind::MinusToken: return UnaryOperatorKind::Negation; case TokenKind::NotKeyword: return UnaryOperatorKind::LogicalNegation; - default: + default: // This should never trigger, so throw. throw; } } @@ -58,7 +58,7 @@ BinaryOperatorKind GetBinaryOperatorKind(TokenKind kind){ case TokenKind::EqualityToken: return BinaryOperatorKind ::Equality; case TokenKind::AndKeyword: return BinaryOperatorKind ::LogicalAnd; case TokenKind::OrKeyword: return BinaryOperatorKind ::LogicalOr; - default: + default: // This should never trigger, so throw. throw; } } @@ -82,22 +82,22 @@ ParsedExpression* Parser::ParseBinaryExpression(IToken* current, OperatorPrecede ParsedExpression* left; if (unaryPrecedence != OperatorPrecedence::No && unaryPrecedence >= parentPrecedence){ UnaryOperatorKind operatorKind = GetUnaryOperatorKind(current -> GetKind()); - auto next = Parser::Next(); - auto operand = Parser::ParseBinaryExpression(next, unaryPrecedence); + auto next = this -> Next(); + auto operand = this -> ParseBinaryExpression(next, unaryPrecedence); auto startPos = current -> GetStartPosition(); left = new UnaryExpression(operatorKind, operand, startPos, operand -> GetEndPosition() - startPos); } else{ - left = Parser::ParsePrimaryExpression(current); + left = this -> ParsePrimaryExpression(current); } while (true){ - auto next = Parser::Peek(); + auto next = this -> Peek(); OperatorPrecedence binaryPrecedence = GetBinaryPrecedence(next -> GetKind()); if (binaryPrecedence == OperatorPrecedence::No || binaryPrecedence <= parentPrecedence){ break; } auto operatorKind = GetBinaryOperatorKind(next -> GetKind()); - Parser::Next(); - auto right = ParseBinaryExpression(Parser::Next(), binaryPrecedence); + this -> Next(); + auto right = ParseBinaryExpression(this -> Next(), binaryPrecedence); auto startPos = left -> GetStartPosition(); left = new BinaryExpression(operatorKind, left, right, startPos, right -> GetEndPosition() - startPos); } @@ -111,18 +111,19 @@ ParsedExpression *Parser::ParsePrimaryExpression(IToken *current) { case TokenKind ::TrueKeyword: return new LiteralBoolExpression(current); case TokenKind ::FalseKeyword: return new LiteralBoolExpression(current); default: - throw; + this -> ScriptData -> Diagnostics.LogError(DiagnosticCode::UnexpectedToken, current->GetStartPosition(), current->GetLength()); + return new BadExpression(current->GetStartPosition(), current->GetLength()); } } IToken *Parser::Peek() { - return Parser::_tokens[_position]; + return this -> _tokens[_position]; } IToken *Parser::Next() { - Parser::_position++; - return Parser::_tokens[_position - 1]; + this -> _position++; + return this -> _tokens[_position - 1]; } #ifdef TESTS_BUILD @@ -130,7 +131,7 @@ IToken *Parser::Next() { TEST_CASE( "Parse single true keyword", "[parser]" ) { vector v {new SimpleToken(TokenKind::TrueKeyword,0,0), new SimpleToken(TokenKind::EndOfFile,0,0)}; - Parser parser = Parser(v); + Parser parser = Parser(v, nullptr); auto parsedStatements = parser.Parse() -> GetStatements(); REQUIRE(parsedStatements.size() == 1); auto firstStatement = parsedStatements[0]; @@ -143,7 +144,7 @@ TEST_CASE( "Parse single true keyword", "[parser]" ) { TEST_CASE( "Parse single false keyword", "[parser]" ) { vector v {new SimpleToken(TokenKind::FalseKeyword,0,0), new SimpleToken(TokenKind::EndOfFile,0,0)}; - Parser parser = Parser(v); + Parser parser = Parser(v, nullptr); auto parsedStatements = parser.Parse() -> GetStatements(); REQUIRE(parsedStatements.size() == 1); auto firstStatement = parsedStatements[0]; @@ -161,7 +162,7 @@ TEST_CASE( "Parse simple addition", "[parser]" ) { new IntegerToken(10, 0, 0), new SimpleToken(TokenKind::EndOfFile,0,0) }; - Parser parser = Parser(v); + Parser parser = Parser(v, nullptr); auto parsedStatements = parser.Parse() -> GetStatements(); REQUIRE(parsedStatements.size() == 1); auto firstStatement = parsedStatements[0]; @@ -184,7 +185,7 @@ TEST_CASE( "Parse simple negation", "[parser]" ) { new IntegerToken(10, 0, 0), new SimpleToken(TokenKind::EndOfFile,0,0) }; - Parser parser = Parser(v); + Parser parser = Parser(v, nullptr); auto parsedStatements = parser.Parse() -> GetStatements(); REQUIRE(parsedStatements.size() == 1); auto firstStatement = parsedStatements[0]; @@ -204,7 +205,7 @@ TEST_CASE( "Parse logical negation", "[parser]" ) { new SimpleToken(TokenKind::FalseKeyword,0,0), new SimpleToken(TokenKind::EndOfFile,0,0) }; - Parser parser = Parser(v); + Parser parser = Parser(v, nullptr); auto parsedStatements = parser.Parse() -> GetStatements(); REQUIRE(parsedStatements.size() == 1); auto firstStatement = parsedStatements[0]; @@ -227,7 +228,7 @@ TEST_CASE( "Assert binary precedence", "[parser]" ) { new IntegerToken(6, 0, 0), new SimpleToken(TokenKind::EndOfFile,0,0) }; - Parser parser = Parser(v); + Parser parser = Parser(v, nullptr); auto parsedStatements = parser.Parse() -> GetStatements(); REQUIRE(parsedStatements.size() == 1); auto firstStatement = parsedStatements[0]; diff --git a/src/Parser/Parser.hpp b/src/Parser/Parser.hpp index 5d8290d..cb8c8d1 100644 --- a/src/Parser/Parser.hpp +++ b/src/Parser/Parser.hpp @@ -5,6 +5,7 @@ #include "ParsedStatements/ParsedStatement.hpp" +#include "../Script.hpp" enum class OperatorPrecedence { No, @@ -19,6 +20,7 @@ enum class OperatorPrecedence { class Parser { vector _tokens; unsigned int _position; + Script* ScriptData; IToken* Peek(); IToken* Next(); @@ -28,9 +30,10 @@ class Parser { ParsedExpression* ParsePrimaryExpression(IToken* current); public: ParsedScriptStatement* Parse(); - explicit Parser(vector tokens){ + explicit Parser(vector tokens, Script* scriptData){ _tokens = std::move(tokens); _position = 0; + ScriptData = scriptData; } }; diff --git a/src/Script.cpp b/src/Script.cpp index b888f80..01eb0c8 100644 --- a/src/Script.cpp +++ b/src/Script.cpp @@ -14,7 +14,7 @@ Script Script::Create(string script) { void Script::Parse(string script) { auto lexer = Lexer(std::move(script), this); auto lexResult = lexer.Lex(); - auto parser = Parser(lexResult); + auto parser = Parser(lexResult, this); auto parseResult = parser.Parse(); for (auto token : lexResult){ delete token;