change if/else to match
This commit is contained in:
parent
f3fa836939
commit
9f94f823b0
1 changed files with 206 additions and 188 deletions
|
@ -1877,211 +1877,229 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
let ex: Expr_;
|
let ex: Expr_;
|
||||||
|
|
||||||
if self.token == token::LPAREN {
|
match self.token {
|
||||||
self.bump();
|
token::LPAREN => {
|
||||||
// (e) is parenthesized e
|
self.bump();
|
||||||
// (e,) is a tuple with only one field, e
|
// (e) is parenthesized e
|
||||||
let mut trailing_comma = false;
|
// (e,) is a tuple with only one field, e
|
||||||
if self.token == token::RPAREN {
|
let mut trailing_comma = false;
|
||||||
|
if self.token == token::RPAREN {
|
||||||
|
hi = self.span.hi;
|
||||||
|
self.bump();
|
||||||
|
let lit = box(GC) spanned(lo, hi, LitNil);
|
||||||
|
return self.mk_expr(lo, hi, ExprLit(lit));
|
||||||
|
}
|
||||||
|
let mut es = vec!(self.parse_expr());
|
||||||
|
self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
|
||||||
|
while self.token == token::COMMA {
|
||||||
|
self.bump();
|
||||||
|
if self.token != token::RPAREN {
|
||||||
|
es.push(self.parse_expr());
|
||||||
|
self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
trailing_comma = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
hi = self.span.hi;
|
hi = self.span.hi;
|
||||||
self.bump();
|
self.commit_expr_expecting(*es.last().unwrap(), token::RPAREN);
|
||||||
let lit = box(GC) spanned(lo, hi, LitNil);
|
|
||||||
return self.mk_expr(lo, hi, ExprLit(lit));
|
|
||||||
}
|
|
||||||
let mut es = vec!(self.parse_expr());
|
|
||||||
self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
|
|
||||||
while self.token == token::COMMA {
|
|
||||||
self.bump();
|
|
||||||
if self.token != token::RPAREN {
|
|
||||||
es.push(self.parse_expr());
|
|
||||||
self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
trailing_comma = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hi = self.span.hi;
|
|
||||||
self.commit_expr_expecting(*es.last().unwrap(), token::RPAREN);
|
|
||||||
|
|
||||||
return if es.len() == 1 && !trailing_comma {
|
return if es.len() == 1 && !trailing_comma {
|
||||||
self.mk_expr(lo, hi, ExprParen(*es.get(0)))
|
self.mk_expr(lo, hi, ExprParen(*es.get(0)))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.mk_expr(lo, hi, ExprTup(es))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
token::LBRACE => {
|
||||||
|
self.bump();
|
||||||
|
let blk = self.parse_block_tail(lo, DefaultBlock);
|
||||||
|
return self.mk_expr(blk.span.lo, blk.span.hi,
|
||||||
|
ExprBlock(blk));
|
||||||
|
},
|
||||||
|
_ if token::is_bar(&self.token) => {
|
||||||
|
return self.parse_lambda_expr();
|
||||||
|
},
|
||||||
|
_ if self.eat_keyword(keywords::Proc) => {
|
||||||
|
let decl = self.parse_proc_decl();
|
||||||
|
let body = self.parse_expr();
|
||||||
|
let fakeblock = P(ast::Block {
|
||||||
|
view_items: Vec::new(),
|
||||||
|
stmts: Vec::new(),
|
||||||
|
expr: Some(body),
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
rules: DefaultBlock,
|
||||||
|
span: body.span,
|
||||||
|
});
|
||||||
|
return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
|
||||||
|
},
|
||||||
|
_ if self.eat_keyword(keywords::Self) => {
|
||||||
|
let path = ast_util::ident_to_path(mk_sp(lo, hi), special_idents::self_);
|
||||||
|
ex = ExprPath(path);
|
||||||
|
hi = self.last_span.hi;
|
||||||
}
|
}
|
||||||
else {
|
_ if self.eat_keyword(keywords::If) => {
|
||||||
self.mk_expr(lo, hi, ExprTup(es))
|
return self.parse_if_expr();
|
||||||
}
|
},
|
||||||
} else if self.token == token::LBRACE {
|
_ if self.eat_keyword(keywords::For) => {
|
||||||
self.bump();
|
return self.parse_for_expr(None);
|
||||||
let blk = self.parse_block_tail(lo, DefaultBlock);
|
},
|
||||||
return self.mk_expr(blk.span.lo, blk.span.hi,
|
_ if self.eat_keyword(keywords::While) => {
|
||||||
ExprBlock(blk));
|
return self.parse_while_expr();
|
||||||
} else if token::is_bar(&self.token) {
|
},
|
||||||
return self.parse_lambda_expr();
|
_ if Parser::token_is_lifetime(&self.token) => {
|
||||||
} else if self.eat_keyword(keywords::Proc) {
|
|
||||||
let decl = self.parse_proc_decl();
|
|
||||||
let body = self.parse_expr();
|
|
||||||
let fakeblock = P(ast::Block {
|
|
||||||
view_items: Vec::new(),
|
|
||||||
stmts: Vec::new(),
|
|
||||||
expr: Some(body),
|
|
||||||
id: ast::DUMMY_NODE_ID,
|
|
||||||
rules: DefaultBlock,
|
|
||||||
span: body.span,
|
|
||||||
});
|
|
||||||
|
|
||||||
return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
|
|
||||||
} else if self.eat_keyword(keywords::Self) {
|
|
||||||
let path = ast_util::ident_to_path(mk_sp(lo, hi), special_idents::self_);
|
|
||||||
ex = ExprPath(path);
|
|
||||||
hi = self.last_span.hi;
|
|
||||||
} else if self.eat_keyword(keywords::If) {
|
|
||||||
return self.parse_if_expr();
|
|
||||||
} else if self.eat_keyword(keywords::For) {
|
|
||||||
return self.parse_for_expr(None);
|
|
||||||
} else if self.eat_keyword(keywords::While) {
|
|
||||||
return self.parse_while_expr();
|
|
||||||
} else if Parser::token_is_lifetime(&self.token) {
|
|
||||||
let lifetime = self.get_lifetime();
|
|
||||||
self.bump();
|
|
||||||
self.expect(&token::COLON);
|
|
||||||
if self.eat_keyword(keywords::For) {
|
|
||||||
return self.parse_for_expr(Some(lifetime))
|
|
||||||
} else if self.eat_keyword(keywords::Loop) {
|
|
||||||
return self.parse_loop_expr(Some(lifetime))
|
|
||||||
} else {
|
|
||||||
self.fatal("expected `for` or `loop` after a label")
|
|
||||||
}
|
|
||||||
} else if self.eat_keyword(keywords::Loop) {
|
|
||||||
return self.parse_loop_expr(None);
|
|
||||||
} else if self.eat_keyword(keywords::Continue) {
|
|
||||||
let lo = self.span.lo;
|
|
||||||
let ex = if Parser::token_is_lifetime(&self.token) {
|
|
||||||
let lifetime = self.get_lifetime();
|
let lifetime = self.get_lifetime();
|
||||||
self.bump();
|
self.bump();
|
||||||
ExprAgain(Some(lifetime))
|
self.expect(&token::COLON);
|
||||||
} else {
|
if self.eat_keyword(keywords::For) {
|
||||||
ExprAgain(None)
|
return self.parse_for_expr(Some(lifetime))
|
||||||
};
|
} else if self.eat_keyword(keywords::Loop) {
|
||||||
let hi = self.span.hi;
|
return self.parse_loop_expr(Some(lifetime))
|
||||||
return self.mk_expr(lo, hi, ex);
|
|
||||||
} else if self.eat_keyword(keywords::Match) {
|
|
||||||
return self.parse_match_expr();
|
|
||||||
} else if self.eat_keyword(keywords::Unsafe) {
|
|
||||||
return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided));
|
|
||||||
} else if self.token == token::LBRACKET {
|
|
||||||
self.bump();
|
|
||||||
|
|
||||||
if self.token == token::RBRACKET {
|
|
||||||
// Empty vector.
|
|
||||||
self.bump();
|
|
||||||
ex = ExprVec(Vec::new());
|
|
||||||
} else {
|
|
||||||
// Nonempty vector.
|
|
||||||
let first_expr = self.parse_expr();
|
|
||||||
if self.token == token::COMMA &&
|
|
||||||
self.look_ahead(1, |t| *t == token::DOTDOT) {
|
|
||||||
// Repeating vector syntax: [ 0, ..512 ]
|
|
||||||
self.bump();
|
|
||||||
self.bump();
|
|
||||||
let count = self.parse_expr();
|
|
||||||
self.expect(&token::RBRACKET);
|
|
||||||
ex = ExprRepeat(first_expr, count);
|
|
||||||
} else if self.token == token::COMMA {
|
|
||||||
// Vector with two or more elements.
|
|
||||||
self.bump();
|
|
||||||
let remaining_exprs = self.parse_seq_to_end(
|
|
||||||
&token::RBRACKET,
|
|
||||||
seq_sep_trailing_allowed(token::COMMA),
|
|
||||||
|p| p.parse_expr()
|
|
||||||
);
|
|
||||||
let mut exprs = vec!(first_expr);
|
|
||||||
exprs.push_all_move(remaining_exprs);
|
|
||||||
ex = ExprVec(exprs);
|
|
||||||
} else {
|
} else {
|
||||||
// Vector with one element.
|
self.fatal("expected `for` or `loop` after a label")
|
||||||
self.expect(&token::RBRACKET);
|
|
||||||
ex = ExprVec(vec!(first_expr));
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
hi = self.last_span.hi;
|
_ if self.eat_keyword(keywords::Loop) => {
|
||||||
} else if self.eat_keyword(keywords::Return) {
|
return self.parse_loop_expr(None);
|
||||||
// RETURN expression
|
},
|
||||||
if can_begin_expr(&self.token) {
|
_ if self.eat_keyword(keywords::Continue) => {
|
||||||
let e = self.parse_expr();
|
let lo = self.span.lo;
|
||||||
hi = e.span.hi;
|
let ex = if Parser::token_is_lifetime(&self.token) {
|
||||||
ex = ExprRet(Some(e));
|
let lifetime = self.get_lifetime();
|
||||||
} else { ex = ExprRet(None); }
|
|
||||||
} else if self.eat_keyword(keywords::Break) {
|
|
||||||
// BREAK expression
|
|
||||||
if Parser::token_is_lifetime(&self.token) {
|
|
||||||
let lifetime = self.get_lifetime();
|
|
||||||
self.bump();
|
|
||||||
ex = ExprBreak(Some(lifetime));
|
|
||||||
} else {
|
|
||||||
ex = ExprBreak(None);
|
|
||||||
}
|
|
||||||
hi = self.span.hi;
|
|
||||||
} else if self.token == token::MOD_SEP ||
|
|
||||||
is_ident(&self.token) && !self.is_keyword(keywords::True) &&
|
|
||||||
!self.is_keyword(keywords::False) {
|
|
||||||
let pth = self.parse_path(LifetimeAndTypesWithColons).path;
|
|
||||||
|
|
||||||
// `!`, as an operator, is prefix, so we know this isn't that
|
|
||||||
if self.token == token::NOT {
|
|
||||||
// MACRO INVOCATION expression
|
|
||||||
self.bump();
|
|
||||||
|
|
||||||
let ket = token::close_delimiter_for(&self.token)
|
|
||||||
.unwrap_or_else(|| self.fatal("expected open delimiter"));
|
|
||||||
self.bump();
|
|
||||||
|
|
||||||
let tts = self.parse_seq_to_end(&ket,
|
|
||||||
seq_sep_none(),
|
|
||||||
|p| p.parse_token_tree());
|
|
||||||
let hi = self.span.hi;
|
|
||||||
|
|
||||||
return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT));
|
|
||||||
} else if self.token == token::LBRACE {
|
|
||||||
// This is a struct literal, unless we're prohibited from
|
|
||||||
// parsing struct literals here.
|
|
||||||
if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
|
|
||||||
// It's a struct literal.
|
|
||||||
self.bump();
|
self.bump();
|
||||||
let mut fields = Vec::new();
|
ExprAgain(Some(lifetime))
|
||||||
let mut base = None;
|
} else {
|
||||||
|
ExprAgain(None)
|
||||||
|
};
|
||||||
|
let hi = self.span.hi;
|
||||||
|
return self.mk_expr(lo, hi, ex);
|
||||||
|
},
|
||||||
|
_ if self.eat_keyword(keywords::Match) => {
|
||||||
|
return self.parse_match_expr();
|
||||||
|
},
|
||||||
|
_ if self.eat_keyword(keywords::Unsafe) => {
|
||||||
|
return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided));
|
||||||
|
},
|
||||||
|
token::LBRACKET => {
|
||||||
|
self.bump();
|
||||||
|
|
||||||
while self.token != token::RBRACE {
|
if self.token == token::RBRACKET {
|
||||||
if self.eat(&token::DOTDOT) {
|
// Empty vector.
|
||||||
base = Some(self.parse_expr());
|
self.bump();
|
||||||
break;
|
ex = ExprVec(Vec::new());
|
||||||
|
} else {
|
||||||
|
// Nonempty vector.
|
||||||
|
let first_expr = self.parse_expr();
|
||||||
|
if self.token == token::COMMA &&
|
||||||
|
self.look_ahead(1, |t| *t == token::DOTDOT) {
|
||||||
|
// Repeating vector syntax: [ 0, ..512 ]
|
||||||
|
self.bump();
|
||||||
|
self.bump();
|
||||||
|
let count = self.parse_expr();
|
||||||
|
self.expect(&token::RBRACKET);
|
||||||
|
ex = ExprRepeat(first_expr, count);
|
||||||
|
} else if self.token == token::COMMA {
|
||||||
|
// Vector with two or more elements.
|
||||||
|
self.bump();
|
||||||
|
let remaining_exprs = self.parse_seq_to_end(
|
||||||
|
&token::RBRACKET,
|
||||||
|
seq_sep_trailing_allowed(token::COMMA),
|
||||||
|
|p| p.parse_expr()
|
||||||
|
);
|
||||||
|
let mut exprs = vec!(first_expr);
|
||||||
|
exprs.push_all_move(remaining_exprs);
|
||||||
|
ex = ExprVec(exprs);
|
||||||
|
} else {
|
||||||
|
// Vector with one element.
|
||||||
|
self.expect(&token::RBRACKET);
|
||||||
|
ex = ExprVec(vec!(first_expr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hi = self.last_span.hi;
|
||||||
|
},
|
||||||
|
_ if self.eat_keyword(keywords::Return) => {
|
||||||
|
// RETURN expression
|
||||||
|
if can_begin_expr(&self.token) {
|
||||||
|
let e = self.parse_expr();
|
||||||
|
hi = e.span.hi;
|
||||||
|
ex = ExprRet(Some(e));
|
||||||
|
} else { ex = ExprRet(None); }
|
||||||
|
},
|
||||||
|
_ if self.eat_keyword(keywords::Break) => {
|
||||||
|
// BREAK expression
|
||||||
|
if Parser::token_is_lifetime(&self.token) {
|
||||||
|
let lifetime = self.get_lifetime();
|
||||||
|
self.bump();
|
||||||
|
ex = ExprBreak(Some(lifetime));
|
||||||
|
} else {
|
||||||
|
ex = ExprBreak(None);
|
||||||
|
}
|
||||||
|
hi = self.span.hi;
|
||||||
|
},
|
||||||
|
_ if self.token == token::MOD_SEP ||
|
||||||
|
is_ident(&self.token) && !self.is_keyword(keywords::True) &&
|
||||||
|
!self.is_keyword(keywords::False) => {
|
||||||
|
let pth = self.parse_path(LifetimeAndTypesWithColons).path;
|
||||||
|
|
||||||
|
// `!`, as an operator, is prefix, so we know this isn't that
|
||||||
|
if self.token == token::NOT {
|
||||||
|
// MACRO INVOCATION expression
|
||||||
|
self.bump();
|
||||||
|
|
||||||
|
let ket = token::close_delimiter_for(&self.token)
|
||||||
|
.unwrap_or_else(|| self.fatal("expected open delimiter"));
|
||||||
|
self.bump();
|
||||||
|
|
||||||
|
let tts = self.parse_seq_to_end(&ket,
|
||||||
|
seq_sep_none(),
|
||||||
|
|p| p.parse_token_tree());
|
||||||
|
let hi = self.span.hi;
|
||||||
|
|
||||||
|
return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT));
|
||||||
|
} else if self.token == token::LBRACE {
|
||||||
|
// This is a struct literal, unless we're prohibited from
|
||||||
|
// parsing struct literals here.
|
||||||
|
if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
|
||||||
|
// It's a struct literal.
|
||||||
|
self.bump();
|
||||||
|
let mut fields = Vec::new();
|
||||||
|
let mut base = None;
|
||||||
|
|
||||||
|
while self.token != token::RBRACE {
|
||||||
|
if self.eat(&token::DOTDOT) {
|
||||||
|
base = Some(self.parse_expr());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fields.push(self.parse_field());
|
||||||
|
self.commit_expr(fields.last().unwrap().expr,
|
||||||
|
&[token::COMMA], &[token::RBRACE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fields.push(self.parse_field());
|
if fields.len() == 0 && base.is_none() {
|
||||||
self.commit_expr(fields.last().unwrap().expr,
|
let last_span = self.last_span;
|
||||||
&[token::COMMA], &[token::RBRACE]);
|
self.span_err(last_span,
|
||||||
}
|
"structure literal must either have at \
|
||||||
|
least one field or use functional \
|
||||||
|
structure update syntax");
|
||||||
|
}
|
||||||
|
|
||||||
if fields.len() == 0 && base.is_none() {
|
hi = self.span.hi;
|
||||||
let last_span = self.last_span;
|
self.expect(&token::RBRACE);
|
||||||
self.span_err(last_span,
|
ex = ExprStruct(pth, fields, base);
|
||||||
"structure literal must either have at \
|
return self.mk_expr(lo, hi, ex);
|
||||||
least one field or use functional \
|
|
||||||
structure update syntax");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hi = self.span.hi;
|
|
||||||
self.expect(&token::RBRACE);
|
|
||||||
ex = ExprStruct(pth, fields, base);
|
|
||||||
return self.mk_expr(lo, hi, ex);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
hi = pth.span.hi;
|
hi = pth.span.hi;
|
||||||
ex = ExprPath(pth);
|
ex = ExprPath(pth);
|
||||||
} else {
|
},
|
||||||
// other literal expression
|
_ => {
|
||||||
let lit = self.parse_lit();
|
// other literal expression
|
||||||
hi = lit.span.hi;
|
let lit = self.parse_lit();
|
||||||
ex = ExprLit(box(GC) lit);
|
hi = lit.span.hi;
|
||||||
|
ex = ExprLit(box(GC) lit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.mk_expr(lo, hi, ex);
|
return self.mk_expr(lo, hi, ex);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue