1
Fork 0

For #2229, recognize 'again' in place of 'cont', final change pending snapshot.

This commit is contained in:
Graydon Hoare 2012-07-06 15:46:31 -07:00
parent e20f63d095
commit ceac155211
19 changed files with 34 additions and 34 deletions

View file

@ -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

View file

@ -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;

View file

@ -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"

View file

@ -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"))))))),

View file

@ -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),

View file

@ -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)) }

View file

@ -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();

View file

@ -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",

View file

@ -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 {

View file

@ -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);

View file

@ -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);
} }
} }

View file

@ -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");
} }

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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(_) |

View file

@ -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"); }
} }
} }

View file

@ -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); }
} }
} }

View file

@ -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 {

View file

@ -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 }}}
} }