summaryrefslogtreecommitdiff
path: root/src/parse/pattern.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse/pattern.cpp')
-rw-r--r--src/parse/pattern.cpp48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp
index 4e4fa862..12f35aa7 100644
--- a/src/parse/pattern.cpp
+++ b/src/parse/pattern.cpp
@@ -16,6 +16,7 @@ using AST::ExprNode;
::std::vector<AST::Pattern> Parse_PatternList(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);
AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refutable);
@@ -198,9 +199,9 @@ AST::Pattern Parse_PatternReal1(TokenStream& lex, bool is_refutable)
case TOK_BYTESTRING:
return AST::Pattern( AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_String, tok.str()) );
case TOK_PAREN_OPEN:
- return AST::Pattern(AST::Pattern::TagTuple(), Parse_PatternList(lex, is_refutable));
+ return AST::Pattern( AST::Pattern::TagTuple(), Parse_PatternList(lex, is_refutable) );
case TOK_SQUARE_OPEN:
- throw ParseError::Todo(lex, "array patterns");
+ return Parse_PatternReal_Slice(lex, is_refutable);
default:
throw ParseError::Unexpected(lex, tok);
}
@@ -221,6 +222,49 @@ AST::Pattern Parse_PatternReal_Path(TokenStream& lex, AST::Path path, bool is_re
}
}
+AST::Pattern Parse_PatternReal_Slice(TokenStream& lex, bool is_refutable)
+{
+ auto sp = lex.start_span();
+ Token tok;
+
+ auto rv = ::AST::Pattern( AST::Pattern::TagSlice() );
+ auto& rv_array = rv.data().as_Slice();
+
+ bool is_trailing = false;
+ while(GET_TOK(tok, lex) != TOK_SQUARE_CLOSE)
+ {
+ if( tok.type() == TOK_IDENT && lex.lookahead(1) == TOK_DOUBLE_DOT) {
+ if(is_trailing)
+ ERROR(lex.end_span(sp), E0000, "Multiple instances of .. in a slice pattern");
+ rv_array.extra_bind = mv$(tok.str());
+ is_trailing = true;
+
+ GET_TOK(tok, lex); // TOK_DOUBLE_DOT
+ }
+ else if( tok.type() == TOK_DOUBLE_DOT ) {
+ if(is_trailing)
+ ERROR(lex.end_span(sp), E0000, "Multiple instances of .. in a slice pattern");
+ rv_array.extra_bind = "_";
+ is_trailing = true;
+ }
+ else {
+ lex.putback(tok);
+ if(is_trailing) {
+ rv_array.trailing.push_back( Parse_Pattern(lex, is_refutable) );
+ }
+ else {
+ rv_array.leading.push_back( Parse_Pattern(lex, is_refutable) );
+ }
+ }
+
+ if( GET_TOK(tok, lex) != TOK_COMMA )
+ break;
+ }
+ CHECK_TOK(tok, TOK_SQUARE_CLOSE);
+
+ return rv;
+}
+
::std::vector<AST::Pattern> Parse_PatternList(TokenStream& lex, bool is_refutable)
{
TRACE_FUNCTION;