Skip to content

Commit

Permalink
Support Ruby-style block argument syntax
Browse files Browse the repository at this point in the history
Issue #1054
  • Loading branch information
marijnh committed Oct 21, 2011
1 parent ff813f8 commit f134261
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions src/comp/syntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,10 @@ fn mk_mac_expr(p: parser, lo: uint, hi: uint, m: ast::mac_) -> @ast::expr {
span: ast_util::mk_sp(lo, hi)};
}

fn is_bar(t: token::token) -> bool {
alt t { token::BINOP(token::OR.) | token::OROR. { true } _ { false } }
}

fn parse_bottom_expr(p: parser) -> @ast::expr {
let lo = p.get_lo_pos();
let hi = p.get_hi_pos();
Expand Down Expand Up @@ -815,8 +819,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
hi = p.get_hi_pos();
expect(p, token::RBRACE);
ex = ast::expr_rec(fields, base);
} else if p.peek() == token::BINOP(token::OR) ||
p.peek() == token::OROR {
} else if is_bar(p.peek()) {
ret parse_fn_block_expr(p);
} else {
let blk = parse_block_tail(p, lo, ast::default_blk);
Expand Down Expand Up @@ -1061,10 +1064,8 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
ret e;
} else {
// Call expr.

let es =
parse_seq(token::LPAREN, token::RPAREN,
some(token::COMMA), parse_expr, p);
let es = parse_seq(token::LPAREN, token::RPAREN,
some(token::COMMA), parse_expr, p);
hi = es.span.hi;
let nd = ast::expr_call(e, es.node);
e = mk_expr(p, lo, hi, nd);
Expand All @@ -1088,6 +1089,19 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
t { unexpected(p, t); }
}
}
token::LBRACE. when is_bar(p.look_ahead(1u)) {
p.bump();
let blk = parse_fn_block_expr(p);
alt e.node {
ast::expr_call(f, args) {
e = @{node: ast::expr_call(f, args + [blk]) with *e};
}
_ {
e = mk_expr(p, lo, p.get_last_hi_pos(),
ast::expr_call(e, [blk]));
}
}
}
_ { ret e; }
}
}
Expand Down Expand Up @@ -1394,11 +1408,6 @@ fn parse_initializer(p: parser) -> option::t<ast::initializer> {
p.bump();
ret some({op: ast::init_move, expr: parse_expr(p)});
}





// Now that the the channel is the first argument to receive,
// combining it with an initializer doesn't really make sense.
// case (token::RECV) {
Expand Down Expand Up @@ -1792,7 +1801,7 @@ fn parse_fn_decl(p: parser, purity: ast::purity, il: ast::inlineness) ->
fn parse_fn_block_decl(p: parser) -> ast::fn_decl {
let inputs =
if p.peek() == token::OROR {
p.bump();;
p.bump();
[]
} else {
parse_seq(token::BINOP(token::OR), token::BINOP(token::OR),
Expand Down

0 comments on commit f134261

Please sign in to comment.