about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-09-04 13:36:54 -0700
committerBrian Anderson <banderson@mozilla.com>2012-09-04 13:37:11 -0700
commitd3e75ea37546ad197cc5a1efa522a054a54d78b4 (patch)
tree91df69327b7197e8ed97396deef1a626a726c26e /src/libsyntax/parse
parent443f79922dd9a8542ecda59e03030d54540653c5 (diff)
downloadrust-d3e75ea37546ad197cc5a1efa522a054a54d78b4.tar.gz
rust-d3e75ea37546ad197cc5a1efa522a054a54d78b4.zip
Parse 'loop' and 'again' the same
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs53
1 files changed, 35 insertions, 18 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 60cee541965..5f91d22f5d0 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -883,7 +883,7 @@ struct parser {
             return pexpr(self.parse_sugary_call_expr(~"do", expr_do_body));
         } else if self.eat_keyword(~"while") {
             return pexpr(self.parse_while_expr());
-        } else if self.eat_keyword(~"loop") {
+        } else if self.eat_keyword(~"again") || self.eat_keyword(~"loop") {
             return pexpr(self.parse_loop_expr());
         } else if self.eat_keyword(~"match") {
             return pexpr(self.parse_alt_expr());
@@ -969,13 +969,6 @@ struct parser {
                 ex = expr_break(None);
             }
             hi = self.span.hi;
-        } else if self.eat_keyword(~"again") {
-            if is_ident(self.token) {
-                ex = expr_again(Some(self.parse_ident()));
-            } else {
-                ex = expr_again(None);
-            }
-            hi = self.span.hi;
         } else if self.eat_keyword(~"copy") {
             let e = self.parse_expr();
             ex = expr_copy(e);
@@ -1609,18 +1602,42 @@ struct parser {
     }
 
     fn parse_loop_expr() -> @expr {
-        let opt_ident;
-        if is_ident(self.token) && !self.is_any_keyword(copy self.token) {
-            opt_ident = Some(self.parse_ident());
-            self.expect(token::COLON);
+        // loop headers look like 'loop {' or 'loop unsafe {'
+        let is_loop_header =
+            self.token == token::LBRACE
+            || (is_ident(copy self.token)
+                && self.look_ahead(1) == token::LBRACE);
+        // labeled loop headers look like 'loop foo: {'
+        let is_labeled_loop_header =
+            is_ident(self.token)
+            && !self.is_any_keyword(copy self.token)
+            && self.look_ahead(1) == token::COLON;
+
+        if is_loop_header || is_labeled_loop_header {
+            // This is a loop body
+            let opt_ident;
+            if is_labeled_loop_header {
+                opt_ident = Some(self.parse_ident());
+                self.expect(token::COLON);
+            } else {
+                opt_ident = None;
+            }
+
+            let lo = self.last_span.lo;
+            let body = self.parse_block_no_value();
+            let mut hi = body.span.hi;
+            return self.mk_expr(lo, hi, expr_loop(body, opt_ident));
         } else {
-            opt_ident = None;
+            // This is a 'continue' expression
+            let lo = self.span.lo;
+            let ex = if is_ident(self.token) {
+                expr_again(Some(self.parse_ident()))
+            } else {
+                expr_again(None)
+            };
+            let hi = self.span.hi;
+            return self.mk_expr(lo, hi, ex);
         }
-
-        let lo = self.last_span.lo;
-        let body = self.parse_block_no_value();
-        let mut hi = body.span.hi;
-        return self.mk_expr(lo, hi, expr_loop(body, opt_ident));
     }
 
     // For distingishing between record literals and blocks