about summary refs log tree commit diff
path: root/src/rustc/syntax
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-03-09 16:11:56 -0800
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-03-09 16:40:58 -0800
commit321fd80219e024cabb7ee539e701bc6b4a258751 (patch)
treea0dc81403ffd175f75c704e1a26765339b63907a /src/rustc/syntax
parent4ffcb959744194413ca20223274d2c351ad7686c (diff)
downloadrust-321fd80219e024cabb7ee539e701bc6b4a258751.tar.gz
rust-321fd80219e024cabb7ee539e701bc6b4a258751.zip
Add an infinite loop construct
Add a loop {} construct for infinite loops, and use it in test
cases. See #1906 for details.
Diffstat (limited to 'src/rustc/syntax')
-rw-r--r--src/rustc/syntax/ast.rs4
-rw-r--r--src/rustc/syntax/fold.rs5
-rw-r--r--src/rustc/syntax/parse/parser.rs21
-rw-r--r--src/rustc/syntax/print/pprust.rs5
-rw-r--r--src/rustc/syntax/visit.rs1
5 files changed, 29 insertions, 7 deletions
diff --git a/src/rustc/syntax/ast.rs b/src/rustc/syntax/ast.rs
index b98a1374888..fdd40e6e199 100644
--- a/src/rustc/syntax/ast.rs
+++ b/src/rustc/syntax/ast.rs
@@ -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),
diff --git a/src/rustc/syntax/fold.rs b/src/rustc/syntax/fold.rs
index 6b461fbc7ec..dbdd8cd9b36 100644
--- a/src/rustc/syntax/fold.rs
+++ b/src/rustc/syntax/fold.rs
@@ -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)
           }
diff --git a/src/rustc/syntax/parse/parser.rs b/src/rustc/syntax/parse/parser.rs
index 95c7383cb66..53f75d8f7c3 100644
--- a/src/rustc/syntax/parse/parser.rs
+++ b/src/rustc/syntax/parse/parser.rs
@@ -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
       }
diff --git a/src/rustc/syntax/print/pprust.rs b/src/rustc/syntax/print/pprust.rs
index 2db67a0c97d..ba9c76c748f 100644
--- a/src/rustc/syntax/print/pprust.rs
+++ b/src/rustc/syntax/print/pprust.rs
@@ -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);
diff --git a/src/rustc/syntax/visit.rs b/src/rustc/syntax/visit.rs
index 01aaac48f4a..d9060ea2cfd 100644
--- a/src/rustc/syntax/visit.rs
+++ b/src/rustc/syntax/visit.rs
@@ -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);