summaryrefslogtreecommitdiff
path: root/src/parse
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-08-19 10:27:38 +0800
committerJohn Hodge <tpg@mutabah.net>2016-08-19 10:27:38 +0800
commita3e8257c4f77f197c9be2dbae7aaddb81257abb2 (patch)
tree598c815b4e42041966e3a0834a118b9a7c56411f /src/parse
parent64c957b03ede8b0af825b50e6e551c61444a3275 (diff)
downloadmrust-a3e8257c4f77f197c9be2dbae7aaddb81257abb2.tar.gz
Patterns - Support tuples with .. (fully)
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/expr.cpp2
-rw-r--r--src/parse/pattern.cpp63
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)