diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-19 10:27:38 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-19 10:27:38 +0800 |
commit | a3e8257c4f77f197c9be2dbae7aaddb81257abb2 (patch) | |
tree | 598c815b4e42041966e3a0834a118b9a7c56411f /src/parse | |
parent | 64c957b03ede8b0af825b50e6e551c61444a3275 (diff) | |
download | mrust-a3e8257c4f77f197c9be2dbae7aaddb81257abb2.tar.gz |
Patterns - Support tuples with .. (fully)
Diffstat (limited to 'src/parse')
-rw-r--r-- | src/parse/expr.cpp | 2 | ||||
-rw-r--r-- | src/parse/pattern.cpp | 63 |
2 files changed, 33 insertions, 32 deletions
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 44f0b35d..682d641c 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -730,7 +730,7 @@ LEFTASSOC(Parse_Expr10, Parse_Expr11, // 11: Cast
LEFTASSOC(Parse_Expr11, Parse_Expr12,
case TOK_RWORD_AS:
- rv = NEWNODE( AST::ExprNode_Cast, ::std::move(rv), Parse_Type(lex) );
+ rv = NEWNODE( AST::ExprNode_Cast, ::std::move(rv), Parse_Type(lex, false) );
break;
)
// 12: Type Ascription
diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp index a2b5afb8..ded81103 100644 --- a/src/parse/pattern.cpp +++ b/src/parse/pattern.cpp @@ -15,7 +15,7 @@ using AST::ExprNode; -::AST::Pattern::TuplePat Parse_PatternList(TokenStream& lex, bool is_refutable); +::AST::Pattern::TuplePat Parse_PatternTuple(TokenStream& lex, bool is_refutable); AST::Pattern Parse_PatternReal_Slice(TokenStream& lex, bool is_refutable); AST::Pattern Parse_PatternReal_Path(TokenStream& lex, AST::Path path, bool is_refutable); AST::Pattern Parse_PatternReal(TokenStream& lex, bool is_refutable); @@ -231,7 +231,7 @@ AST::Pattern Parse_PatternReal1(TokenStream& lex, bool is_refutable) // TODO: Differentiate byte and UTF-8 strings return AST::Pattern( AST::Pattern::TagValue(), AST::Pattern::Value::make_String( mv$(tok.str()) ) ); case TOK_PAREN_OPEN: - return AST::Pattern( AST::Pattern::TagTuple(), Parse_PatternList(lex, is_refutable) ); + return AST::Pattern( AST::Pattern::TagTuple(), Parse_PatternTuple(lex, is_refutable) ); case TOK_SQUARE_OPEN: return Parse_PatternReal_Slice(lex, is_refutable); default: @@ -245,7 +245,7 @@ AST::Pattern Parse_PatternReal_Path(TokenStream& lex, AST::Path path, bool is_re switch( GET_TOK(tok, lex) ) { case TOK_PAREN_OPEN: - return AST::Pattern( AST::Pattern::TagNamedTuple(), mv$(path), Parse_PatternList(lex, is_refutable) ); + return AST::Pattern( AST::Pattern::TagNamedTuple(), mv$(path), Parse_PatternTuple(lex, is_refutable) ); case TOK_BRACE_OPEN: return Parse_PatternStruct(lex, mv$(path), is_refutable); default: @@ -310,48 +310,49 @@ AST::Pattern Parse_PatternReal_Slice(TokenStream& lex, bool is_refutable) return rv; } -::AST::Pattern::TuplePat Parse_PatternList(TokenStream& lex, bool is_refutable) +::AST::Pattern::TuplePat Parse_PatternTuple(TokenStream& lex, bool is_refutable) { TRACE_FUNCTION; auto sp = lex.start_span(); Token tok; - auto glob_pos = ::AST::Pattern::TupleGlob::None; - - auto end = TOK_PAREN_CLOSE; - // 1. Leading `..` - if( LOOK_AHEAD(lex) == TOK_DOUBLE_DOT ) { - GET_TOK(tok, lex); - glob_pos = ::AST::Pattern::TupleGlob::Start; + ::std::vector<AST::Pattern> leading; + while( LOOK_AHEAD(lex) != TOK_PAREN_CLOSE && LOOK_AHEAD(lex) != TOK_DOUBLE_DOT ) + { + leading.push_back( Parse_Pattern(lex, is_refutable) ); + if( GET_TOK(tok, lex) != TOK_COMMA ) { - CHECK_TOK(tok, end); - return ::AST::Pattern::TuplePat { glob_pos, {} }; + CHECK_TOK(tok, TOK_PAREN_CLOSE); + return AST::Pattern::TuplePat { mv$(leading), false, {} }; } } - // 2. Body - ::std::vector<AST::Pattern> child_pats; - do { - if( GET_TOK(tok, lex) == end || tok.type() == TOK_DOUBLE_DOT ) - break; - else - PUTBACK(tok, lex); + if( LOOK_AHEAD(lex) != TOK_DOUBLE_DOT ) + { + GET_TOK(tok, lex); - AST::Pattern pat = Parse_Pattern(lex, is_refutable); - DEBUG("pat = " << pat); - child_pats.push_back( ::std::move(pat) ); - } while( GET_TOK(tok, lex) == TOK_COMMA ); + CHECK_TOK(tok, TOK_PAREN_CLOSE); + return AST::Pattern::TuplePat { mv$(leading), false, {} }; + } + GET_CHECK_TOK(tok, lex, TOK_DOUBLE_DOT); - // 3. Trailing `..` - if( tok.type() == TOK_DOUBLE_DOT ) { - if( glob_pos != ::AST::Pattern::TupleGlob::None ) { - ERROR(lex.end_span(sp), E0000, "Multiple instances of .. in pattern"); + ::std::vector<AST::Pattern> trailing; + if( GET_TOK(tok, lex) == TOK_COMMA ) + { + while( LOOK_AHEAD(lex) != TOK_PAREN_CLOSE ) + { + trailing.push_back( Parse_Pattern(lex, is_refutable) ); + + if( GET_TOK(tok, lex) != TOK_COMMA ) { + PUTBACK(tok, lex); + break; + } } - glob_pos = ::AST::Pattern::TupleGlob::End; GET_TOK(tok, lex); } - CHECK_TOK(tok, end); - return ::AST::Pattern::TuplePat { glob_pos, mv$(child_pats) }; + + CHECK_TOK(tok, TOK_PAREN_CLOSE); + return ::AST::Pattern::TuplePat { mv$(leading), true, mv$(trailing) }; } AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refutable) |