diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2012-03-26 16:09:27 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2012-03-27 09:27:31 +0200 |
| commit | f6e3738b9c824e56f561e75f0ff11cf3a0d2dd09 (patch) | |
| tree | ab6624224bc83dc5edc4561b6d3d81860ecf6cef /src/rustc/syntax/parse | |
| parent | 9638e7fece158fd084a1d1f70970d716e9979f96 (diff) | |
| download | rust-f6e3738b9c824e56f561e75f0ff11cf3a0d2dd09.tar.gz rust-f6e3738b9c824e56f561e75f0ff11cf3a0d2dd09.zip | |
Support an alternate for syntax that calls a higher-order function
The last argument of the call must be a block, and the type of this
argument must a function returning bool. `break` and `cont` are
supported in the body of the block, and return `false` or `true` from
the function. When the end of the function is reached, `true` is
implicitly returned.
for vec::all([1, 2, 3]) {|elt|
if elt == 2 { break; }
log(error, elt);
}
Issue #1619
Diffstat (limited to 'src/rustc/syntax/parse')
| -rw-r--r-- | src/rustc/syntax/parse/parser.rs | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/src/rustc/syntax/parse/parser.rs b/src/rustc/syntax/parse/parser.rs index 78d8d2b6133..a898ee840be 100644 --- a/src/rustc/syntax/parse/parser.rs +++ b/src/rustc/syntax/parse/parser.rs @@ -1403,13 +1403,37 @@ fn parse_else_expr(p: parser) -> @ast::expr { } fn parse_for_expr(p: parser) -> @ast::expr { - let lo = p.last_span.lo; - let decl = parse_local(p, false, false); - expect_word(p, "in"); - let seq = parse_expr(p); - let body = parse_block_no_value(p); - let mut hi = body.span.hi; - ret mk_expr(p, lo, hi, ast::expr_for(decl, seq, body)); + let lo = p.last_span; + // FIXME remove this kludge after migration and snapshotting (#1619) + let new_style = alt p.token { + token::IDENT(_, false) { alt p.look_ahead(1u) { + token::DOT | token::LPAREN { true } + _ { false } + } } + token::IDENT(_, true) { true } + _ { false } + }; + if new_style { + let call = parse_expr(p); + alt call.node { + ast::expr_call(f, args, true) { + let b_arg = vec::last(args); + let last = mk_expr(p, b_arg.span.lo, b_arg.span.hi, + ast::expr_loop_body(b_arg)); + @{node: ast::expr_call(f, vec::init(args) + [last], true) + with *call} + } + _ { + p.span_fatal(lo, "`for` must be followed by a block call"); + } + } + } else { + let decl = parse_local(p, false, false); + expect_word(p, "in"); + let seq = parse_expr(p); + let body = parse_block_no_value(p); + mk_expr(p, lo.lo, body.span.hi, ast::expr_for(decl, seq, body)) + } } fn parse_while_expr(p: parser) -> @ast::expr { |
