diff --git a/include/parser/Parser.hpp b/include/parser/Parser.hpp index b7b613e..4fefe83 100644 --- a/include/parser/Parser.hpp +++ b/include/parser/Parser.hpp @@ -22,15 +22,17 @@ #include #include #include +#include #include #include #include #include -#include +#include #include #include #include #include +#include #include #include #include @@ -42,6 +44,11 @@ #include #include #include +#include +#include +#include +#include + #include #include #include @@ -508,18 +515,277 @@ class Parser { } 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->exprPrimary(); + 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 statement() { - if(this->isNext("if")) - return this->exprIf(); - else if(this->isNext("while")) - return this->exprWhile(); + 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(); std::unique_ptr expr = this->expression(); this->consume(";");