diff options
| author | Jakub Wieczorek <jakubw@jakubw.net> | 2012-12-08 20:22:43 +0000 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2012-12-17 16:50:40 -0800 |
| commit | 1968cb315af9d128ee4457738fddd1eba275277f (patch) | |
| tree | 99dc401a2713e3502c9b53333b74767adad53e98 /src/libsyntax | |
| parent | 5bf7ba077330c4cdb75802a4ca2497af24d21c4e (diff) | |
| download | rust-1968cb315af9d128ee4457738fddd1eba275277f.tar.gz rust-1968cb315af9d128ee4457738fddd1eba275277f.zip | |
Add support for destructuring vectors in match expressions
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 40 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 10 |
6 files changed, 73 insertions, 2 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 444f90c7f04..351b2995471 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -389,6 +389,7 @@ enum pat_ { pat_region(@pat), // borrowed pointer pattern pat_lit(@expr), pat_range(@expr, @expr), + pat_vec(~[@pat], Option<@pat>) } #[auto_serialize] diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index ef7bd1d8928..294a66166fa 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -593,6 +593,14 @@ fn walk_pat(pat: @pat, it: fn(@pat)) { pat_box(s) | pat_uniq(s) | pat_region(s) => { walk_pat(s, it) } + pat_vec(elts, tail) => { + for elts.each |p| { + walk_pat(*p, it) + } + do option::iter(&tail) |tail| { + walk_pat(*tail, it) + } + } pat_wild | pat_lit(_) | pat_range(_, _) | pat_ident(_, _, _) | pat_enum(_, _) => { } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 93845f3dbb8..0b1ff4f56ec 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -356,7 +356,11 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ { pat_region(inner) => pat_region(fld.fold_pat(inner)), pat_range(e1, e2) => { pat_range(fld.fold_expr(e1), fld.fold_expr(e2)) - } + }, + pat_vec(elts, tail) => pat_vec( + vec::map(elts, |x| fld.fold_pat(*x)), + option::map(&tail, |tail| fld.fold_pat(*tail)) + ) }; } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 47f65ed2f8d..50ed0df28a0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1794,6 +1794,39 @@ impl Parser { }; } + fn parse_pat_vec_elements(refutable: bool) -> (~[@pat], Option<@pat>) { + let mut elements = ~[]; + let mut tail = None; + let mut first = true; + + while self.token != token::RBRACKET { + if first { first = false; } + else { self.expect(token::COMMA); } + + let mut is_tail = false; + if self.token == token::DOTDOT { + self.bump(); + is_tail = true; + } + + let subpat = self.parse_pat(refutable); + if is_tail { + match subpat { + @{ node: pat_wild, _ } => (), + @{ node: pat_ident(_, _, _), _ } => (), + @{ span, _ } => self.span_fatal( + span, ~"expected an identifier or `_`" + ) + } + tail = Some(subpat); + break; + } + + elements.push(subpat); + } + return (elements, tail); + } + fn parse_pat_fields(refutable: bool) -> (~[ast::field_pat], bool) { let mut fields = ~[]; let mut etc = false; @@ -1929,6 +1962,13 @@ impl Parser { pat = pat_tup(fields); } } + token::LBRACKET => { + self.bump(); + let (elements, tail) = self.parse_pat_vec_elements(refutable); + hi = self.span.hi; + self.expect(token::RBRACKET); + pat = ast::pat_vec(elements, tail); + } copy tok => { if !is_ident_or_path(tok) || self.is_keyword(~"true") diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index e977327e919..3b995addd62 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1641,6 +1641,16 @@ fn print_pat(s: ps, &&pat: @ast::pat, refutable: bool) { word(s.s, ~".."); print_expr(s, end); } + ast::pat_vec(elts, tail) => { + word(s.s, ~"["); + commasep(s, inconsistent, elts, |s, p| print_pat(s, p, refutable)); + do option::iter(&tail) |tail| { + if vec::len(elts) != 0u { word_space(s, ~","); } + word(s.s, ~".."); + print_pat(s, *tail, refutable); + } + word(s.s, ~"]"); + } } (s.ann.post)(ann_node); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 7b406564114..9a47edfeb05 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -251,7 +251,15 @@ fn visit_pat<E>(p: @pat, e: E, v: vt<E>) { (v.visit_expr)(e1, e, v); (v.visit_expr)(e2, e, v); } - pat_wild => () + pat_wild => (), + pat_vec(elts, tail) => { + for elts.each |elt| { + (v.visit_pat)(*elt, e, v); + } + do option::iter(&tail) |tail| { + (v.visit_pat)(*tail, e, v); + } + } } } |
