From f6e3738b9c824e56f561e75f0ff11cf3a0d2dd09 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 26 Mar 2012 16:09:27 +0200 Subject: 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 --- src/rustc/syntax/parse/parser.rs | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'src/rustc/syntax/parse/parser.rs') 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 { -- cgit 1.4.1-3-g733a5