Skip to content

Commit d3e75ea

Browse files
committed
Parse 'loop' and 'again' the same
1 parent 443f799 commit d3e75ea

File tree

4 files changed

+41
-22
lines changed

4 files changed

+41
-22
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ struct parser {
883883
return pexpr(self.parse_sugary_call_expr(~"do", expr_do_body));
884884
} else if self.eat_keyword(~"while") {
885885
return pexpr(self.parse_while_expr());
886-
} else if self.eat_keyword(~"loop") {
886+
} else if self.eat_keyword(~"again") || self.eat_keyword(~"loop") {
887887
return pexpr(self.parse_loop_expr());
888888
} else if self.eat_keyword(~"match") {
889889
return pexpr(self.parse_alt_expr());
@@ -969,13 +969,6 @@ struct parser {
969969
ex = expr_break(None);
970970
}
971971
hi = self.span.hi;
972-
} else if self.eat_keyword(~"again") {
973-
if is_ident(self.token) {
974-
ex = expr_again(Some(self.parse_ident()));
975-
} else {
976-
ex = expr_again(None);
977-
}
978-
hi = self.span.hi;
979972
} else if self.eat_keyword(~"copy") {
980973
let e = self.parse_expr();
981974
ex = expr_copy(e);
@@ -1609,18 +1602,42 @@ struct parser {
16091602
}
16101603

16111604
fn parse_loop_expr() -> @expr {
1612-
let opt_ident;
1613-
if is_ident(self.token) && !self.is_any_keyword(copy self.token) {
1614-
opt_ident = Some(self.parse_ident());
1615-
self.expect(token::COLON);
1605+
// loop headers look like 'loop {' or 'loop unsafe {'
1606+
let is_loop_header =
1607+
self.token == token::LBRACE
1608+
|| (is_ident(copy self.token)
1609+
&& self.look_ahead(1) == token::LBRACE);
1610+
// labeled loop headers look like 'loop foo: {'
1611+
let is_labeled_loop_header =
1612+
is_ident(self.token)
1613+
&& !self.is_any_keyword(copy self.token)
1614+
&& self.look_ahead(1) == token::COLON;
1615+
1616+
if is_loop_header || is_labeled_loop_header {
1617+
// This is a loop body
1618+
let opt_ident;
1619+
if is_labeled_loop_header {
1620+
opt_ident = Some(self.parse_ident());
1621+
self.expect(token::COLON);
1622+
} else {
1623+
opt_ident = None;
1624+
}
1625+
1626+
let lo = self.last_span.lo;
1627+
let body = self.parse_block_no_value();
1628+
let mut hi = body.span.hi;
1629+
return self.mk_expr(lo, hi, expr_loop(body, opt_ident));
16161630
} else {
1617-
opt_ident = None;
1631+
// This is a 'continue' expression
1632+
let lo = self.span.lo;
1633+
let ex = if is_ident(self.token) {
1634+
expr_again(Some(self.parse_ident()))
1635+
} else {
1636+
expr_again(None)
1637+
};
1638+
let hi = self.span.hi;
1639+
return self.mk_expr(lo, hi, ex);
16181640
}
1619-
1620-
let lo = self.last_span.lo;
1621-
let body = self.parse_block_no_value();
1622-
let mut hi = body.span.hi;
1623-
return self.mk_expr(lo, hi, expr_loop(body, opt_ident));
16241641
}
16251642

16261643
// For distingishing between record literals and blocks

src/libsyntax/print/pprust.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,9 @@ fn print_possibly_embedded_block_(s: ps, blk: ast::blk, embedded: embed_type,
883883
// alt, do, & while unambiguously without being parenthesized
884884
fn print_maybe_parens_discrim(s: ps, e: @ast::expr) {
885885
let disambig = match e.node {
886-
ast::expr_ret(None) | ast::expr_fail(None) => true,
886+
ast::expr_ret(None)
887+
| ast::expr_fail(None)
888+
| ast::expr_again(*) => true,
887889
_ => false
888890
};
889891
if disambig { popen(s); }

src/test/run-pass/loop-break-cont.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn main() {
1717
is_even = false;
1818
i += 1u;
1919
if i % 2u != 0u {
20-
again;
20+
loop;
2121
}
2222
is_even = true;
2323
}
@@ -30,7 +30,7 @@ fn main() {
3030
is_even = false;
3131
i += 1u;
3232
if i % 2u != 0u {
33-
again;
33+
loop;
3434
}
3535
is_even = true;
3636
}

src/test/run-pass/weird-exprs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ fn canttouchthis() -> uint {
5959
fn angrydome() {
6060
loop { if break { } }
6161
let mut i = 0;
62-
loop { i += 1; if i == 1 { match again { 1 => { }, _ => fail ~"wat" } }
62+
loop { i += 1; if i == 1 { match (again) { 1 => { }, _ => fail ~"wat" } }
6363
break; }
6464
}
6565

0 commit comments

Comments
 (0)