1
Fork 0

Add syntax for ranges

This commit is contained in:
Nick Cameron 2014-12-13 18:41:02 +13:00
parent 53c5fcb99f
commit 8a357e1d87
13 changed files with 83 additions and 8 deletions

View file

@ -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
}
}