diff --git a/include/dusk/AST/ASTVisitor.h b/include/dusk/AST/ASTVisitor.h index d8007395c32410c7630c72210dfd46f0404d52b4..39c81d282816649cd7b367db0751ce9e61105135 100644 --- a/include/dusk/AST/ASTVisitor.h +++ b/include/dusk/AST/ASTVisitor.h @@ -70,18 +70,20 @@ public: /// Visit a conrete expression node. bool visit(Expr *E) { switch (E->getKind()) { - case ExprKind::Assign: - return getDerived().visit(static_cast<AssignExpr *>(E)); - case ExprKind::Call: - return getDerived().visit(static_cast<CallExpr *>(E)); - case ExprKind::Binary: - return getDerived().visit(static_cast<BinrayExpr *>(E)); - case ExprKind::Unary: - return getDerived().visit(static_cast<UnaryExpr *>(E)); case ExprKind::NumberLiteral: return getDerived().visit(static_cast<NumberLiteralExpr *>(E)); case ExprKind::Identifier: return getDerived().visit(static_cast<IdentifierExpr *>(E)); + case ExprKind::Paren: + return getDerived().visit(static_cast<ParenExpr *>(E)); + case ExprKind::Assign: + return getDerived().visit(static_cast<AssignExpr *>(E)); + case ExprKind::Infix: + return getDerived().visit(static_cast<InfixExpr *>(E)); + case ExprKind::Prefix: + return getDerived().visit(static_cast<PrefixExpr *>(E)); + case ExprKind::Call: + return getDerived().visit(static_cast<CallExpr *>(E)); case ExprKind::Subscript: return getDerived().visit(static_cast<SubscriptExpr *>(E)); } diff --git a/include/dusk/AST/Expr.h b/include/dusk/AST/Expr.h index 041f69b2a7bf67cca6ecd8203689637e1c6bc2fb..ee583f58837228219068b18e53a8bbb07d1f618b 100644 --- a/include/dusk/AST/Expr.h +++ b/include/dusk/AST/Expr.h @@ -17,7 +17,9 @@ namespace dusk { class NumberLiteralExpr; class IdentifierExpr; -class BinrayExpr; +class ParenExpr; +class InfixExpr; +class PrefixExpr; class CallExpr; class SubscriptExpr; class BlockStmt; @@ -29,9 +31,10 @@ class ASTWalker; enum struct ExprKind { NumberLiteral, Identifier, - Binary, + Paren, + Infix, Assign, - Unary, + Prefix, Call, Subscript }; @@ -76,13 +79,35 @@ public: virtual llvm::SMRange getSourceRange() const override; }; -class BinrayExpr: public Expr { +/// Represents a paranthesized expression +/// +/// E.g. '(' Expr ')' +class ParenExpr: public Expr { + /// Paranthesized expression + Expr *Expression; + + /// Left parethensis + llvm::SMLoc LPar; + + /// Right parethensis + llvm::SMLoc RPar; + +public: + ParenExpr(Expr *E, llvm::SMLoc L, llvm::SMLoc R); + + Expr *getExpr() const { return Expression; } + + virtual llvm::SMRange getSourceRange() const override; +}; + +/// An infix expression +class InfixExpr: public Expr { Expr *LHS; Expr *RHS; Token Op; public: - BinrayExpr(Expr *L, Expr *R, Token O); + InfixExpr(Expr *L, Expr *R, Token O); Expr *getLHS() const { return LHS; } Expr *getRHS() const { return RHS; } @@ -104,12 +129,12 @@ public: virtual llvm::SMRange getSourceRange() const override; }; -class UnaryExpr: public Expr { +class PrefixExpr: public Expr { Expr *Dest; Token Op; public: - UnaryExpr(Expr *D, Token O); + PrefixExpr(Expr *D, Token O); Expr *getDest() const { return Dest; } Token getOp() const { return Op; } diff --git a/include/dusk/Parse/Parser.h b/include/dusk/Parse/Parser.h index d845cb0167c14e09a96e0d6eccbeeb2abcde5dbf..5e21a5255770e782865ee65428cac6f0dec21668 100644 --- a/include/dusk/Parse/Parser.h +++ b/include/dusk/Parse/Parser.h @@ -111,7 +111,7 @@ private: Expr *parseParenExpr(); NumberLiteralExpr *parseNumberLiteralExpr(); - UnaryExpr *parseUnaryExpr(); + PrefixExpr *parseUnaryExpr(); // MARK: - Statements diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 57fb92f1f7d264ec85dd93721e90f9c069b1729c..0d4a12c0b4b3e3fd405bffb4d2fe3f3c11dbaca7 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -99,6 +99,13 @@ public: return true; } + bool visit(ParenExpr *E) { + Printer << "("; + super::visit(E->getExpr()); + Printer << ")"; + return true; + } + bool visit(AssignExpr *E) { super::visit(E->getDest()); Printer << " " << tok::assign << " "; @@ -119,14 +126,14 @@ public: return true; } - bool visit(BinrayExpr *E) { + bool visit(InfixExpr *E) { super::visit(E->getLHS()); Printer << " " << E->getOp().getKind() << " "; super::visit(E->getRHS()); return true; } - bool visit(UnaryExpr *E) { + bool visit(PrefixExpr *E) { Printer << E->getOp().getKind(); super::visit(E->getDest()); return true; diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp index 9788baf6d9642e79ecd6fbd2e3be004b73512c02..d4e7d72cd912109f3ca187dabb11565629957845 100644 --- a/lib/AST/ASTWalker.cpp +++ b/lib/AST/ASTWalker.cpp @@ -99,63 +99,73 @@ public: // MARK: - Expression nodes - bool visit(AssignExpr *E) { + bool visit(NumberLiteralExpr *E) { // Skip subtree if (!Walker.preWalk(E)) return true; - - if (!super::visit(E->getDest())) - return false; - if (!super::visit(E->getSource())) - return false; return Walker.postWalk(E); } - - bool visit(CallExpr *E) { + + bool visit(IdentifierExpr *E) { // Skip subtree if (!Walker.preWalk(E)) return true; - - for (auto V : E->getArgs()->getValues()) - if (!super::visit(V)) - return false; + return Walker.postWalk(E); } - - bool visit(BinrayExpr *E) { + + bool visit(ParenExpr *E) { + // Skip subtree + if (!Walker.preWalk(E)) + return true; + + if (!super::visit(E->getExpr())) + return false; + return false; + } + + bool visit(AssignExpr *E) { // Skip subtree if (!Walker.preWalk(E)) return true; - if (!super::visit(E->getLHS())) + if (!super::visit(E->getDest())) return false; - if (!super::visit(E->getRHS())) + if (!super::visit(E->getSource())) return false; return Walker.postWalk(E); } - bool visit(UnaryExpr *E) { + bool visit(InfixExpr *E) { // Skip subtree if (!Walker.preWalk(E)) return true; - if (!super::visit(E->getDest())) + if (!super::visit(E->getLHS())) + return false; + if (!super::visit(E->getRHS())) return false; return Walker.postWalk(E); } - bool visit(NumberLiteralExpr *E) { + bool visit(PrefixExpr *E) { // Skip subtree if (!Walker.preWalk(E)) return true; + + if (!super::visit(E->getDest())) + return false; return Walker.postWalk(E); } - - bool visit(IdentifierExpr *E) { + + bool visit(CallExpr *E) { // Skip subtree if (!Walker.preWalk(E)) return true; - + + for (auto V : E->getArgs()->getValues()) + if (!super::visit(V)) + return false; return Walker.postWalk(E); } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index e93ee7882576ae04b91f4a20615517bc5e49a283..39d4367c0dc9c373b31bf2aaa1315a9b6de9ce30 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -35,15 +35,27 @@ llvm::SMRange IdentifierExpr::getSourceRange() const { return { NameLoc, E }; } -// MARK: - Binary expression +// MARK: - Parenthesis expression -BinrayExpr::BinrayExpr(Expr *L, Expr *R, Token O) -: Expr(ExprKind::Binary), LHS(L), RHS(R), Op(O) +ParenExpr::ParenExpr(Expr *E, llvm::SMLoc L, llvm::SMLoc R) +: Expr(ExprKind::Paren), Expression(E), LPar(L), RPar(R) +{ + assert(Expression && "Invalid `paren` expression"); +} + +llvm::SMRange ParenExpr::getSourceRange() const { + return { LPar, RPar }; +} + +// MARK: - Infix expression + +InfixExpr::InfixExpr(Expr *L, Expr *R, Token O) +: Expr(ExprKind::Infix), LHS(L), RHS(R), Op(O) { assert(LHS && RHS && "Invalid `infix` expresssion."); } -llvm::SMRange BinrayExpr::getSourceRange() const { +llvm::SMRange InfixExpr::getSourceRange() const { return { LHS->getLocStart(), RHS->getLocEnd() }; } @@ -61,13 +73,13 @@ llvm::SMRange AssignExpr::getSourceRange() const { // MARK: - Unary expresssion -UnaryExpr::UnaryExpr(Expr *D, Token O) -: Expr(ExprKind::Unary), Dest(D), Op(O) +PrefixExpr::PrefixExpr(Expr *D, Token O) +: Expr(ExprKind::Prefix), Dest(D), Op(O) { assert(Dest && "Invalid `unary` expression."); } -llvm::SMRange UnaryExpr::getSourceRange() const { +llvm::SMRange PrefixExpr::getSourceRange() const { return { Op.getLoc(), Dest->getLocEnd() }; } diff --git a/lib/Parser/ParseExpr.cpp b/lib/Parser/ParseExpr.cpp index 29504f7ef88558f7c07577b54a132f386f2f91d4..78ecef10c462eec722dd14db8ddf71d1cd7e7cc9 100644 --- a/lib/Parser/ParseExpr.cpp +++ b/lib/Parser/ParseExpr.cpp @@ -91,7 +91,7 @@ Expr *Parser::parseLogicalExprRHS(Expr *LHS) { case tok::greater: case tok::greater_eq: consumeToken(); - return new BinrayExpr(LHS, parseArithExpr(), T); + return new InfixExpr(LHS, parseArithExpr(), T); default: llvm_unreachable("Unexpected token."); @@ -133,7 +133,7 @@ Expr *Parser::parseArithExprRHS(Expr *LHS) { case tok::plus: case tok::minus: consumeToken(); - return new BinrayExpr(LHS, parseExpr(), T); + return new InfixExpr(LHS, parseExpr(), T); default: llvm_unreachable("Unexpected token."); @@ -177,7 +177,7 @@ Expr *Parser::parseMulExprRHS(Expr *LHS) { case tok::multipy: case tok::divide: consumeToken(); - return new BinrayExpr(LHS, parseExpr(), T); + return new InfixExpr(LHS, parseExpr(), T); default: llvm_unreachable("Unexpected token."); @@ -254,18 +254,19 @@ Expr *Parser::parseParenExpr() { auto E = parseExpr(); if (!consumeIf(tok::r_paren)) assert("Missing `)`" && false); - return E; + return new ParenExpr(E, L, PreviousLoc); } -UnaryExpr *Parser::parseUnaryExpr() { +PrefixExpr *Parser::parseUnaryExpr() { // Validate that we have a unary operand. assert(Tok.isAny(tok::neg, tok::minus) && "Invalid parse method."); auto Op = Tok; consumeToken(); - return new UnaryExpr(parsePrimaryExpr(), Op); + return new PrefixExpr(parsePrimaryExpr(), Op); } +/// Properly parse number literal NumberLiteralExpr *Parser::parseNumberLiteralExpr() { // Validate that we have a number literal assert(Tok.is(tok::number_literal) && "Invalid parsing method.");