diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-11-02 11:07:23 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-11-02 11:07:23 +0800 |
commit | 1d02810c3cf908bfba7c15ae50eb5314603b9d85 (patch) | |
tree | 79dd5e4ef4c3ff79db0912ba546f08e61a7a8c10 /src/parse/expr.cpp | |
parent | 7111acba04d72fe4084b1a1f3209ff83efe8614d (diff) | |
parent | 8b53b38f40625ab0510f541d69db3f83332a830a (diff) | |
download | mrust-1d02810c3cf908bfba7c15ae50eb5314603b9d85.tar.gz |
Merge branch 'nightly-1.29' - #95 Working support for rustc 1.29
Diffstat (limited to 'src/parse/expr.cpp')
-rw-r--r-- | src/parse/expr.cpp | 91 |
1 files changed, 68 insertions, 23 deletions
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 5194e1d8..2735c39e 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -32,8 +32,8 @@ ExprNodeP Parse_ExprBlockLine_Stmt(TokenStream& lex, bool& has_semicolon); ExprNodeP Parse_Stmt_Let(TokenStream& lex); ExprNodeP Parse_Expr0(TokenStream& lex); ExprNodeP Parse_IfStmt(TokenStream& lex); -ExprNodeP Parse_WhileStmt(TokenStream& lex, ::std::string lifetime); -ExprNodeP Parse_ForStmt(TokenStream& lex, ::std::string lifetime); +ExprNodeP Parse_WhileStmt(TokenStream& lex, RcString lifetime); +ExprNodeP Parse_ForStmt(TokenStream& lex, RcString lifetime); ExprNodeP Parse_Expr_Match(TokenStream& lex); ExprNodeP Parse_Expr1(TokenStream& lex); ExprNodeP Parse_ExprMacro(TokenStream& lex, AST::Path tok); @@ -57,13 +57,18 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex, bool is_unsafe/*=false*/) ::std::shared_ptr<AST::Module> local_mod; + if( LOOK_AHEAD(lex) == TOK_INTERPOLATED_BLOCK ) + { + GET_TOK(tok, lex); + return tok.take_frag_node(); + } + GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN); bool last_value_yielded = false; while( LOOK_AHEAD(lex) != TOK_BRACE_CLOSE ) { last_value_yielded = false; - DEBUG("tok = " << tok); // NOTE: Doc comments can appear within a function and apply to the function if( lex.parse_state().parent_attrs ) @@ -103,7 +108,7 @@ ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST: GET_TOK(tok, lex); // `union Ident` - contextual keyword - if( tok.type() == TOK_IDENT && tok.str() == "union" && lex.lookahead(0) == TOK_IDENT ) { + if( tok.type() == TOK_IDENT && tok.istr() == "union" && lex.lookahead(0) == TOK_IDENT ) { PUTBACK(tok, lex); if( !local_mod ) { local_mod = lex.parse_state().get_current_mod().add_anon(); @@ -112,7 +117,7 @@ ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST: return ExprNodeP(); } - if( tok.type() == TOK_IDENT && tok.str() == "macro_rules" && lex.lookahead(0) == TOK_EXCLAM ) + if( tok.type() == TOK_IDENT && tok.istr() == "macro_rules" && lex.lookahead(0) == TOK_EXCLAM ) { // Special case - create a local module if macro_rules! is seen // - Allows correct scoping of defined macros @@ -124,6 +129,7 @@ ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST: switch(tok.type()) { // Items: + case TOK_INTERPOLATED_VIS: case TOK_RWORD_PUB: // NOTE: Allowed, but doesn't do much case TOK_RWORD_TYPE: @@ -185,7 +191,7 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence) if( GET_TOK(tok, lex) == TOK_LIFETIME ) { // Lifetimes can only precede loops... and blocks? - ::std::string lifetime = tok.str(); + auto lifetime = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_COLON); switch( GET_TOK(tok, lex) ) @@ -248,6 +254,7 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence) case TOK_BRACE_OPEN: { PUTBACK(tok, lex); ret = Parse_ExprBlockNode(lex); } + // If the block is followed by `.` or `?`, it's actually an expression! if( lex.lookahead(0) == TOK_DOT || lex.lookahead(0) == TOK_QMARK ) { lex.putback( Token(Token::TagTakeIP(), InterpolatedFragment(InterpolatedFragment::EXPR, ret.release())) ); return Parse_ExprBlockLine_Stmt(lex, *add_silence); @@ -284,7 +291,7 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence) // If a braced macro invocation is the first part of a statement, don't expect a semicolon if( lex.lookahead(1) == TOK_BRACE_OPEN || (lex.lookahead(1) == TOK_IDENT && lex.lookahead(2) == TOK_BRACE_OPEN) ) { lex.getToken(); - return Parse_ExprMacro(lex, tok.str()); + return Parse_ExprMacro(lex, tok.istr()); } } // Fall through to the statement code @@ -316,7 +323,7 @@ ExprNodeP Parse_ExprBlockLine_Stmt(TokenStream& lex, bool& has_semicolon) } /// While loop (either as a statement, or as part of an expression) -ExprNodeP Parse_WhileStmt(TokenStream& lex, ::std::string lifetime) +ExprNodeP Parse_WhileStmt(TokenStream& lex, RcString lifetime) { Token tok; @@ -342,12 +349,12 @@ ExprNodeP Parse_WhileStmt(TokenStream& lex, ::std::string lifetime) } } /// For loop (either as a statement, or as part of an expression) -ExprNodeP Parse_ForStmt(TokenStream& lex, ::std::string lifetime) +ExprNodeP Parse_ForStmt(TokenStream& lex, RcString lifetime) { Token tok; // Irrefutable pattern - AST::Pattern pat = Parse_Pattern(lex, false); + auto pat = Parse_Pattern(lex, false); GET_CHECK_TOK(tok, lex, TOK_RWORD_IN); ExprNodeP val; { @@ -435,6 +442,9 @@ ExprNodeP Parse_Expr_Match(TokenStream& lex) arm.m_attrs = Parse_ItemAttrs(lex); + // HACK: Questionably valid, but 1.29 librustc/hir/lowering.rs needs this + if( LOOK_AHEAD(lex) == TOK_PIPE ) + GET_TOK(tok, lex); do { // Refutable pattern arm.m_patterns.push_back( Parse_Pattern(lex, true) ); @@ -461,6 +471,17 @@ ExprNodeP Parse_Expr_Match(TokenStream& lex) return NEWNODE( AST::ExprNode_Match, ::std::move(switch_val), ::std::move(arms) ); } +/// "do catch" block +ExprNodeP Parse_Expr_Try(TokenStream& lex) +{ + TRACE_FUNCTION; + //Token tok; + + auto inner = Parse_ExprBlockNode(lex); + //TODO(lex.point_span(), "do catch"); + return NEWNODE(AST::ExprNode_Try, ::std::move(inner)); +} + /// Parses the 'stmt' fragment specifier /// - Flow control /// - Expressions @@ -503,10 +524,10 @@ ExprNodeP Parse_Stmt(TokenStream& lex) case TOK_RWORD_BREAK: type = AST::ExprNode_Flow::BREAK; break; default: throw ParseError::BugCheck(/*lex,*/ "continue/break"); } - ::std::string lifetime; + RcString lifetime; if( GET_TOK(tok, lex) == TOK_LIFETIME ) { - lifetime = tok.str(); + lifetime = tok.istr(); // TODO: Hygine? GET_TOK(tok, lex); } ExprNodeP val; @@ -706,7 +727,7 @@ ExprNodeP Parse_Expr1_1(TokenStream& lex) ExprNodeP left, right; // Inclusive range to a value - if( GET_TOK(tok, lex) == TOK_TRIPLE_DOT ) { + if( GET_TOK(tok, lex) == TOK_TRIPLE_DOT || (TARGETVER_1_29 && tok.type() == TOK_DOUBLE_DOT_EQUAL) ) { right = next(lex); return NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::RANGE_INC, nullptr, mv$(right) ); } @@ -746,6 +767,13 @@ LEFTASSOC(Parse_Expr1_2, Parse_Expr1_5, case TOK_TRIPLE_DOT: rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::RANGE_INC, mv$(rv), next(lex) ); break; + case TOK_DOUBLE_DOT_EQUAL: + if( TARGETVER_1_29 ) + { + rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::RANGE_INC, mv$(rv), next(lex) ); + break; + } + // Fall through ) // 1: Bool OR LEFTASSOC(Parse_Expr1_5, Parse_Expr2, @@ -920,26 +948,26 @@ ExprNodeP Parse_ExprFC(TokenStream& lex) switch(GET_TOK(tok, lex)) { case TOK_IDENT: { - AST::PathNode path( mv$(tok.str()) , {}); + AST::PathNode pn( tok.istr() , {}); switch( GET_TOK(tok, lex) ) { case TOK_PAREN_OPEN: PUTBACK(tok, lex); - val = NEWNODE( AST::ExprNode_CallMethod, ::std::move(val), ::std::move(path), Parse_ParenList(lex) ); + val = NEWNODE( AST::ExprNode_CallMethod, ::std::move(val), ::std::move(pn), Parse_ParenList(lex) ); break; case TOK_DOUBLE_COLON: GET_CHECK_TOK(tok, lex, TOK_LT); - path.args() = Parse_Path_GenericList(lex); - val = NEWNODE( AST::ExprNode_CallMethod, ::std::move(val), ::std::move(path), Parse_ParenList(lex) ); + pn.args() = Parse_Path_GenericList(lex); + val = NEWNODE( AST::ExprNode_CallMethod, ::std::move(val), ::std::move(pn), Parse_ParenList(lex) ); break; default: - val = NEWNODE( AST::ExprNode_Field, ::std::move(val), ::std::string(path.name()) ); + val = NEWNODE( AST::ExprNode_Field, ::std::move(val), pn.name() ); PUTBACK(tok, lex); break; } break; } case TOK_INTEGER: - val = NEWNODE( AST::ExprNode_Field, ::std::move(val), FMT(tok.intval()) ); + val = NEWNODE( AST::ExprNode_Field, ::std::move(val), RcString::new_interned(FMT(tok.intval())) ); break; default: throw ParseError::Unexpected(lex, mv$(tok)); @@ -1005,7 +1033,7 @@ ExprNodeP Parse_ExprVal_StructLiteral(TokenStream& lex, AST::Path path) } CHECK_TOK(tok, TOK_IDENT); auto h = lex.getHygiene(); - auto name = mv$(tok.str()); + auto name = tok.istr(); ExprNodeP val; if( lex.lookahead(0) != TOK_COLON ) @@ -1110,6 +1138,23 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) return Parse_WhileStmt(lex, ""); case TOK_RWORD_FOR: return Parse_ForStmt(lex, ""); + case TOK_RWORD_DO: + if( TARGETVER_1_29 ) + { + // `do catch` - stabilised later as `try` + if( GET_TOK(tok, lex) == TOK_IDENT && tok.istr() == "catch" ) + { + return Parse_Expr_Try(lex); + } + else + { + throw ParseError::Unexpected(lex, tok); + } + } + else + { + throw ParseError::Unexpected(lex, tok); + } case TOK_RWORD_MATCH: return Parse_Expr_Match(lex); case TOK_RWORD_IF: @@ -1275,10 +1320,10 @@ ExprNodeP Parse_ExprMacro(TokenStream& lex, AST::Path path) } Token tok; - ::std::string name = path.m_class.is_Local() ? path.m_class.as_Local().name : path.nodes()[0].name(); - ::std::string ident; + auto name = path.m_class.is_Local() ? path.m_class.as_Local().name : path.nodes()[0].name(); + RcString ident; if( GET_TOK(tok, lex) == TOK_IDENT ) { - ident = mv$(tok.str()); + ident = tok.istr(); } else { PUTBACK(tok, lex); |