Add an infinite loop construct
Add a loop {} construct for infinite loops, and use it in test
cases. See #1906 for details.
This commit is contained in:
parent
4ffcb95974
commit
321fd80219
33 changed files with 208 additions and 122 deletions
|
|
@ -229,6 +229,10 @@ enum expr_ {
|
|||
expr_while(@expr, blk),
|
||||
expr_for(@local, @expr, blk),
|
||||
expr_do_while(blk, @expr),
|
||||
/* Conditionless loop (can be exited with break, cont, ret, or fail)
|
||||
Same semantics as while(true) { body }, but typestate knows that the
|
||||
(implicit) condition is always true. */
|
||||
expr_loop(blk),
|
||||
expr_alt(@expr, [arm], alt_mode),
|
||||
expr_fn(proto, fn_decl, blk, @capture_clause),
|
||||
expr_fn_block(fn_decl, blk),
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
|
|||
let fold_mac = bind fold_mac_(_, fld);
|
||||
|
||||
ret alt e {
|
||||
expr_vec(exprs, mutt) {
|
||||
expr_vec(exprs, mutt) {
|
||||
expr_vec(fld.map_exprs(fld.fold_expr, exprs), mutt)
|
||||
}
|
||||
expr_rec(fields, maybe_expr) {
|
||||
|
|
@ -417,6 +417,9 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
|
|||
expr_do_while(blk, expr) {
|
||||
expr_do_while(fld.fold_block(blk), fld.fold_expr(expr))
|
||||
}
|
||||
expr_loop(body) {
|
||||
expr_loop(fld.fold_block(body))
|
||||
}
|
||||
expr_alt(expr, arms, mode) {
|
||||
expr_alt(fld.fold_expr(expr), vec::map(arms, fld.fold_arm), mode)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,11 +146,11 @@ fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader,
|
|||
fn bad_expr_word_table() -> hashmap<str, ()> {
|
||||
let words = new_str_hash();
|
||||
for word in ["alt", "assert", "be", "break", "check", "claim",
|
||||
"class", "const", "cont", "copy", "do", "else", "enum",
|
||||
"export", "fail", "fn", "for", "if", "iface", "impl",
|
||||
"import", "let", "log", "mod", "mutable", "native", "pure",
|
||||
"resource", "ret", "trait", "type", "unchecked", "unsafe",
|
||||
"while", "crust", "mut"] {
|
||||
"class", "const", "cont", "copy", "crust", "do", "else",
|
||||
"enum", "export", "fail", "fn", "for", "if", "iface",
|
||||
"impl", "import", "let", "log", "loop", "mod", "mut",
|
||||
"mutable", "native", "pure", "resource", "ret", "trait",
|
||||
"type", "unchecked", "unsafe", "while"] {
|
||||
words.insert(word, ());
|
||||
}
|
||||
words
|
||||
|
|
@ -839,6 +839,8 @@ fn parse_bottom_expr(p: parser) -> pexpr {
|
|||
ret pexpr(parse_while_expr(p));
|
||||
} else if eat_word(p, "do") {
|
||||
ret pexpr(parse_do_while_expr(p));
|
||||
} else if eat_word(p, "loop") {
|
||||
ret pexpr(parse_loop_expr(p));
|
||||
} else if eat_word(p, "alt") {
|
||||
ret pexpr(parse_alt_expr(p));
|
||||
} else if eat_word(p, "fn") {
|
||||
|
|
@ -1399,6 +1401,13 @@ fn parse_do_while_expr(p: parser) -> @ast::expr {
|
|||
ret mk_expr(p, lo, hi, ast::expr_do_while(body, cond));
|
||||
}
|
||||
|
||||
fn parse_loop_expr(p: parser) -> @ast::expr {
|
||||
let lo = p.last_span.lo;
|
||||
let body = parse_block_no_value(p);
|
||||
let hi = body.span.hi;
|
||||
ret mk_expr(p, lo, hi, ast::expr_loop(body));
|
||||
}
|
||||
|
||||
fn parse_alt_expr(p: parser) -> @ast::expr {
|
||||
let lo = p.last_span.lo;
|
||||
let mode = if eat_word(p, "check") { ast::alt_check }
|
||||
|
|
@ -1691,7 +1700,7 @@ fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool {
|
|||
ast::expr_if(_, _, _) | ast::expr_if_check(_, _, _)
|
||||
| ast::expr_alt(_, _, _) | ast::expr_block(_)
|
||||
| ast::expr_do_while(_, _) | ast::expr_while(_, _)
|
||||
| ast::expr_for(_, _, _)
|
||||
| ast::expr_loop(_) | ast::expr_for(_, _, _)
|
||||
| ast::expr_call(_, _, true) {
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -913,6 +913,11 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
|
|||
space(s.s);
|
||||
print_block(s, blk);
|
||||
}
|
||||
ast::expr_loop(blk) {
|
||||
head(s, "loop");
|
||||
space(s.s);
|
||||
print_block(s, blk);
|
||||
}
|
||||
ast::expr_for(decl, expr, blk) {
|
||||
head(s, "for");
|
||||
print_for_decl(s, decl, expr);
|
||||
|
|
|
|||
|
|
@ -343,6 +343,7 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
|
|||
visit_expr_opt(eo, e, v);
|
||||
}
|
||||
expr_while(x, b) { v.visit_expr(x, e, v); v.visit_block(b, e, v); }
|
||||
expr_loop(b) { v.visit_block(b, e, v); }
|
||||
expr_for(dcl, x, b) {
|
||||
v.visit_local(dcl, e, v);
|
||||
v.visit_expr(x, e, v);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue