diff --git a/include/dusk/AST/ASTVisitor.h b/include/dusk/AST/ASTVisitor.h index 04d86f3aff93e858126d9ac33ed794cbbe02108f..8bf3ba0b9371db617506625a55e779dec73f3c31 100644 --- a/include/dusk/AST/ASTVisitor.h +++ b/include/dusk/AST/ASTVisitor.h @@ -98,6 +98,8 @@ public: return getDerived().visit(static_cast<ReturnStmt *>(S)); case StmtKind::Range: return getDerived().visit(static_cast<RangeStmt *>(S)); + case StmtKind::Subscript: + return getDerived().visit(static_cast<SubscriptStmt *>(S)); case StmtKind::Block: return getDerived().visit(static_cast<BlockStmt *>(S)); case StmtKind::For: @@ -118,8 +120,6 @@ public: return getDerived().visit(static_cast<ExprPattern *>(P)); case PatternKind::Variable: return getDerived().visit(static_cast<VarPattern *>(P)); - case PatternKind::Subscript: - return getDerived().visit(static_cast<SubscriptPattern *>(P)); } } }; diff --git a/include/dusk/AST/Expr.h b/include/dusk/AST/Expr.h index 398880883470d55e3d1cd765399725fd50f23be7..ff1865909c6302490be72ab212e333f7a343f5fb 100644 --- a/include/dusk/AST/Expr.h +++ b/include/dusk/AST/Expr.h @@ -165,13 +165,13 @@ class SubscriptExpr : public Expr { Expr *Base; /// Subscription pattern - Pattern *Subscript; + Stmt *Subscript; public: - SubscriptExpr(Expr *B, Pattern *S); + SubscriptExpr(Expr *B, Stmt *S); Expr *getBase() { return Base; } - Pattern *getSubscript() { return Subscript; } + Stmt *getSubscript() { return Subscript; } virtual SMRange getSourceRange() const override; }; diff --git a/include/dusk/AST/Pattern.h b/include/dusk/AST/Pattern.h index 1d9057163ab82e472562e6f2a0993d8447952e2d..c0ebc47a92ee8ab1ff76cd36936bb32e3e80fa34 100644 --- a/include/dusk/AST/Pattern.h +++ b/include/dusk/AST/Pattern.h @@ -25,7 +25,7 @@ class Stmt; class ParamDecl; /// Pattern description. -enum struct PatternKind { Expr, Variable, Subscript }; +enum struct PatternKind { Expr, Variable }; class Pattern : public ASTNode { /// Pattern type. @@ -86,30 +86,6 @@ public: virtual SMRange getSourceRange() const override; }; -/// Subscript pattern -/// -/// Pattern used in array declaration and in accessing array elements. -class SubscriptPattern : public Pattern { - /// Subscript value - Expr *Value; - - /// Location of left bracket - SMLoc LBracet; - - /// Location of right bracket - SMLoc RBracet; - -public: - SubscriptPattern(Expr *V, SMLoc L, SMLoc R); - - Expr *getValue() const { return Value; } - SMLoc getLBracket() const { return LBracet; } - SMLoc getRBracket() const { return RBracet; } - - virtual size_t count() const override; - virtual SMRange getSourceRange() const override; -}; - } // namespace dusk #endif /* DUSK_PATTERN_H */ diff --git a/include/dusk/AST/Stmt.h b/include/dusk/AST/Stmt.h index 6ce554c09ae940812ad67ed97161f056c62101c6..a811718b10bf5d2317c3aff269fc378eb37fba7d 100644 --- a/include/dusk/AST/Stmt.h +++ b/include/dusk/AST/Stmt.h @@ -26,7 +26,7 @@ class IdentifierExpr; class ASTWalker; /// Describes statement type. -enum struct StmtKind { Break, Return, Range, Block, Func, For, While, If }; +enum struct StmtKind { Break, Return, Range, Block, Func, For, While, If, Subscript }; class Stmt : public ASTNode { /// Statement type @@ -65,6 +65,27 @@ public: virtual SMRange getSourceRange() const override; }; +/// Subscript statement. +class SubscriptStmt: public Stmt { + /// Subcript value + Expr *Value; + + /// Location of left bracket + SMLoc LBracket; + + /// Location of right bracket + SMLoc RBracket; + +public: + SubscriptStmt(Expr *V, SMLoc L, SMLoc R); + + Expr *getValue() const { return Value; } + SMLoc getLBracket() const { return LBracket; } + SMLoc getRBracket() const { return RBracket; } + + virtual SMRange getSourceRange() const override; +}; + /// Represents a range. class RangeStmt : public Stmt { /// Start of the range diff --git a/include/dusk/Parse/Parser.h b/include/dusk/Parse/Parser.h index f9ef38097996dbf087b26eca28fd17b9f8874631..faea278647bf73542d67530c5d7eceb50282a76a 100644 --- a/include/dusk/Parse/Parser.h +++ b/include/dusk/Parse/Parser.h @@ -142,6 +142,8 @@ private: Stmt *parseBreakStmt(); Stmt *parseReturnStmt(); + + Stmt *parseSubscriptStmt(); Stmt *parseFuncStmt(); @@ -163,8 +165,6 @@ private: SmallVector<Decl *, 128> parseVarPatternBody(); Decl *parseVarPatternItem(); - Pattern *parseSubscriptPattern(); - /// Creates and adds a new instance of \c ASTNode to the parser result /// and returns a pointer to it. template <typename Node, typename... Args> Node *make(Args &&... args) { diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 0b890508f15429289fa77ae5dbbbdf551e5b0ddf..625ab3f4076d1d7bd2c5f2b80fcb844b54eb7dbe 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -149,6 +149,13 @@ public: return true; } + bool visit(SubscriptStmt *S) { + Printer.printStmtPre(S); + super::visit(S->getValue()); + Printer.printStmtPost(S); + return true; + } + bool visit(RangeStmt *S) { Printer.printStmtPre(S); super::visit(S->getStart()); @@ -252,13 +259,6 @@ public: Printer.printPatternPost(P); return true; } - - bool visit(SubscriptPattern *P) { - Printer.printPatternPre(P); - super::visit(P->getValue()); - Printer.printPatternPost(P); - return true; - } }; /// Implementation of an \c ASTPrinter, which is used to pretty print the AST. @@ -312,6 +312,9 @@ public: if (!isAtStartOfLine()) printNewline(); return; + case StmtKind::Subscript: + *this << "["; + break; default: return; } @@ -319,13 +322,16 @@ public: virtual void printStmtPost(Stmt *S) override { switch (S->getKind()) { + case StmtKind::Block: + --(*this); + *this << tok::r_brace; + break; case StmtKind::Break: case StmtKind::Return: *this << ";"; break; - case StmtKind::Block: - --(*this); - *this << tok::r_brace; + case StmtKind::Subscript: + *this << "]"; break; default: return; @@ -338,11 +344,6 @@ public: case PatternKind::Expr: *this << "("; break; - case PatternKind::Subscript: - *this << "["; - break; - default: - break; } } @@ -352,11 +353,6 @@ public: case PatternKind::Expr: *this << ")"; break; - case PatternKind::Subscript: - *this << "]"; - break; - default: - break; } } }; diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp index d4066566a595081bbbaee0b7d632af5ac4bd197a..2cd819d32703e66b75d163681ae46f8d790c6b55 100644 --- a/lib/AST/ASTWalker.cpp +++ b/lib/AST/ASTWalker.cpp @@ -208,6 +208,16 @@ public: return false; return Walker.postWalk(S); } + + bool visit(SubscriptStmt *S) { + // Skip subtree + if (!Walker.preWalk(S)) + return true; + + if (!super::visit(S->getValue())) + return false; + return Walker.postWalk(S); + } bool visit(BlockStmt *S) { // Skip subtree @@ -293,15 +303,6 @@ public: return false; return Walker.postWalk(P); } - - bool visit(SubscriptPattern *P) { - // Skip subtree - if (!Walker.preWalk(P)) - return true; - - super::visit(P->getValue()); - return Walker.postWalk(P); - } }; } // End of anonymous namespace diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 5f37462c5b05fafe8544c56031b42bc2b445366b..996dae6a7f591908302fb5bdd1dec5fb4826dae1 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -76,7 +76,7 @@ SMRange CallExpr::getSourceRange() const { // MARK: - Subscript expression -SubscriptExpr::SubscriptExpr(Expr *B, Pattern *S) +SubscriptExpr::SubscriptExpr(Expr *B, Stmt *S) : Expr(ExprKind::Subscript), Base(B), Subscript(S) {} SMRange SubscriptExpr::getSourceRange() const { diff --git a/lib/AST/Pattern.cpp b/lib/AST/Pattern.cpp index 9357e408b2b4f9f9759550b225f5c118d6e853bc..a17aa3640ca92140127d89c8c16e6374b3c61673 100644 --- a/lib/AST/Pattern.cpp +++ b/lib/AST/Pattern.cpp @@ -33,11 +33,3 @@ VarPattern::VarPattern(SmallVector<Decl *, 128> &&V, SMLoc L, SMLoc R) SMRange VarPattern::getSourceRange() const { return {LPar, RPar}; } size_t VarPattern::count() const { return Vars.size(); } - -// MARK: - Subscript pattern - -SubscriptPattern::SubscriptPattern(Expr *V, SMLoc L, SMLoc R) - : Pattern(PatternKind::Subscript), Value(V), LBracet(L), RBracet(R) {} - -SMRange SubscriptPattern::getSourceRange() const { return {LBracet, RBracet}; } -size_t SubscriptPattern::count() const { return 1; } diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 48c69f6f74ebe41be3d77758b37264ed757736ba..522922d2ce924014bf4ffe42e70b3c6bac4c9878 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -40,6 +40,12 @@ SMRange RangeStmt::getSourceRange() const { return {Start->getLocStart(), End->getLocEnd()}; } +// MARK: - Subcsript statement +SubscriptStmt::SubscriptStmt(Expr *V, SMLoc L, SMLoc R) + : Stmt(StmtKind::Subscript), Value(V), LBracket(L), RBracket(R) {} + +SMRange SubscriptStmt::getSourceRange() const { return {LBracket, RBracket}; } + // MARK: - Block statement BlockStmt::BlockStmt(SMLoc S, SMLoc E, std::vector<ASTNode *> &&N) diff --git a/lib/Parser/ParseExpr.cpp b/lib/Parser/ParseExpr.cpp index 84c547da35b88aba8db30f520d9d5e2329057751..270c560bbfc1df15d23172855bd0b16e94bb6206 100644 --- a/lib/Parser/ParseExpr.cpp +++ b/lib/Parser/ParseExpr.cpp @@ -260,7 +260,7 @@ Expr *Parser::parseCallExpr(Expr *Dest) { Expr *Parser::parseSubscriptExpr(Expr *Dest) { // Validate `[` assert(Tok.is(tok::l_bracket) && "Invalid parse method."); - return make<SubscriptExpr>(Dest, parseSubscriptPattern()); + return make<SubscriptExpr>(Dest, parseSubscriptStmt()); } /// PrimaryExpr ::= '(' Expr ')' diff --git a/lib/Parser/ParsePattern.cpp b/lib/Parser/ParsePattern.cpp index 6cf4a7143b0a41feb24f577a9d0bcff72690a6bd..376f944477079872d847566f4f1de1dd1f203816 100644 --- a/lib/Parser/ParsePattern.cpp +++ b/lib/Parser/ParsePattern.cpp @@ -148,20 +148,3 @@ Decl *Parser::parseVarPatternItem() { } } -/// SubscriptionPattern ::= -/// [ Expr ] -Pattern *Parser::parseSubscriptPattern() { - // Validate `[` start. - assert(Tok.is(tok::l_bracket) && "Invalid parse method."); - - auto L = consumeToken(); - auto V = parseExpr(); - if (!consumeIf(tok::r_bracket)) { - diagnose(Tok.getLoc(), diag::DiagID::expected_r_bracket) - .fixItAfter("]", PreviousLoc); - return nullptr; - } - - return make<SubscriptPattern>(V, L, PreviousLoc); -} - diff --git a/lib/Parser/ParseStmt.cpp b/lib/Parser/ParseStmt.cpp index d0720dd6c01b47bc31771fa1053237186c8816f8..5e174f8af51710109d6ecda8dd20b89773f184a1 100644 --- a/lib/Parser/ParseStmt.cpp +++ b/lib/Parser/ParseStmt.cpp @@ -70,6 +70,23 @@ Stmt *Parser::parseReturnStmt() { return make<ReturnStmt>(RL, E); } +/// SubscriptionPattern ::= +/// [ Expr ] +Stmt *Parser::parseSubscriptStmt() { + // Validate `[` start. + assert(Tok.is(tok::l_bracket) && "Invalid parse method."); + + auto L = consumeToken(); + auto V = parseExpr(); + if (!consumeIf(tok::r_bracket)) { + diagnose(Tok.getLoc(), diag::DiagID::expected_r_bracket) + .fixItAfter("]", PreviousLoc); + return nullptr; + } + + return make<SubscriptStmt>(V, L, PreviousLoc); +} + /// Block ::= /// '{' BlockBody '}' Stmt *Parser::parseBlock() {