For #2229, recognize 'again' in place of 'cont', final change pending snapshot.
This commit is contained in:
parent
e20f63d095
commit
ceac155211
19 changed files with 34 additions and 34 deletions
16
doc/rust.md
16
doc/rust.md
|
@ -209,9 +209,9 @@ import export use mod
|
||||||
The keywords in [source files](#source-files) are the following strings:
|
The keywords in [source files](#source-files) are the following strings:
|
||||||
|
|
||||||
~~~~~~~~ {.keyword}
|
~~~~~~~~ {.keyword}
|
||||||
alt assert
|
alt again assert
|
||||||
break
|
break
|
||||||
check claim class const cont copy
|
check claim class const copy
|
||||||
drop
|
drop
|
||||||
else enum export extern
|
else enum export extern
|
||||||
fail false fn for
|
fail false fn for
|
||||||
|
@ -2034,19 +2034,19 @@ break_expr : "break" ;
|
||||||
Executing a `break` expression immediately terminates the innermost loop
|
Executing a `break` expression immediately terminates the innermost loop
|
||||||
enclosing it. It is only permitted in the body of a loop.
|
enclosing it. It is only permitted in the body of a loop.
|
||||||
|
|
||||||
### Continue expressions
|
### Again expressions
|
||||||
|
|
||||||
~~~~~~~~{.ebnf .gram}
|
~~~~~~~~{.ebnf .gram}
|
||||||
break_expr : "cont" ;
|
again_expr : "again" ;
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
Evaluating a `cont` expression immediately terminates the current iteration of
|
Evaluating an `again` expression immediately terminates the current iteration of
|
||||||
the innermost loop enclosing it, returning control to the loop *head*. In the
|
the innermost loop enclosing it, returning control to the loop *head*. In the
|
||||||
case of a `while` loop, the head is the conditional expression controlling the
|
case of a `while` loop, the head is the conditional expression controlling the
|
||||||
loop. In the case of a `for` loop, the head is the vector-element increment
|
loop. In the case of a `for` loop, the head is the call-expression controlling
|
||||||
controlling the loop.
|
the loop.
|
||||||
|
|
||||||
A `cont` expression is only permitted in the body of a loop.
|
An `again` expression is only permitted in the body of a loop.
|
||||||
|
|
||||||
|
|
||||||
### For expressions
|
### For expressions
|
||||||
|
|
|
@ -783,7 +783,7 @@ a specific value, are not allowed.
|
||||||
|
|
||||||
`while` produces a loop that runs as long as its given condition
|
`while` produces a loop that runs as long as its given condition
|
||||||
(which must have type `bool`) evaluates to true. Inside a loop, the
|
(which must have type `bool`) evaluates to true. Inside a loop, the
|
||||||
keyword `break` can be used to abort the loop, and `cont` can be used
|
keyword `break` can be used to abort the loop, and `again` can be used
|
||||||
to abort the current iteration and continue with the next.
|
to abort the current iteration and continue with the next.
|
||||||
|
|
||||||
~~~~
|
~~~~
|
||||||
|
@ -1187,7 +1187,7 @@ Empty argument lists can be omitted from `do` expressions.
|
||||||
|
|
||||||
Most iteration in Rust is done with `for` loops. Like `do`,
|
Most iteration in Rust is done with `for` loops. Like `do`,
|
||||||
`for` is a nice syntax for doing control flow with closures.
|
`for` is a nice syntax for doing control flow with closures.
|
||||||
Additionally, within a `for` loop, `break, `cont`, and `ret`
|
Additionally, within a `for` loop, `break, `again`, and `ret`
|
||||||
work just as they do with `while` and `loop`.
|
work just as they do with `while` and `loop`.
|
||||||
|
|
||||||
Consider again our `each` function, this time improved to
|
Consider again our `each` function, this time improved to
|
||||||
|
@ -1221,8 +1221,8 @@ each(~[2, 4, 8, 5, 16], |n| {
|
||||||
With `for`, functions like `each` can be treated more
|
With `for`, functions like `each` can be treated more
|
||||||
like builtin looping structures. When calling `each`
|
like builtin looping structures. When calling `each`
|
||||||
in a `for` loop, instead of returning `false` to break
|
in a `for` loop, instead of returning `false` to break
|
||||||
out of the loop, you just write `break`. To continue
|
out of the loop, you just write `break`. To skip ahead
|
||||||
to the next iteration, write `cont`.
|
to the next iteration, write `again`.
|
||||||
|
|
||||||
~~~~
|
~~~~
|
||||||
# import each = vec::each;
|
# import each = vec::each;
|
||||||
|
|
|
@ -56,9 +56,9 @@
|
||||||
"trait" "fn" "enum" "iface"
|
"trait" "fn" "enum" "iface"
|
||||||
"impl"))
|
"impl"))
|
||||||
(puthash word 'def table))
|
(puthash word 'def table))
|
||||||
(dolist (word '("assert"
|
(dolist (word '("again" "assert"
|
||||||
"break"
|
"break"
|
||||||
"check" "claim" "cont" "copy"
|
"check" "claim" "copy"
|
||||||
"do" "drop"
|
"do" "drop"
|
||||||
"else" "export" "extern"
|
"else" "export" "extern"
|
||||||
"fail" "for"
|
"fail" "for"
|
||||||
|
|
|
@ -42,7 +42,7 @@ fn common_exprs() -> ~[ast::expr] {
|
||||||
}
|
}
|
||||||
|
|
||||||
~[dse(ast::expr_break),
|
~[dse(ast::expr_break),
|
||||||
dse(ast::expr_cont),
|
dse(ast::expr_again),
|
||||||
dse(ast::expr_fail(option::none)),
|
dse(ast::expr_fail(option::none)),
|
||||||
dse(ast::expr_fail(option::some(
|
dse(ast::expr_fail(option::some(
|
||||||
@dse(ast::expr_lit(@dsl(ast::lit_str(@"boo"))))))),
|
@dse(ast::expr_lit(@dsl(ast::lit_str(@"boo"))))))),
|
||||||
|
|
|
@ -336,7 +336,7 @@ enum expr_ {
|
||||||
expr_addr_of(mutability, @expr),
|
expr_addr_of(mutability, @expr),
|
||||||
expr_fail(option<@expr>),
|
expr_fail(option<@expr>),
|
||||||
expr_break,
|
expr_break,
|
||||||
expr_cont,
|
expr_again,
|
||||||
expr_ret(option<@expr>),
|
expr_ret(option<@expr>),
|
||||||
expr_log(int, @expr, @expr),
|
expr_log(int, @expr, @expr),
|
||||||
|
|
||||||
|
|
|
@ -464,7 +464,7 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
|
||||||
}
|
}
|
||||||
expr_path(pth) { expr_path(fld.fold_path(pth)) }
|
expr_path(pth) { expr_path(fld.fold_path(pth)) }
|
||||||
expr_fail(e) { expr_fail(option::map(e, fld.fold_expr)) }
|
expr_fail(e) { expr_fail(option::map(e, fld.fold_expr)) }
|
||||||
expr_break | expr_cont { copy e }
|
expr_break | expr_again { copy e }
|
||||||
expr_ret(e) { expr_ret(option::map(e, fld.fold_expr)) }
|
expr_ret(e) { expr_ret(option::map(e, fld.fold_expr)) }
|
||||||
expr_log(i, lv, e) { expr_log(i, fld.fold_expr(lv),
|
expr_log(i, lv, e) { expr_log(i, fld.fold_expr(lv),
|
||||||
fld.fold_expr(e)) }
|
fld.fold_expr(e)) }
|
||||||
|
|
|
@ -966,8 +966,9 @@ class parser {
|
||||||
} else if self.eat_keyword("break") {
|
} else if self.eat_keyword("break") {
|
||||||
ex = expr_break;
|
ex = expr_break;
|
||||||
hi = self.span.hi;
|
hi = self.span.hi;
|
||||||
} else if self.eat_keyword("cont") {
|
} else if self.eat_keyword("cont") ||
|
||||||
ex = expr_cont;
|
self.eat_keyword("again") {
|
||||||
|
ex = expr_again;
|
||||||
hi = self.span.hi;
|
hi = self.span.hi;
|
||||||
} else if self.eat_keyword("copy") {
|
} else if self.eat_keyword("copy") {
|
||||||
let e = self.parse_expr();
|
let e = self.parse_expr();
|
||||||
|
|
|
@ -304,8 +304,7 @@ fn contextual_keyword_table() -> hashmap<str, ()> {
|
||||||
fn restricted_keyword_table() -> hashmap<str, ()> {
|
fn restricted_keyword_table() -> hashmap<str, ()> {
|
||||||
let words = str_hash();
|
let words = str_hash();
|
||||||
let keys = ~[
|
let keys = ~[
|
||||||
"alt",
|
"alt", "again", "assert",
|
||||||
"assert",
|
|
||||||
"break",
|
"break",
|
||||||
"check", "claim", "class", "const", "cont", "copy",
|
"check", "claim", "class", "const", "cont", "copy",
|
||||||
"do", "drop",
|
"do", "drop",
|
||||||
|
|
|
@ -1063,7 +1063,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::expr_break { word(s.s, "break"); }
|
ast::expr_break { word(s.s, "break"); }
|
||||||
ast::expr_cont { word(s.s, "cont"); }
|
ast::expr_again { word(s.s, "again"); }
|
||||||
ast::expr_ret(result) {
|
ast::expr_ret(result) {
|
||||||
word(s.s, "ret");
|
word(s.s, "ret");
|
||||||
alt result {
|
alt result {
|
||||||
|
|
|
@ -421,7 +421,7 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
|
||||||
expr_path(p) { visit_path(p, e, v); }
|
expr_path(p) { visit_path(p, e, v); }
|
||||||
expr_fail(eo) { visit_expr_opt(eo, e, v); }
|
expr_fail(eo) { visit_expr_opt(eo, e, v); }
|
||||||
expr_break { }
|
expr_break { }
|
||||||
expr_cont { }
|
expr_again { }
|
||||||
expr_ret(eo) { visit_expr_opt(eo, e, v); }
|
expr_ret(eo) { visit_expr_opt(eo, e, v); }
|
||||||
expr_log(_, lv, x) {
|
expr_log(_, lv, x) {
|
||||||
v.visit_expr(lv, e, v);
|
v.visit_expr(lv, e, v);
|
||||||
|
|
|
@ -176,7 +176,7 @@ impl public_methods for borrowck_ctxt {
|
||||||
ast::expr_new(*) | ast::expr_binary(*) | ast::expr_while(*) |
|
ast::expr_new(*) | ast::expr_binary(*) | ast::expr_while(*) |
|
||||||
ast::expr_block(*) | ast::expr_loop(*) | ast::expr_alt(*) |
|
ast::expr_block(*) | ast::expr_loop(*) | ast::expr_alt(*) |
|
||||||
ast::expr_lit(*) | ast::expr_break | ast::expr_mac(*) |
|
ast::expr_lit(*) | ast::expr_break | ast::expr_mac(*) |
|
||||||
ast::expr_cont | ast::expr_rec(*) {
|
ast::expr_again | ast::expr_rec(*) {
|
||||||
ret self.cat_rvalue(expr, expr_ty);
|
ret self.cat_rvalue(expr, expr_ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
|
||||||
tcx.sess.span_err(e.span, "`break` outside of loop");
|
tcx.sess.span_err(e.span, "`break` outside of loop");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr_cont {
|
expr_again {
|
||||||
if !cx.in_loop {
|
if !cx.in_loop {
|
||||||
tcx.sess.span_err(e.span, "`cont` outside of loop");
|
tcx.sess.span_err(e.span, "`cont` outside of loop");
|
||||||
}
|
}
|
||||||
|
|
|
@ -470,7 +470,7 @@ fn visit_expr(expr: @expr, &&self: @ir_maps, vt: vt<@ir_maps>) {
|
||||||
expr_assert(*) | expr_check(*) | expr_addr_of(*) | expr_copy(*) |
|
expr_assert(*) | expr_check(*) | expr_addr_of(*) | expr_copy(*) |
|
||||||
expr_loop_body(*) | expr_do_body(*) | expr_cast(*) |
|
expr_loop_body(*) | expr_do_body(*) | expr_cast(*) |
|
||||||
expr_unary(*) | expr_fail(*) |
|
expr_unary(*) | expr_fail(*) |
|
||||||
expr_break | expr_cont | expr_lit(_) | expr_ret(*) |
|
expr_break | expr_again | expr_lit(_) | expr_ret(*) |
|
||||||
expr_block(*) | expr_move(*) | expr_assign(*) | expr_swap(*) |
|
expr_block(*) | expr_move(*) | expr_assign(*) | expr_swap(*) |
|
||||||
expr_assign_op(*) | expr_mac(*) {
|
expr_assign_op(*) | expr_mac(*) {
|
||||||
visit::visit_expr(expr, self, vt);
|
visit::visit_expr(expr, self, vt);
|
||||||
|
@ -1009,7 +1009,7 @@ class liveness {
|
||||||
self.break_ln
|
self.break_ln
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_cont {
|
expr_again {
|
||||||
if !self.cont_ln.is_valid() {
|
if !self.cont_ln.is_valid() {
|
||||||
self.tcx.sess.span_bug(
|
self.tcx.sess.span_bug(
|
||||||
expr.span, "cont with invalid cont_ln");
|
expr.span, "cont with invalid cont_ln");
|
||||||
|
@ -1457,7 +1457,7 @@ fn check_expr(expr: @expr, &&self: @liveness, vt: vt<@liveness>) {
|
||||||
expr_assert(*) | expr_check(*) | expr_copy(*) |
|
expr_assert(*) | expr_check(*) | expr_copy(*) |
|
||||||
expr_loop_body(*) | expr_do_body(*) |
|
expr_loop_body(*) | expr_do_body(*) |
|
||||||
expr_cast(*) | expr_unary(*) | expr_fail(*) |
|
expr_cast(*) | expr_unary(*) | expr_fail(*) |
|
||||||
expr_ret(*) | expr_break | expr_cont | expr_lit(_) |
|
expr_ret(*) | expr_break | expr_again | expr_lit(_) |
|
||||||
expr_block(*) | expr_swap(*) | expr_mac(*) | expr_addr_of(*) {
|
expr_block(*) | expr_swap(*) | expr_mac(*) | expr_addr_of(*) {
|
||||||
visit::visit_expr(expr, self, vt);
|
visit::visit_expr(expr, self, vt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3644,7 +3644,7 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
|
||||||
assert dest == ignore;
|
assert dest == ignore;
|
||||||
ret trans_break(bcx);
|
ret trans_break(bcx);
|
||||||
}
|
}
|
||||||
ast::expr_cont {
|
ast::expr_again {
|
||||||
assert dest == ignore;
|
assert dest == ignore;
|
||||||
ret trans_cont(bcx);
|
ret trans_cont(bcx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,7 +242,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
expr_alt(_, _, _) | expr_block(_) | expr_if(_, _, _) |
|
expr_alt(_, _, _) | expr_block(_) | expr_if(_, _, _) |
|
||||||
expr_while(_, _) | expr_fail(_) | expr_break | expr_cont |
|
expr_while(_, _) | expr_fail(_) | expr_break | expr_again |
|
||||||
expr_unary(_, _) | expr_lit(_) | expr_assert(_) | expr_check(_, _) |
|
expr_unary(_, _) | expr_lit(_) | expr_assert(_) | expr_check(_, _) |
|
||||||
expr_if_check(_, _, _) | expr_mac(_) | expr_addr_of(_, _) |
|
expr_if_check(_, _, _) | expr_mac(_) | expr_addr_of(_, _) |
|
||||||
expr_ret(_) | expr_loop(_) |
|
expr_ret(_) | expr_loop(_) |
|
||||||
|
|
|
@ -446,7 +446,7 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
|
||||||
join_then_else(fcx, p, conseq, maybe_alt, e.id, if_check);
|
join_then_else(fcx, p, conseq, maybe_alt, e.id, if_check);
|
||||||
}
|
}
|
||||||
expr_break { clear_pp(expr_pp(fcx.ccx, e)); }
|
expr_break { clear_pp(expr_pp(fcx.ccx, e)); }
|
||||||
expr_cont { clear_pp(expr_pp(fcx.ccx, e)); }
|
expr_again { clear_pp(expr_pp(fcx.ccx, e)); }
|
||||||
expr_mac(_) { fcx.ccx.tcx.sess.bug("unexpanded macro"); }
|
expr_mac(_) { fcx.ccx.tcx.sess.bug("unexpanded macro"); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -498,7 +498,7 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
|
||||||
ret join_then_else(fcx, p, conseq, maybe_alt, e.id, if_check, pres);
|
ret join_then_else(fcx, p, conseq, maybe_alt, e.id, if_check, pres);
|
||||||
}
|
}
|
||||||
expr_break { ret pure_exp(fcx.ccx, e.id, pres); }
|
expr_break { ret pure_exp(fcx.ccx, e.id, pres); }
|
||||||
expr_cont { ret pure_exp(fcx.ccx, e.id, pres); }
|
expr_again { ret pure_exp(fcx.ccx, e.id, pres); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1220,7 +1220,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||||
fcx.write_bot(id);
|
fcx.write_bot(id);
|
||||||
}
|
}
|
||||||
ast::expr_break { fcx.write_bot(id); bot = true; }
|
ast::expr_break { fcx.write_bot(id); bot = true; }
|
||||||
ast::expr_cont { fcx.write_bot(id); bot = true; }
|
ast::expr_again { fcx.write_bot(id); bot = true; }
|
||||||
ast::expr_ret(expr_opt) {
|
ast::expr_ret(expr_opt) {
|
||||||
bot = true;
|
bot = true;
|
||||||
let ret_ty = alt fcx.indirect_ret_ty {
|
let ret_ty = alt fcx.indirect_ret_ty {
|
||||||
|
|
|
@ -57,7 +57,7 @@ fn loop_query(b: ast::blk, p: fn@(ast::expr_) -> bool) -> bool {
|
||||||
|
|
||||||
fn has_nonlocal_exits(b: ast::blk) -> bool {
|
fn has_nonlocal_exits(b: ast::blk) -> bool {
|
||||||
do loop_query(b) |e| { alt e {
|
do loop_query(b) |e| { alt e {
|
||||||
ast::expr_break | ast::expr_cont { true }
|
ast::expr_break | ast::expr_again { true }
|
||||||
_ { false }}}
|
_ { false }}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue