diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-08-22 14:38:48 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-08-22 17:49:31 +0200 |
| commit | 7d08678b740d779d9f0e1e6d15d7cf6ad4e1b57a (patch) | |
| tree | 71a73aa6e74449cab2048957f79a5ca05138e22b /src/comp/syntax | |
| parent | a2466233b4217cc8da4d2ebcd5f7c0b11db5b861 (diff) | |
| download | rust-7d08678b740d779d9f0e1e6d15d7cf6ad4e1b57a.tar.gz rust-7d08678b740d779d9f0e1e6d15d7cf6ad4e1b57a.zip | |
Implement pattern guards
The syntax is
alt x {
mypat where mycond { ... }
}
The condition may refer to any of the variables bound by the pattern.
When a guard fails, pattern-matching continues with the next pattern.
Closes #857
Diffstat (limited to 'src/comp/syntax')
| -rw-r--r-- | src/comp/syntax/ast.rs | 2 | ||||
| -rw-r--r-- | src/comp/syntax/fold.rs | 4 | ||||
| -rw-r--r-- | src/comp/syntax/parse/parser.rs | 6 | ||||
| -rw-r--r-- | src/comp/syntax/print/pprust.rs | 8 | ||||
| -rw-r--r-- | src/comp/syntax/visit.rs | 1 |
5 files changed, 18 insertions, 3 deletions
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index 80d327b119b..2537aa95f36 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -267,7 +267,7 @@ type decl = spanned<decl_>; tag decl_ { decl_local([@local]); decl_item(@item); } -type arm = {pats: [@pat], body: blk}; +type arm = {pats: [@pat], guard: option::t<@expr>, body: blk}; type field_ = {mut: mutability, ident: ident, expr: @expr}; diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs index ef04e66d756..a91b2f31814 100644 --- a/src/comp/syntax/fold.rs +++ b/src/comp/syntax/fold.rs @@ -269,7 +269,9 @@ fn noop_fold_stmt(s: &stmt_, fld: ast_fold) -> stmt_ { } fn noop_fold_arm(a: &arm, fld: ast_fold) -> arm { - ret {pats: vec::map(fld.fold_pat, a.pats), body: fld.fold_block(a.body)}; + ret {pats: vec::map(fld.fold_pat, a.pats), + guard: option::map(fld.fold_expr, a.guard), + body: fld.fold_block(a.body)}; } fn noop_fold_pat(p: &pat_, fld: ast_fold) -> pat_ { diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index d20f345b3af..b20c7905013 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -1360,8 +1360,12 @@ fn parse_alt_expr(p: &parser) -> @ast::expr { let arms: [ast::arm] = []; while p.peek() != token::RBRACE { let pats = parse_pats(p); + let guard = none; + if eat_word(p, "when") { + guard = some(parse_expr(p)); + } let blk = parse_block(p); - arms += [{pats: pats, body: blk}]; + arms += [{pats: pats, guard: guard, body: blk}]; } let hi = p.get_hi_pos(); p.bump(); diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs index c0e38a3b40e..8ecbfd58405 100644 --- a/src/comp/syntax/print/pprust.rs +++ b/src/comp/syntax/print/pprust.rs @@ -905,6 +905,14 @@ fn print_expr(s: &ps, expr: &@ast::expr) { print_pat(s, p); } space(s.s); + alt arm.guard { + some(e) { + word_space(s, "when"); + print_expr(s, e); + space(s.s); + } + none. {} + } print_possibly_embedded_block(s, arm.body, block_normal, alt_indent_unit); } diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs index 350dfc3dd44..d69104a7010 100644 --- a/src/comp/syntax/visit.rs +++ b/src/comp/syntax/visit.rs @@ -332,6 +332,7 @@ fn visit_expr<E>(ex: &@expr, e: &E, v: &vt<E>) { fn visit_arm<E>(a: &arm, e: &E, v: &vt<E>) { for p: @pat in a.pats { v.visit_pat(p, e, v); } + visit_expr_opt(a.guard, e, v); v.visit_block(a.body, e, v); } |
