diff options
| author | Nick Cameron <ncameron@mozilla.com> | 2014-12-13 18:41:02 +1300 |
|---|---|---|
| committer | Nick Cameron <ncameron@mozilla.com> | 2014-12-24 09:12:45 +1300 |
| commit | 8a357e1d87971574817a033e5467785402d5fcfb (patch) | |
| tree | 7572e05c56f1a6f49964a24610c1c6c949b57c17 /src/libsyntax/parse/parser.rs | |
| parent | 53c5fcb99fc8c62b8723032280fab3dc06fef973 (diff) | |
| download | rust-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.rs | 40 |
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 } } |
