From 9c015720a0fa1acf10d43ffd7a006c4940f57ab6 Mon Sep 17 00:00:00 2001 From: Nathanne Isip Date: Sun, 15 Sep 2024 09:09:41 +0800 Subject: [PATCH] Liquidated Parser class implementations. --- include/parser/Parser.hpp | 785 +++----------------------------------- 1 file changed, 47 insertions(+), 738 deletions(-) diff --git a/include/parser/Parser.hpp b/include/parser/Parser.hpp index 88c33ea..1c4cee7 100644 --- a/include/parser/Parser.hpp +++ b/include/parser/Parser.hpp @@ -72,751 +72,60 @@ class Parser { int length; int index = 0; + std::unique_ptr exprArray(); + std::unique_ptr exprBlock(); + std::unique_ptr exprCatchHandle(); + std::unique_ptr exprDoWhile(); + std::unique_ptr exprFunctionDecl(); + std::unique_ptr exprLoop(); + std::unique_ptr exprIf(); + std::unique_ptr exprLiteral(); + std::unique_ptr exprRandom(); + std::unique_ptr exprRender(); + std::unique_ptr exprType(); + std::unique_ptr exprUnless(); + std::unique_ptr exprWhen(); + std::unique_ptr exprWhile(); + std::unique_ptr exprPrimary(); + std::unique_ptr exprLogicOr(); + std::unique_ptr exprLogicAnd(); + std::unique_ptr exprBitwiseOr(); + std::unique_ptr exprBitwiseXor(); + std::unique_ptr exprBitwiseAnd(); + std::unique_ptr exprNilCoalescing(); + std::unique_ptr exprEquality(); + std::unique_ptr exprComparison(); + std::unique_ptr exprShift(); + std::unique_ptr exprTerm(); + std::unique_ptr exprFactor(); + + std::unique_ptr stmtBreak(); + std::unique_ptr stmtContinue(); + std::unique_ptr stmtRet(); + std::unique_ptr stmtThrow(); + std::unique_ptr stmtTest(); + + std::unique_ptr expression(); + std::unique_ptr statement(); + + Token peek() const; + Token consume(const std::string& image); + Token consume(TokenType type); + + void advance(); + bool isNext(const std::string& image) const; + bool isAtEnd() const; + public: Parser(const std::vector& _tokens) : globalStatements{}, tokens(_tokens), length(static_cast(_tokens.size())) {} - static Parser fromFile(const std::string& fileName) { - std::unique_ptr tokenizer = Tokenizer::loadFile(fileName); - tokenizer->scan(); - - return Parser(tokenizer->getTokens()); - } - - bool isAtEnd() const { - return this->index == this->length; - } - - void advance() { - this->index++; - } - - Token peek() const { - if(this->isAtEnd()) - throw ParserException("Encountered end-of-file."); - - return this->tokens[this->index]; - } - - bool isNext(const std::string& image) const { - if(this->isAtEnd()) - return false; - - return this->peek().getImage() == image; - } - - Token consume(const std::string& image) { - if(this->isAtEnd()) - throw ParserException("Expecting \"" + image + "\", encountered end-of-code."); - - Token token = this->peek(); - if(token.getImage() != image) - throw ParserException("Expecting \"" + image + "\", encountered " + token.getImage()); - - this->advance(); - return token; - } - - Token consume(TokenType type) { - if(this->isAtEnd()) - throw ParserException("Expecting token type, encountered end-of-code."); - - Token token = this->peek(); - if(token.getType() != type) - throw ParserException( - "Expecting " + tokenTypeToString(type) + - ", encountered " + tokenTypeToString(token.getType()) - ); - - this->advance(); - return token; - } - - const std::vector>& getGlobalStatements() const { - return this->globalStatements; - } - - std::unique_ptr exprArray() { - Token address = this->consume("["); - std::vector> expressions; - - while(!this->isNext("]")) { - if(!expressions.empty()) - this->consume(","); - - expressions.push_back(this->expression()); - } - - this->consume("]"); - return std::make_unique( - std::make_unique(address), - std::move(expressions) - ); - } - - std::unique_ptr exprBlock() { - Token address = this->consume("{"); - std::vector> body; - - while(!this->isNext("}")) - body.emplace_back(this->expression()); - - return std::make_unique( - std::make_unique(address), - std::move(body) - ); - } - - std::unique_ptr exprCatchHandle() { - Token address = this->consume("catch"); - std::unique_ptr catchExpr = this->expression(); - this->consume("handle"); - - Token handler = this->consume(TokenType::IDENTIFIER); - std::unique_ptr handleExpr = this->expression(); - - std::unique_ptr finalExpr = nullptr; - if(this->isNext("handle")) { - this->consume("handle"); - finalExpr = this->expression(); - } - - return std::make_unique( - std::make_unique(address), - std::move(catchExpr), - std::move(handleExpr), - std::make_unique(handler), - std::move(finalExpr) - ); - } - - std::unique_ptr exprDoWhile() { - Token address = this->consume("do"); - std::unique_ptr body = this->expression(); - - this->consume("while"); - this->consume("("); - - std::unique_ptr condition = this->expression(); - this->consume(")"); - - return std::make_unique( - std::make_unique(address), - std::move(body), - std::move(condition) - ); - } - - std::unique_ptr exprFunctionDecl() { - Token address = this->consume("func"); - this->consume("("); - - std::vector> parameters; - while(!this->isNext(")")) { - if(!parameters.empty()) - this->consume(","); - - parameters.emplace_back( - std::make_unique( - this->consume(TokenType::IDENTIFIER) - ) - ); - } - this->consume(")"); - - std::unique_ptr body = this->expression(); - return std::make_unique( - std::make_unique(address), - std::move(parameters), - std::move(body) - ); - } - - std::unique_ptr exprLoop() { - Token address = this->consume("loop"); - this->consume("("); - - std::unique_ptr initial = this->expression(); - this->consume(";"); - - std::unique_ptr condition = this->expression(); - this->consume(";"); - - std::unique_ptr postexpr = this->expression(); - this->consume(")"); - - std::unique_ptr body = this->expression(); - return std::make_unique( - std::make_unique(address), - std::move(initial), - std::move(condition), - std::move(postexpr), - std::move(body) - ); - } - - std::unique_ptr exprIf() { - Token address = this->consume("if"); - this->consume("("); - - std::unique_ptr condition = this->expression(); - this->consume(")"); - - std::unique_ptr thenExpr = this->expression(); - std::unique_ptr elseExpr = nullptr; - - if(this->isNext("else")) { - this->consume("else"); - elseExpr = this->expression(); - } - - return std::make_unique( - std::make_unique(address), - std::move(condition), - std::move(thenExpr), - std::move(elseExpr) - ); - } - - std::unique_ptr exprLiteral() { - std::unique_ptr expr = nullptr; - - if(this->isNext("true")) - expr = std::make_unique( - std::make_unique(this->consume("true")), - true - ); - else if(this->isNext("false")) - expr = std::make_unique( - std::make_unique(this->consume("false")), - false - ); - else if(this->isNext("maybe")) - expr = std::make_unique( - std::make_unique(this->consume("maybe")) - ); - else if(this->isNext("nil")) - expr = std::make_unique( - std::make_unique(this->consume("nil")) - ); - else if(this->peek().getType() == TokenType::STRING) { - Token stringToken = this->consume(TokenType::STRING); - expr = std::make_unique( - std::make_unique(stringToken), - stringToken.getImage() - ); - } - else if(this->peek().getType() == TokenType::DIGIT) { - Token digitToken = this->consume(TokenType::DIGIT); - expr = std::make_unique( - std::make_unique(digitToken), - ZhivoUtil::Convert::translateDigit(digitToken.getImage()) - ); - } - - if(!expr) - throw ParserException( - "Expecting expression, encountered " + - this->peek().getImage() - ); - - return expr; - } - - std::unique_ptr exprRandom() { - Token address = this->consume("random"); - std::unique_ptr thenExpr = this->expression(); - std::unique_ptr elseExpr = nullptr; - - if(this->isNext("else")) { - this->consume("else"); - elseExpr = this->expression(); - } - - return std::make_unique( - std::make_unique(address), - std::move(thenExpr), - std::move(elseExpr) - ); - } - - std::unique_ptr exprRender() { - Token address = this->consume("render"); - std::unique_ptr expression = this->expression(); - - return std::make_unique( - std::make_unique(address), - std::move(expression) - ); - } - - std::unique_ptr exprType() { - Token address = this->consume("type"); - std::unique_ptr expression = this->expression(); - - return std::make_unique( - std::make_unique(address), - std::move(expression) - ); - } - - std::unique_ptr exprUnless() { - Token address = this->consume("unless"); - this->consume("("); - - std::unique_ptr condition = this->expression(); - this->consume(")"); - - std::unique_ptr thenExpr = this->expression(); - std::unique_ptr elseExpr = nullptr; - - if(this->isNext("else")) { - this->consume("else"); - elseExpr = this->expression(); - } - - return std::make_unique( - std::make_unique(address), - std::move(condition), - std::move(thenExpr), - std::move(elseExpr) - ); - } - - std::unique_ptr exprWhen() { - Token address = this->consume("when"); - this->consume("("); - - std::unique_ptr expression = this->expression(); - this->consume(")"); - this->consume("{"); - - std::vector, std::unique_ptr>> cases; - std::unique_ptr defaultCase = nullptr; - - while(!this->isNext("}")) { - if(!cases.empty()) - this->consume(","); - - if(this->isNext("if")) { - this->consume("if"); - this->consume("("); - - std::unique_ptr caseExpr = this->expression(); - this->consume(")"); - - std::unique_ptr thenBlock = this->expression(); - cases.emplace_back(std::make_pair( - std::move(caseExpr), - std::move(thenBlock) - )); - } - else if(this->isNext("else")) { - if(defaultCase) - throw std::runtime_error("Cannot have more than one (1) else for when expression."); - - this->consume("else"); - defaultCase = this->expression(); - } - } - - return std::make_unique( - std::make_unique(address), - std::move(expression), - std::move(cases), - std::move(defaultCase) - ); - } - - std::unique_ptr exprWhile() { - Token address = this->consume("while"); - this->consume("("); - - std::unique_ptr condition = this->expression(); - this->consume(")"); - - return std::make_unique( - std::make_unique(address), - std::move(condition), - this->expression() - ); - } - - std::unique_ptr exprPrimary() { - std::unique_ptr expression = nullptr; - - if(this->isNext("+") || this->isNext("-") || this->isNext("~")) { - Token address = this->consume(TokenType::OPERATOR); - expression = std::make_unique( - std::make_unique(address), - std::move(std::string(address.getImage())), - this->expression() - ); - } - else if(this->isNext("(")) { - Token address = this->consume("("); - std::unique_ptr innerExpr = this->expression(); - - expression = std::make_unique( - std::make_unique(address), - std::move(innerExpr) - ); - this->consume(")"); - } - else if(this->isNext("{")) { - Token address = this->consume(TokenType::IDENTIFIER); - std::vector> statements; - - while(!this->isNext("}")) { - std::unique_ptr stmt = this->statement(); - statements.emplace_back(std::move(stmt)); - } - this->consume("}"); - - expression = std::make_unique( - std::make_unique(address), - std::move(statements) - ); - } - else if(this->isNext("render")) - expression = this->exprRender(); - else if(this->isNext("catch")) - expression = this->exprCatchHandle(); - else if(this->isNext("do")) - expression = this->exprDoWhile(); - else if(this->isNext("while")) - expression = this->exprWhile(); - else if(this->isNext("loop")) - expression = this->exprLoop(); - else if(this->isNext("unless")) - expression = this->exprUnless(); - else if(this->isNext("when")) - expression = this->exprWhen(); - else if(this->isNext("func")) - expression = this->exprFunctionDecl(); - else if(this->isNext("[")) - expression = this->exprArray(); - else if(this->peek().getType() == TokenType::IDENTIFIER) { - expression = std::make_unique( - std::make_unique(this->consume(TokenType::IDENTIFIER)) - ); - - while(this->isNext("[")) { - Token address = this->consume("["); - std::unique_ptr indexExpr = this->expression(); - - this->consume("]"); - expression = std::make_unique( - std::make_unique(address), - std::move(expression), - std::move(indexExpr) - ); - } - } - else expression = this->exprLiteral(); - - while(this->isNext("(") || this->isNext("[")) { - while(this->isNext("(")) { - Token address = this->consume("("); - std::vector> arguments; - - while(!this->isNext(")")) { - if(!arguments.empty()) - this->consume(","); - - arguments.emplace_back( - std::move(this->expression()) - ); - } - - this->consume(")"); - expression = std::make_unique( - std::make_unique(address), - std::move(expression), - std::move(arguments) - ); - } - - while(this->isNext("[")) { - Token address = this->consume("["); - std::unique_ptr indexExpr = this->expression(); - - this->consume("]"); - expression = std::make_unique( - std::make_unique(address), - std::move(expression), - std::move(indexExpr) - ); - } - } - - return expression; - } - - std::unique_ptr exprLogicOr() { - std::unique_ptr expression = this->exprLogicAnd(); - - while(this->isNext("||")) - expression = std::make_unique( - std::make_unique( - this->consume(TokenType::OPERATOR) - ), - std::move(expression), - "||", - std::move(this->exprLogicAnd()) - ); - - return expression; - } - - std::unique_ptr exprLogicAnd() { - std::unique_ptr expression = this->exprBitwiseOr(); - - while(this->isNext("&&")) - expression = std::make_unique( - std::make_unique( - this->consume(TokenType::OPERATOR) - ), - std::move(expression), - "&&", - std::move(this->exprBitwiseOr()) - ); - - return expression; - } - - std::unique_ptr exprBitwiseOr() { - std::unique_ptr expression = this->exprBitwiseXor(); - - while(this->isNext("|")) - expression = std::make_unique( - std::make_unique( - this->consume(TokenType::OPERATOR) - ), - std::move(expression), - "|", - std::move(this->exprBitwiseXor()) - ); - - return expression; - } - - std::unique_ptr exprBitwiseXor() { - std::unique_ptr expression = this->exprBitwiseAnd(); - - while(this->isNext("^")) - expression = std::make_unique( - std::make_unique( - this->consume(TokenType::OPERATOR) - ), - std::move(expression), - "^", - std::move(this->exprBitwiseAnd()) - ); - - return expression; - } - - std::unique_ptr exprBitwiseAnd() { - std::unique_ptr expression = this->exprNilCoalescing(); - - while(this->isNext("&")) - expression = std::make_unique( - std::make_unique( - this->consume(TokenType::OPERATOR) - ), - std::move(expression), - "&", - std::move(this->exprNilCoalescing()) - ); - - return expression; - } - - std::unique_ptr exprNilCoalescing() { - std::unique_ptr expression = this->exprEquality(); - - while(this->isNext("?")) - expression = std::make_unique( - std::make_unique( - this->consume(TokenType::OPERATOR) - ), - std::move(expression), - std::move(this->exprEquality()) - ); - - return expression; - } - - std::unique_ptr exprEquality() { - std::unique_ptr expression = this->exprComparison(); - - while(this->isNext("==") || this->isNext("!=") || this->isNext("=")) { - Token op = this->consume(TokenType::OPERATOR); - expression = std::make_unique( - std::make_unique(op), - std::move(expression), - op.getImage(), - std::move(this->exprComparison()) - ); - } - - return expression; - } - - std::unique_ptr exprComparison() { - std::unique_ptr expression = this->exprShift(); - - while(this->isNext("<") || - this->isNext("<=") || - this->isNext(">") || - this->isNext(">=") - ) { - Token op = this->consume(TokenType::OPERATOR); - expression = std::make_unique( - std::make_unique(op), - std::move(expression), - op.getImage(), - std::move(this->exprShift()) - ); - } - - return expression; - } - - std::unique_ptr exprShift() { - std::unique_ptr expression = this->exprTerm(); - - while(this->isNext("<<") || this->isNext(">>")) { - Token op = this->consume(TokenType::OPERATOR); - expression = std::make_unique( - std::make_unique(op), - std::move(expression), - op.getImage(), - std::move(this->exprTerm()) - ); - } - - return expression; - } - - std::unique_ptr exprTerm() { - std::unique_ptr expression = this->exprFactor(); - - while(this->isNext("+") || this->isNext("-")) { - Token op = this->consume(TokenType::OPERATOR); - expression = std::make_unique( - std::make_unique(op), - std::move(expression), - op.getImage(), - std::move(this->exprFactor()) - ); - } - - return expression; - } - - std::unique_ptr exprFactor() { - std::unique_ptr expression = this->exprPrimary(); - - while(this->isNext("*") || this->isNext("/") || this->isNext("%")) { - Token op = this->consume(TokenType::OPERATOR); - expression = std::make_unique( - std::make_unique(op), - std::move(expression), - op.getImage(), - std::move(this->exprPrimary()) - ); - } - - return expression; - } - - std::unique_ptr expression() { - return this->exprLogicOr(); - } - - std::unique_ptr stmtBreak() { - Token address = this->consume("break"); - this->consume(";"); - - return std::make_unique( - std::make_unique(address) - ); - } - - std::unique_ptr stmtContinue() { - Token address = this->consume("continue"); - this->consume(";"); - - return std::make_unique( - std::make_unique(address) - ); - } - - std::unique_ptr stmtRet() { - Token address = this->consume("ret"); - std::unique_ptr expression = this->expression(); - - this->consume(";"); - return std::make_unique( - std::make_unique(address), - std::move(expression) - ); - } - - std::unique_ptr stmtThrow() { - Token address = this->consume("throw"); - std::unique_ptr expression = this->expression(); - - this->consume(";"); - return std::make_unique( - std::make_unique(address), - std::move(expression) - ); - } - - std::unique_ptr stmtTest() { - Token address = this->consume("test"); - this->consume("("); - - std::unique_ptr testName = this->expression(); - this->consume(")"); - - std::unique_ptr testBody = this->expression(); - this->consume(";"); - - return std::make_unique( - std::make_unique(address), - std::move(testName), - std::move(testBody) - ); - } - - std::unique_ptr statement() { - if(this->isNext("break")) - return this->stmtBreak(); - else if(this->isNext("continue")) - return this->stmtContinue(); - else if(this->isNext("ret")) - return this->stmtRet(); - else if(this->isNext("throw")) - return this->stmtThrow(); - else if(this->isNext("test")) - return this->stmtTest(); - - std::unique_ptr expr = this->expression(); - this->consume(";"); - - return expr; - } + const std::vector>& getGlobalStatements() const; + void parse(); - void parse() { - while(!this->isAtEnd()) - this->globalStatements.push_back(this->statement()); - } + static Parser fromFile(const std::string& fileName); }; #endif