summaryrefslogtreecommitdiff
path: root/src/parse/expr.cpp
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-11-02 11:07:23 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-11-02 11:07:23 +0800
commit1d02810c3cf908bfba7c15ae50eb5314603b9d85 (patch)
tree79dd5e4ef4c3ff79db0912ba546f08e61a7a8c10 /src/parse/expr.cpp
parent7111acba04d72fe4084b1a1f3209ff83efe8614d (diff)
parent8b53b38f40625ab0510f541d69db3f83332a830a (diff)
downloadmrust-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.cpp91
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);