Convert restriction enum into bitflags
This makes having multiple restrictions at once cleaner. Also drop NO_DOUBLEBAR restriction since it is never used.
This commit is contained in:
parent
63eaba24d6
commit
99293b16e4
1 changed files with 28 additions and 32 deletions
|
@ -88,14 +88,13 @@ use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
bitflags! {
|
||||||
#[deriving(PartialEq)]
|
flags Restrictions: u8 {
|
||||||
pub enum restriction {
|
static Unrestricted = 0b0000,
|
||||||
UNRESTRICTED,
|
static RestrictionStmtExpr = 0b0001,
|
||||||
RESTRICT_STMT_EXPR,
|
static RestrictionNoBarOp = 0b0010,
|
||||||
RESTRICT_NO_BAR_OP,
|
static RestrictionNoStructLiteral = 0b0100
|
||||||
RESTRICT_NO_BAR_OR_DOUBLEBAR_OP,
|
}
|
||||||
RESTRICT_NO_STRUCT_LITERAL,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
|
type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
|
||||||
|
@ -314,7 +313,7 @@ pub struct Parser<'a> {
|
||||||
pub buffer_start: int,
|
pub buffer_start: int,
|
||||||
pub buffer_end: int,
|
pub buffer_end: int,
|
||||||
pub tokens_consumed: uint,
|
pub tokens_consumed: uint,
|
||||||
pub restriction: restriction,
|
pub restrictions: Restrictions,
|
||||||
pub quote_depth: uint, // not (yet) related to the quasiquoter
|
pub quote_depth: uint, // not (yet) related to the quasiquoter
|
||||||
pub reader: Box<Reader+'a>,
|
pub reader: Box<Reader+'a>,
|
||||||
pub interner: Rc<token::IdentInterner>,
|
pub interner: Rc<token::IdentInterner>,
|
||||||
|
@ -383,7 +382,7 @@ impl<'a> Parser<'a> {
|
||||||
buffer_start: 0,
|
buffer_start: 0,
|
||||||
buffer_end: 0,
|
buffer_end: 0,
|
||||||
tokens_consumed: 0,
|
tokens_consumed: 0,
|
||||||
restriction: UNRESTRICTED,
|
restrictions: Unrestricted,
|
||||||
quote_depth: 0,
|
quote_depth: 0,
|
||||||
obsolete_set: HashSet::new(),
|
obsolete_set: HashSet::new(),
|
||||||
mod_path_stack: Vec::new(),
|
mod_path_stack: Vec::new(),
|
||||||
|
@ -2189,7 +2188,7 @@ impl<'a> Parser<'a> {
|
||||||
if self.token == token::LBRACE {
|
if self.token == token::LBRACE {
|
||||||
// This is a struct literal, unless we're prohibited
|
// This is a struct literal, unless we're prohibited
|
||||||
// from parsing struct literals here.
|
// from parsing struct literals here.
|
||||||
if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
|
if !self.restrictions.contains(RestrictionNoStructLiteral) {
|
||||||
// It's a struct literal.
|
// It's a struct literal.
|
||||||
self.bump();
|
self.bump();
|
||||||
let mut fields = Vec::new();
|
let mut fields = Vec::new();
|
||||||
|
@ -2651,12 +2650,9 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
// Prevent dynamic borrow errors later on by limiting the
|
// Prevent dynamic borrow errors later on by limiting the
|
||||||
// scope of the borrows.
|
// scope of the borrows.
|
||||||
match (&self.token, &self.restriction) {
|
if self.token == token::BINOP(token::OR) &&
|
||||||
(&token::BINOP(token::OR), &RESTRICT_NO_BAR_OP) => return lhs,
|
self.restrictions.contains(RestrictionNoBarOp) {
|
||||||
(&token::BINOP(token::OR),
|
return lhs;
|
||||||
&RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs,
|
|
||||||
(&token::OROR, &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs,
|
|
||||||
_ => { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let cur_opt = token_to_binop(&self.token);
|
let cur_opt = token_to_binop(&self.token);
|
||||||
|
@ -2730,7 +2726,7 @@ impl<'a> Parser<'a> {
|
||||||
/// Parse an 'if' expression ('if' token already eaten)
|
/// Parse an 'if' expression ('if' token already eaten)
|
||||||
pub fn parse_if_expr(&mut self) -> P<Expr> {
|
pub fn parse_if_expr(&mut self) -> P<Expr> {
|
||||||
let lo = self.last_span.lo;
|
let lo = self.last_span.lo;
|
||||||
let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
|
let cond = self.parse_expr_res(RestrictionNoStructLiteral);
|
||||||
let thn = self.parse_block();
|
let thn = self.parse_block();
|
||||||
let mut els: Option<P<Expr>> = None;
|
let mut els: Option<P<Expr>> = None;
|
||||||
let mut hi = thn.span.hi;
|
let mut hi = thn.span.hi;
|
||||||
|
@ -2791,7 +2787,7 @@ impl<'a> Parser<'a> {
|
||||||
let lo = self.last_span.lo;
|
let lo = self.last_span.lo;
|
||||||
let pat = self.parse_pat();
|
let pat = self.parse_pat();
|
||||||
self.expect_keyword(keywords::In);
|
self.expect_keyword(keywords::In);
|
||||||
let expr = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
|
let expr = self.parse_expr_res(RestrictionNoStructLiteral);
|
||||||
let loop_block = self.parse_block();
|
let loop_block = self.parse_block();
|
||||||
let hi = self.span.hi;
|
let hi = self.span.hi;
|
||||||
|
|
||||||
|
@ -2800,7 +2796,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> {
|
pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> {
|
||||||
let lo = self.last_span.lo;
|
let lo = self.last_span.lo;
|
||||||
let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
|
let cond = self.parse_expr_res(RestrictionNoStructLiteral);
|
||||||
let body = self.parse_block();
|
let body = self.parse_block();
|
||||||
let hi = body.span.hi;
|
let hi = body.span.hi;
|
||||||
return self.mk_expr(lo, hi, ExprWhile(cond, body, opt_ident));
|
return self.mk_expr(lo, hi, ExprWhile(cond, body, opt_ident));
|
||||||
|
@ -2815,7 +2811,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
fn parse_match_expr(&mut self) -> P<Expr> {
|
fn parse_match_expr(&mut self) -> P<Expr> {
|
||||||
let lo = self.last_span.lo;
|
let lo = self.last_span.lo;
|
||||||
let discriminant = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
|
let discriminant = self.parse_expr_res(RestrictionNoStructLiteral);
|
||||||
self.commit_expr_expecting(&*discriminant, token::LBRACE);
|
self.commit_expr_expecting(&*discriminant, token::LBRACE);
|
||||||
let mut arms: Vec<Arm> = Vec::new();
|
let mut arms: Vec<Arm> = Vec::new();
|
||||||
while self.token != token::RBRACE {
|
while self.token != token::RBRACE {
|
||||||
|
@ -2834,7 +2830,7 @@ impl<'a> Parser<'a> {
|
||||||
guard = Some(self.parse_expr());
|
guard = Some(self.parse_expr());
|
||||||
}
|
}
|
||||||
self.expect(&token::FAT_ARROW);
|
self.expect(&token::FAT_ARROW);
|
||||||
let expr = self.parse_expr_res(RESTRICT_STMT_EXPR);
|
let expr = self.parse_expr_res(RestrictionStmtExpr);
|
||||||
|
|
||||||
let require_comma =
|
let require_comma =
|
||||||
!classify::expr_is_simple_block(&*expr)
|
!classify::expr_is_simple_block(&*expr)
|
||||||
|
@ -2856,15 +2852,15 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Parse an expression
|
/// Parse an expression
|
||||||
pub fn parse_expr(&mut self) -> P<Expr> {
|
pub fn parse_expr(&mut self) -> P<Expr> {
|
||||||
return self.parse_expr_res(UNRESTRICTED);
|
return self.parse_expr_res(Unrestricted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse an expression, subject to the given restriction
|
/// Parse an expression, subject to the given restrictions
|
||||||
pub fn parse_expr_res(&mut self, r: restriction) -> P<Expr> {
|
pub fn parse_expr_res(&mut self, r: Restrictions) -> P<Expr> {
|
||||||
let old = self.restriction;
|
let old = self.restrictions;
|
||||||
self.restriction = r;
|
self.restrictions = r;
|
||||||
let e = self.parse_assign_expr();
|
let e = self.parse_assign_expr();
|
||||||
self.restriction = old;
|
self.restrictions = old;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3153,9 +3149,9 @@ impl<'a> Parser<'a> {
|
||||||
self.look_ahead(2, |t| {
|
self.look_ahead(2, |t| {
|
||||||
*t != token::COMMA && *t != token::RBRACKET
|
*t != token::COMMA && *t != token::RBRACKET
|
||||||
}) {
|
}) {
|
||||||
let start = self.parse_expr_res(RESTRICT_NO_BAR_OP);
|
let start = self.parse_expr_res(RestrictionNoBarOp);
|
||||||
self.eat(&token::DOTDOT);
|
self.eat(&token::DOTDOT);
|
||||||
let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
|
let end = self.parse_expr_res(RestrictionNoBarOp);
|
||||||
pat = PatRange(start, end);
|
pat = PatRange(start, end);
|
||||||
} else if is_plain_ident(&self.token) && !can_be_enum_or_struct {
|
} else if is_plain_ident(&self.token) && !can_be_enum_or_struct {
|
||||||
let id = self.parse_ident();
|
let id = self.parse_ident();
|
||||||
|
@ -3441,7 +3437,7 @@ impl<'a> Parser<'a> {
|
||||||
check_expected_item(self, found_attrs);
|
check_expected_item(self, found_attrs);
|
||||||
|
|
||||||
// Remainder are line-expr stmts.
|
// Remainder are line-expr stmts.
|
||||||
let e = self.parse_expr_res(RESTRICT_STMT_EXPR);
|
let e = self.parse_expr_res(RestrictionStmtExpr);
|
||||||
P(spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID)))
|
P(spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3450,7 +3446,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Is this expression a successfully-parsed statement?
|
/// Is this expression a successfully-parsed statement?
|
||||||
fn expr_is_complete(&mut self, e: &Expr) -> bool {
|
fn expr_is_complete(&mut self, e: &Expr) -> bool {
|
||||||
self.restriction == RESTRICT_STMT_EXPR &&
|
self.restrictions.contains(RestrictionStmtExpr) &&
|
||||||
!classify::expr_requires_semi_to_be_stmt(e)
|
!classify::expr_requires_semi_to_be_stmt(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue