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

@ -439,6 +439,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
start.iter().chain(end.iter()).map(|x| &**x))
}
ast::ExprRange(..) => {
self.tcx.sess.span_bug(expr.span, "non-desugared range");
}
ast::ExprUnary(_, ref e) if self.is_method_call(expr) => {
self.call(expr, pred, &**e, None::<ast::Expr>.iter())
}

View File

@ -465,6 +465,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
assert!(overloaded);
}
ast::ExprRange(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared range");
}
ast::ExprCall(ref callee, ref args) => { // callee(args)
self.walk_callee(expr, &**callee);
self.consume_exprs(args);

View File

@ -486,6 +486,9 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
ast::ExprWhileLet(..) => {
ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprRange(..) => {
ir.tcx.sess.span_bug(expr.span, "non-desugared range");
}
ast::ExprForLoop(ref pat, _, _, _) => {
pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
debug!("adding local variable {} from for loop with bm {}",
@ -1197,6 +1200,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&**e1, succ)
}
ast::ExprRange(..) => {
self.ir.tcx.sess.span_bug(expr.span, "non-desugared range");
}
ast::ExprBox(None, ref e) |
ast::ExprAddrOf(_, ref e) |
ast::ExprCast(ref e, _) |
@ -1498,6 +1505,9 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
ast::ExprWhileLet(..) => {
this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprRange(..) => {
this.ir.tcx.sess.span_bug(expr.span, "non-desugared range");
}
}
}

View File

@ -559,6 +559,9 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
ast::ExprWhileLet(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprRange(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared range");
}
}
}

View File

@ -4273,6 +4273,9 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
ast::ExprWhileLet(..) => {
tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprRange(..) => {
tcx.sess.span_bug(expr.span, "non-desugared range");
}
ast::ExprLit(ref lit) if lit_is_str(&**lit) => {
RvalueDpsExpr

View File

@ -247,6 +247,7 @@ mod svh_visitor {
SawExprAssignOp(ast::BinOp),
SawExprIndex,
SawExprSlice,
SawExprRange,
SawExprPath,
SawExprAddrOf(ast::Mutability),
SawExprRet,
@ -280,6 +281,7 @@ mod svh_visitor {
ExprTupField(_, id) => SawExprTupField(id.node),
ExprIndex(..) => SawExprIndex,
ExprSlice(..) => SawExprSlice,
ExprRange(..) => SawExprRange,
ExprPath(..) => SawExprPath,
ExprAddrOf(m, _) => SawExprAddrOf(m),
ExprBreak(id) => SawExprBreak(id.map(content)),

View File

@ -3494,6 +3494,11 @@ fn populate_scope_map(cx: &CrateContext,
end.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map));
}
ast::ExprRange(..) => {
cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
Found unexpanded range.");
}
ast::ExprVec(ref init_expressions) |
ast::ExprTup(ref init_expressions) => {
for ie in init_expressions.iter() {

View File

@ -4278,6 +4278,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
}
}
}
ast::ExprRange(..) => {
tcx.sess.span_bug(expr.span, "non-desugared range");
}
}
debug!("type of expr({}) {} is...", expr.id,

View File

@ -724,6 +724,7 @@ pub enum Expr_ {
ExprTupField(P<Expr>, Spanned<uint>),
ExprIndex(P<Expr>, P<Expr>),
ExprSlice(P<Expr>, Option<P<Expr>>, Option<P<Expr>>, Mutability),
ExprRange(P<Expr>, Option<P<Expr>>),
/// Variable reference, possibly containing `::` and/or
/// type parameters, e.g. foo::bar::<baz>

View File

@ -1390,6 +1390,10 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) ->
e2.map(|x| folder.fold_expr(x)),
m)
}
ExprRange(e1, e2) => {
ExprRange(folder.fold_expr(e1),
e2.map(|x| folder.fold_expr(x)))
}
ExprPath(pth) => ExprPath(folder.fold_path(pth)),
ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))),
ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))),

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

View File

@ -1759,6 +1759,13 @@ impl<'a> State<'a> {
}
try!(word(&mut self.s, "]"));
}
ast::ExprRange(ref start, ref end) => {
try!(self.print_expr(&**start));
try!(word(&mut self.s, ".."));
if let &Some(ref e) = end {
try!(self.print_expr(&**e));
}
}
ast::ExprPath(ref path) => try!(self.print_path(path, true)),
ast::ExprBreak(opt_ident) => {
try!(word(&mut self.s, "break"));

View File

@ -871,6 +871,10 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
walk_expr_opt(visitor, start);
walk_expr_opt(visitor, end)
}
ExprRange(ref start, ref end) => {
visitor.visit_expr(&**start);
walk_expr_opt(visitor, end)
}
ExprPath(ref path) => {
visitor.visit_path(path, expression.id)
}