about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2014-12-13 18:41:02 +1300
committerNick Cameron <ncameron@mozilla.com>2014-12-24 09:12:45 +1300
commit8a357e1d87971574817a033e5467785402d5fcfb (patch)
tree7572e05c56f1a6f49964a24610c1c6c949b57c17 /src/libsyntax/parse/parser.rs
parent53c5fcb99fc8c62b8723032280fab3dc06fef973 (diff)
downloadrust-8a357e1d87971574817a033e5467785402d5fcfb.tar.gz
rust-8a357e1d87971574817a033e5467785402d5fcfb.zip
Add syntax for ranges
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
-rw-r--r--src/libsyntax/parse/parser.rs40
1 files changed, 32 insertions, 8 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 197970317d2..94b61ba56d2 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -26,7 +26,7 @@ use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
 use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
 use ast::{ExprBreak, ExprCall, ExprCast};
 use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex, ExprSlice};
-use ast::{ExprLit, ExprLoop, ExprMac};
+use ast::{ExprLit, ExprLoop, ExprMac, ExprRange};
 use ast::{ExprMethodCall, ExprParen, ExprPath};
 use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
 use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
@@ -95,7 +95,8 @@ bitflags! {
         const UNRESTRICTED                  = 0b0000,
         const RESTRICTION_STMT_EXPR         = 0b0001,
         const RESTRICTION_NO_BAR_OP         = 0b0010,
-        const RESTRICTION_NO_STRUCT_LITERAL = 0b0100
+        const RESTRICTION_NO_STRUCT_LITERAL = 0b0100,
+        const RESTRICTION_NO_DOTS           = 0b1000,
     }
 }
 
@@ -1547,7 +1548,7 @@ impl<'a> Parser<'a> {
 
             // Parse the `; e` in `[ int; e ]`
             // where `e` is a const expression
-            let t = match self.maybe_parse_fixed_vstore() {
+            let t = match self.maybe_parse_fixed_length_of_vec() {
                 None => TyVec(t),
                 Some(suffix) => TyFixedLengthVec(t, suffix)
             };
@@ -1707,12 +1708,12 @@ impl<'a> Parser<'a> {
         }
     }
 
-    pub fn maybe_parse_fixed_vstore(&mut self) -> Option<P<ast::Expr>> {
+    pub fn maybe_parse_fixed_length_of_vec(&mut self) -> Option<P<ast::Expr>> {
         if self.check(&token::Comma) &&
                 self.look_ahead(1, |t| *t == token::DotDot) {
             self.bump();
             self.bump();
-            Some(self.parse_expr())
+            Some(self.parse_expr_res(RESTRICTION_NO_DOTS))
         } else if self.check(&token::Semi) {
             self.bump();
             Some(self.parse_expr())
@@ -2130,7 +2131,8 @@ impl<'a> Parser<'a> {
         ExprIndex(expr, idx)
     }
 
-    pub fn mk_slice(&mut self, expr: P<Expr>,
+    pub fn mk_slice(&mut self,
+                    expr: P<Expr>,
                     start: Option<P<Expr>>,
                     end: Option<P<Expr>>,
                     mutbl: Mutability)
@@ -2138,6 +2140,13 @@ impl<'a> Parser<'a> {
         ExprSlice(expr, start, end, mutbl)
     }
 
+    pub fn mk_range(&mut self,
+                    start: P<Expr>,
+                    end: Option<P<Expr>>)
+                    -> ast::Expr_ {
+        ExprRange(start, end)
+    }
+
     pub fn mk_field(&mut self, expr: P<Expr>, ident: ast::SpannedIdent) -> ast::Expr_ {
         ExprField(expr, ident)
     }
@@ -2615,7 +2624,7 @@ impl<'a> Parser<'a> {
                     }
                     // e[e] | e[e..] | e[e..e]
                     _ => {
-                        let ix = self.parse_expr();
+                        let ix = self.parse_expr_res(RESTRICTION_NO_DOTS);
                         match self.token {
                             // e[e..] | e[e..e]
                             token::DotDot => {
@@ -2628,7 +2637,7 @@ impl<'a> Parser<'a> {
                                     }
                                     // e[e..e]
                                     _ => {
-                                        let e2 = self.parse_expr();
+                                        let e2 = self.parse_expr_res(RESTRICTION_NO_DOTS);
                                         self.commit_expr_expecting(&*e2,
                                             token::CloseDelim(token::Bracket));
                                         Some(e2)
@@ -2654,6 +2663,21 @@ impl<'a> Parser<'a> {
                 }
               }
 
+              // A range expression, either `expr..expr` or `expr..`.
+              token::DotDot if !self.restrictions.contains(RESTRICTION_NO_DOTS) => {
+                self.bump();
+
+                let opt_end = if self.token.can_begin_expr() {
+                    let end = self.parse_expr_res(RESTRICTION_NO_DOTS);
+                    Some(end)
+                } else {
+                    None
+                };
+
+                let hi = self.span.hi;
+                let range = self.mk_range(e, opt_end);
+                return self.mk_expr(lo, hi, range);
+              }
               _ => return e
             }
         }