about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-04-26 16:19:26 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-04-29 14:30:57 -0700
commit670ab8ac367cd8cfe8b86a1338667e7825d8d68d (patch)
treebabfc59051ffe36a8f4f45c2c8dba2a36dc679d5 /src/libsyntax
parent876483dcf4bdcd0001cc25812060bc04cf367f60 (diff)
downloadrust-670ab8ac367cd8cfe8b86a1338667e7825d8d68d.tar.gz
rust-670ab8ac367cd8cfe8b86a1338667e7825d8d68d.zip
librustc: Change labels to use the lifetime notation `'`.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/asm.rs23
-rw-r--r--src/libsyntax/parse/parser.rs57
-rw-r--r--src/libsyntax/print/pprust.rs17
3 files changed, 68 insertions, 29 deletions
diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs
index 534027bd295..dfebf6f786a 100644
--- a/src/libsyntax/ext/asm.rs
+++ b/src/libsyntax/ext/asm.rs
@@ -52,7 +52,10 @@ pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
     let mut dialect = ast::asm_att;
 
     let mut state = Asm;
-    loop outer: {
+
+    // Not using labeled break to get us through one round of bootstrapping.
+    let mut continue = true;
+    while continue {
         match state {
             Asm => {
                 asm = expr_to_str(cx, p.parse_expr(),
@@ -139,20 +142,30 @@ pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
                 p.bump();
                 match next_state(state) {
                     Some(x) => x,
-                    None    => break outer
+                    None    => {
+                        continue = false;
+                        break
+                    }
                 }
             } else if *p.token == token::MOD_SEP {
                 p.bump();
                 let s = match next_state(state) {
                     Some(x) => x,
-                    None    => break outer
+                    None    => {
+                        continue = false;
+                        break
+                    }
                 };
                 match next_state(s) {
                     Some(x) => x,
-                    None    => break outer
+                    None    => {
+                        continue = false;
+                        break
+                    }
                 }
             } else if *p.token == token::EOF {
-                break outer;
+                continue = false;
+                break;
             } else {
                state
             };
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index ae374808270..50bdfb2f557 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -348,6 +348,20 @@ pub impl Parser {
             self.token_is_keyword(&~"fn", tok)
     }
 
+    fn token_is_lifetime(&self, tok: &token::Token) -> bool {
+        match *tok {
+            token::LIFETIME(*) => true,
+            _ => false,
+        }
+    }
+
+    fn get_lifetime(&self, tok: &token::Token) -> ast::ident {
+        match *tok {
+            token::LIFETIME(ref ident) => copy *ident,
+            _ => self.bug(~"not a lifetime"),
+        }
+    }
+
     // parse a ty_bare_fun type:
     fn parse_ty_bare_fn(&self) -> ty_
     {
@@ -1228,8 +1242,14 @@ pub impl Parser {
                                                expr_do_body);
         } else if self.eat_keyword(&~"while") {
             return self.parse_while_expr();
+        } else if self.token_is_lifetime(&*self.token) {
+            let lifetime = self.get_lifetime(&*self.token);
+            self.bump();
+            self.expect(&token::COLON);
+            self.expect_keyword(&~"loop");
+            return self.parse_loop_expr(Some(lifetime));
         } else if self.eat_keyword(&~"loop") {
-            return self.parse_loop_expr();
+            return self.parse_loop_expr(None);
         } else if self.eat_keyword(&~"match") {
             return self.parse_match_expr();
         } else if self.eat_keyword(&~"unsafe") {
@@ -1290,8 +1310,10 @@ pub impl Parser {
             } else { ex = expr_ret(None); }
         } else if self.eat_keyword(&~"break") {
             // BREAK expression
-            if is_ident(&*self.token) {
-                ex = expr_break(Some(self.parse_ident()));
+            if self.token_is_lifetime(&*self.token) {
+                let lifetime = self.get_lifetime(&*self.token);
+                self.bump();
+                ex = expr_break(Some(lifetime));
             } else {
                 ex = expr_break(None);
             }
@@ -1995,37 +2017,32 @@ pub impl Parser {
         return self.mk_expr(lo, hi, expr_while(cond, body));
     }
 
-    fn parse_loop_expr(&self) -> @expr {
+    fn parse_loop_expr(&self, opt_ident: Option<ast::ident>) -> @expr {
         // loop headers look like 'loop {' or 'loop unsafe {'
         let is_loop_header =
             *self.token == token::LBRACE
             || (is_ident(&*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 {
+        if is_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();
             let hi = body.span.hi;
             return self.mk_expr(lo, hi, expr_loop(body, opt_ident));
         } else {
             // This is a 'continue' expression
+            if opt_ident.is_some() {
+                self.span_err(*self.last_span,
+                              ~"a label may not be used with a `loop` \
+                                expression");
+            }
+
             let lo = self.span.lo;
-            let ex = if is_ident(&*self.token) {
-                expr_again(Some(self.parse_ident()))
+            let ex = if self.token_is_lifetime(&*self.token) {
+                let lifetime = self.get_lifetime(&*self.token);
+                self.bump();
+                expr_again(Some(lifetime))
             } else {
                 expr_again(None)
             };
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 337355304d4..d5645ada929 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1210,12 +1210,13 @@ pub fn print_expr(s: @ps, expr: @ast::expr) {
         print_block(s, blk);
       }
       ast::expr_loop(ref blk, opt_ident) => {
-        head(s, ~"loop");
-        space(s.s);
         for opt_ident.each |ident| {
+            word(s.s, ~"'");
             print_ident(s, *ident);
             word_space(s, ~":");
         }
+        head(s, ~"loop");
+        space(s.s);
         print_block(s, blk);
       }
       ast::expr_match(expr, ref arms) => {
@@ -1363,12 +1364,20 @@ pub fn print_expr(s: @ps, expr: @ast::expr) {
       ast::expr_break(opt_ident) => {
         word(s.s, ~"break");
         space(s.s);
-        for opt_ident.each |ident| { print_ident(s, *ident); space(s.s) }
+        for opt_ident.each |ident| {
+            word(s.s, ~"'");
+            print_ident(s, *ident);
+            space(s.s);
+        }
       }
       ast::expr_again(opt_ident) => {
         word(s.s, ~"loop");
         space(s.s);
-        for opt_ident.each |ident| { print_ident(s, *ident); space(s.s) }
+        for opt_ident.each |ident| {
+            word(s.s, ~"'");
+            print_ident(s, *ident);
+            space(s.s)
+        }
       }
       ast::expr_ret(result) => {
         word(s.s, ~"return");