syntax: Allow any block-like expr to be used as alt arm w/o comma separator

This commit is contained in:
Brian Anderson 2012-08-01 16:16:53 -07:00
parent fd17d347b0
commit 507fba57d1
5 changed files with 99 additions and 34 deletions

View file

@ -588,13 +588,6 @@ fn view_path_id(p: @view_path) -> node_id {
}
}
fn lone_block_expr(blk: blk) -> option<@ast::expr> {
if blk.node.view_items.len() != 0 { ret none; }
if blk.node.stmts.len() != 0 { ret none; }
if blk.node.rules != default_blk { ret none; }
ret blk.node.expr;
}
// Local Variables:
// mode: rust
// fill-column: 78;

View file

@ -1477,9 +1477,10 @@ class parser {
// For distingishing between record literals and blocks
fn looking_at_record_literal() -> bool {
let lookahead = self.look_ahead(1);
self.token_is_keyword(~"mut", lookahead) ||
(is_plain_ident(lookahead) &&
self.look_ahead(2) == token::COLON)
self.token == token::LBRACE &&
(self.token_is_keyword(~"mut", lookahead) ||
(is_plain_ident(lookahead) &&
self.look_ahead(2) == token::COLON))
}
fn parse_record_literal() -> expr_ {
@ -1518,26 +1519,30 @@ class parser {
let pats = self.parse_pats();
let mut guard = none;
if self.eat_keyword(~"if") { guard = some(self.parse_expr()); }
let blk = if self.token != token::FAT_ARROW {
self.parse_block()
let expr = if self.token != token::FAT_ARROW {
self.parse_block_expr(self.last_span.lo, default_blk)
} else {
self.bump();
if self.token == token::LBRACE
&& !self.looking_at_record_literal() {
self.parse_block()
} else {
let expr = self.parse_expr();
if self.token != token::RBRACE {
self.expect(token::COMMA);
}
{node: {view_items: ~[],
stmts: ~[],
expr: some(expr),
id: self.get_id(),
rules: default_blk},
span: expr.span}
}
self.parse_expr_res(RESTRICT_STMT_EXPR)
};
let require_comma =
classify::expr_requires_semi_to_be_stmt(expr)
&& self.token != token::RBRACE;
if require_comma {
self.expect(token::COMMA);
} else {
self.eat(token::COMMA);
}
let blk = {node: {view_items: ~[],
stmts: ~[],
expr: some(expr),
id: self.get_id(),
rules: default_blk},
span: expr.span};
vec::push(arms, {pats: pats, guard: guard, body: blk});
}
let mut hi = self.span.hi;

View file

@ -6,7 +6,7 @@ import pp::{break_offset, word, printer,
inconsistent, eof};
import diagnostic;
import ast::{required, provided};
import ast_util::{operator_prec, lone_block_expr};
import ast_util::{operator_prec};
import dvec::{dvec, extensions};
import parse::classify::*;
import util::interner;
@ -1052,17 +1052,21 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
none { }
}
word_space(s, ~"=>");
alt lone_block_expr(arm.body) {
// Extract the expression from the extra block the parser adds
assert arm.body.node.view_items.is_empty();
assert arm.body.node.stmts.is_empty();
assert arm.body.node.rules == ast::default_blk;
alt arm.body.node.expr {
some(expr) => {
end(s); // close the ibox for the pattern
print_expr(s, expr);
if i < len - 1 { word(s.s, ~","); }
if expr_requires_semi_to_be_stmt(expr)
&& i < len - 1 {
word(s.s, ~",");
}
end(s); // close enclosing cbox
}
none => {
print_possibly_embedded_block(s, arm.body, block_normal,
alt_indent_unit);
}
none => fail
}
}
bclose_(s, expr.span, alt_indent_unit);

View file

@ -0,0 +1,7 @@
fn main() {
alt 0 {
0 => {
} + 5 //~ ERROR unexpected token: `+`
}
}

View file

@ -0,0 +1,56 @@
// no-reformat
// Testing the presense or absense of commas separating block-structure
// alt arm expressions
fn fun(_f: fn()) {
}
fn it(_f: fn() -> bool) {
}
fn main() {
alt 0 {
00 => {
}
01 => if true {
} else {
}
03 => alt 0 {
_ => ()
}
04 => do fun {
}
05 => for it {
}
06 => while false {
}
07 => loop {
}
08 => unsafe {
}
09 => unchecked {
}
10 => {
},
11 => if true {
} else {
},
13 => alt 0 {
_ => ()
},
14 => do fun {
},
15 => for it {
},
16 => while false {
},
17 => loop {
},
18 => unsafe {
},
19 => unchecked {
},
_ => ()
}
}