mirror of
https://github.com/rust-lang/rust.git
synced 2026-06-02 06:28:20 +03:00
auto merge of #11226 : pcwalton/rust/mutable-parser, r=pcwalton
r? @alexcrichton
This commit is contained in:
+23
-23
@@ -39,9 +39,9 @@ fn next_state(s: State) -> Option<State> {
|
||||
|
||||
pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
let p = parse::new_parser_from_tts(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
tts.to_owned());
|
||||
let mut p = parse::new_parser_from_tts(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
tts.to_owned());
|
||||
|
||||
let mut asm = @"";
|
||||
let mut asm_str_style = None;
|
||||
@@ -66,9 +66,9 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
asm_str_style = Some(style);
|
||||
}
|
||||
Outputs => {
|
||||
while *p.token != token::EOF &&
|
||||
*p.token != token::COLON &&
|
||||
*p.token != token::MOD_SEP {
|
||||
while p.token != token::EOF &&
|
||||
p.token != token::COLON &&
|
||||
p.token != token::MOD_SEP {
|
||||
|
||||
if outputs.len() != 0 {
|
||||
p.eat(&token::COMMA);
|
||||
@@ -77,10 +77,10 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
let (constraint, _str_style) = p.parse_str();
|
||||
|
||||
if constraint.starts_with("+") {
|
||||
cx.span_unimpl(*p.last_span,
|
||||
cx.span_unimpl(p.last_span,
|
||||
"'+' (read+write) output operand constraint modifier");
|
||||
} else if !constraint.starts_with("=") {
|
||||
cx.span_err(*p.last_span, "output operand constraint lacks '='");
|
||||
cx.span_err(p.last_span, "output operand constraint lacks '='");
|
||||
}
|
||||
|
||||
p.expect(&token::LPAREN);
|
||||
@@ -91,9 +91,9 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
}
|
||||
}
|
||||
Inputs => {
|
||||
while *p.token != token::EOF &&
|
||||
*p.token != token::COLON &&
|
||||
*p.token != token::MOD_SEP {
|
||||
while p.token != token::EOF &&
|
||||
p.token != token::COLON &&
|
||||
p.token != token::MOD_SEP {
|
||||
|
||||
if inputs.len() != 0 {
|
||||
p.eat(&token::COMMA);
|
||||
@@ -102,9 +102,9 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
let (constraint, _str_style) = p.parse_str();
|
||||
|
||||
if constraint.starts_with("=") {
|
||||
cx.span_err(*p.last_span, "input operand constraint contains '='");
|
||||
cx.span_err(p.last_span, "input operand constraint contains '='");
|
||||
} else if constraint.starts_with("+") {
|
||||
cx.span_err(*p.last_span, "input operand constraint contains '+'");
|
||||
cx.span_err(p.last_span, "input operand constraint contains '+'");
|
||||
}
|
||||
|
||||
p.expect(&token::LPAREN);
|
||||
@@ -116,9 +116,9 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
}
|
||||
Clobbers => {
|
||||
let mut clobs = ~[];
|
||||
while *p.token != token::EOF &&
|
||||
*p.token != token::COLON &&
|
||||
*p.token != token::MOD_SEP {
|
||||
while p.token != token::EOF &&
|
||||
p.token != token::COLON &&
|
||||
p.token != token::MOD_SEP {
|
||||
|
||||
if clobs.len() != 0 {
|
||||
p.eat(&token::COMMA);
|
||||
@@ -142,16 +142,16 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
dialect = ast::asm_intel;
|
||||
}
|
||||
|
||||
if *p.token == token::COMMA {
|
||||
if p.token == token::COMMA {
|
||||
p.eat(&token::COMMA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while *p.token == token::COLON ||
|
||||
*p.token == token::MOD_SEP ||
|
||||
*p.token == token::EOF {
|
||||
state = if *p.token == token::COLON {
|
||||
while p.token == token::COLON ||
|
||||
p.token == token::MOD_SEP ||
|
||||
p.token == token::EOF {
|
||||
state = if p.token == token::COLON {
|
||||
p.bump();
|
||||
match next_state(state) {
|
||||
Some(x) => x,
|
||||
@@ -160,7 +160,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if *p.token == token::MOD_SEP {
|
||||
} else if p.token == token::MOD_SEP {
|
||||
p.bump();
|
||||
let s = match next_state(state) {
|
||||
Some(x) => x,
|
||||
@@ -176,7 +176,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if *p.token == token::EOF {
|
||||
} else if p.token == token::EOF {
|
||||
continue_ = false;
|
||||
break;
|
||||
} else {
|
||||
|
||||
@@ -442,11 +442,11 @@ pub fn get_single_str_from_tts(cx: &ExtCtxt,
|
||||
pub fn get_exprs_from_tts(cx: &ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[ast::token_tree]) -> ~[@ast::Expr] {
|
||||
let p = parse::new_parser_from_tts(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
tts.to_owned());
|
||||
let mut p = parse::new_parser_from_tts(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
tts.to_owned());
|
||||
let mut es = ~[];
|
||||
while *p.token != token::EOF {
|
||||
while p.token != token::EOF {
|
||||
if es.len() != 0 && !p.eat(&token::COMMA) {
|
||||
cx.span_fatal(sp, "expected token: `,`");
|
||||
}
|
||||
|
||||
@@ -26,11 +26,13 @@
|
||||
use parse::attr::parser_attr;
|
||||
|
||||
pub fn expand_cfg(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) -> base::MacResult {
|
||||
let p = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts.to_owned());
|
||||
let mut p = parse::new_parser_from_tts(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
tts.to_owned());
|
||||
|
||||
let mut cfgs = ~[];
|
||||
// parse `cfg!(meta_item, meta_item(x,y), meta_item="foo", ...)`
|
||||
while *p.token != token::EOF {
|
||||
while p.token != token::EOF {
|
||||
cfgs.push(p.parse_meta_item());
|
||||
if p.eat(&token::EOF) { break } // trailing comma is optional,.
|
||||
p.expect(&token::COMMA);
|
||||
|
||||
+12
-12
@@ -53,11 +53,11 @@ struct Context<'a> {
|
||||
impl<'a> Context<'a> {
|
||||
/// Parses the arguments from the given list of tokens, returning None if
|
||||
/// there's a parse error so we can continue parsing other format! expressions.
|
||||
fn parse_args(&mut self, sp: Span,
|
||||
tts: &[ast::token_tree]) -> (@ast::Expr, Option<@ast::Expr>) {
|
||||
let p = rsparse::new_parser_from_tts(self.ecx.parse_sess(),
|
||||
self.ecx.cfg(),
|
||||
tts.to_owned());
|
||||
fn parse_args(&mut self, sp: Span, tts: &[ast::token_tree])
|
||||
-> (@ast::Expr, Option<@ast::Expr>) {
|
||||
let mut p = rsparse::new_parser_from_tts(self.ecx.parse_sess(),
|
||||
self.ecx.cfg(),
|
||||
tts.to_owned());
|
||||
// Parse the leading function expression (maybe a block, maybe a path)
|
||||
let extra = p.parse_expr();
|
||||
if !p.eat(&token::COMMA) {
|
||||
@@ -65,34 +65,34 @@ fn parse_args(&mut self, sp: Span,
|
||||
return (extra, None);
|
||||
}
|
||||
|
||||
if *p.token == token::EOF {
|
||||
if p.token == token::EOF {
|
||||
self.ecx.span_err(sp, "requires at least a format string argument");
|
||||
return (extra, None);
|
||||
}
|
||||
let fmtstr = p.parse_expr();
|
||||
let mut named = false;
|
||||
while *p.token != token::EOF {
|
||||
while p.token != token::EOF {
|
||||
if !p.eat(&token::COMMA) {
|
||||
self.ecx.span_err(sp, "expected token: `,`");
|
||||
return (extra, None);
|
||||
}
|
||||
if *p.token == token::EOF { break } // accept trailing commas
|
||||
if named || (token::is_ident(p.token) &&
|
||||
if p.token == token::EOF { break } // accept trailing commas
|
||||
if named || (token::is_ident(&p.token) &&
|
||||
p.look_ahead(1, |t| *t == token::EQ)) {
|
||||
named = true;
|
||||
let ident = match *p.token {
|
||||
let ident = match p.token {
|
||||
token::IDENT(i, _) => {
|
||||
p.bump();
|
||||
i
|
||||
}
|
||||
_ if named => {
|
||||
self.ecx.span_err(*p.span,
|
||||
self.ecx.span_err(p.span,
|
||||
"expected ident, positional arguments \
|
||||
cannot follow named arguments");
|
||||
return (extra, None);
|
||||
}
|
||||
_ => {
|
||||
self.ecx.span_err(*p.span,
|
||||
self.ecx.span_err(p.span,
|
||||
format!("expected ident for named \
|
||||
argument, but found `{}`",
|
||||
p.this_token_to_str()));
|
||||
|
||||
@@ -579,22 +579,18 @@ fn mk_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
ss
|
||||
}
|
||||
|
||||
fn expand_tts(cx: &ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[ast::token_tree]) -> (@ast::Expr, @ast::Expr) {
|
||||
|
||||
fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
-> (@ast::Expr, @ast::Expr) {
|
||||
// NB: It appears that the main parser loses its mind if we consider
|
||||
// $foo as a tt_nonterminal during the main parse, so we have to re-parse
|
||||
// under quote_depth > 0. This is silly and should go away; the _guess_ is
|
||||
// it has to do with transition away from supporting old-style macros, so
|
||||
// try removing it when enough of them are gone.
|
||||
|
||||
let p = parse::new_parser_from_tts(
|
||||
cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
tts.to_owned()
|
||||
);
|
||||
*p.quote_depth += 1u;
|
||||
let mut p = parse::new_parser_from_tts(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
tts.to_owned());
|
||||
p.quote_depth += 1u;
|
||||
|
||||
let cx_expr = p.parse_expr();
|
||||
if !p.eat(&token::COMMA) {
|
||||
|
||||
@@ -81,9 +81,13 @@ pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
let file = get_single_str_from_tts(cx, sp, tts, "include!");
|
||||
// The file will be added to the code map by the parser
|
||||
let p = parse::new_sub_parser_from_file(
|
||||
cx.parse_sess(), cx.cfg(),
|
||||
&res_rel_file(cx, sp, &Path::new(file)), sp);
|
||||
let mut p =
|
||||
parse::new_sub_parser_from_file(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
&res_rel_file(cx,
|
||||
sp,
|
||||
&Path::new(file)),
|
||||
sp);
|
||||
base::MRExpr(p.parse_expr())
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt,
|
||||
None,
|
||||
tt.to_owned());
|
||||
let rdr = tt_rdr as @mut reader;
|
||||
let rust_parser = Parser(sess, cfg.clone(), rdr.dup());
|
||||
let mut rust_parser = Parser(sess, cfg.clone(), rdr.dup());
|
||||
|
||||
if rust_parser.is_keyword(keywords::True) {
|
||||
cx.set_trace_macros(true);
|
||||
@@ -38,7 +38,7 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt,
|
||||
|
||||
rust_parser.bump();
|
||||
|
||||
let rust_parser = Parser(sess, cfg, rdr.dup());
|
||||
let mut rust_parser = Parser(sess, cfg, rdr.dup());
|
||||
let result = rust_parser.parse_expr();
|
||||
base::MRExpr(result)
|
||||
}
|
||||
|
||||
@@ -403,13 +403,13 @@ pub fn parse(
|
||||
}
|
||||
rdr.next_token();
|
||||
} else /* bb_eis.len() == 1 */ {
|
||||
let rust_parser = Parser(sess, cfg.clone(), rdr.dup());
|
||||
let mut rust_parser = Parser(sess, cfg.clone(), rdr.dup());
|
||||
|
||||
let mut ei = bb_eis.pop();
|
||||
match ei.elts[ei.idx].node {
|
||||
match_nonterminal(_, ref name, idx) => {
|
||||
ei.matches[idx].push(@matched_nonterminal(
|
||||
parse_nt(&rust_parser, ident_to_str(name))));
|
||||
parse_nt(&mut rust_parser, ident_to_str(name))));
|
||||
ei.idx += 1u;
|
||||
}
|
||||
_ => fail!()
|
||||
@@ -426,7 +426,7 @@ pub fn parse(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_nt(p: &Parser, name: &str) -> nonterminal {
|
||||
pub fn parse_nt(p: &mut Parser, name: &str) -> nonterminal {
|
||||
match name {
|
||||
"item" => match p.parse_item(~[]) {
|
||||
Some(i) => token::nt_item(i),
|
||||
@@ -438,19 +438,21 @@ pub fn parse_nt(p: &Parser, name: &str) -> nonterminal {
|
||||
"expr" => token::nt_expr(p.parse_expr()),
|
||||
"ty" => token::nt_ty(p.parse_ty(false /* no need to disambiguate*/)),
|
||||
// this could be handled like a token, since it is one
|
||||
"ident" => match *p.token {
|
||||
"ident" => match p.token {
|
||||
token::IDENT(sn,b) => { p.bump(); token::nt_ident(~sn,b) }
|
||||
_ => p.fatal(~"expected ident, found "
|
||||
+ token::to_str(get_ident_interner(), p.token))
|
||||
_ => {
|
||||
let token_str = token::to_str(get_ident_interner(), &p.token);
|
||||
p.fatal(~"expected ident, found " + token_str)
|
||||
}
|
||||
},
|
||||
"path" => {
|
||||
token::nt_path(~p.parse_path(LifetimeAndTypesWithoutColons).path)
|
||||
}
|
||||
"attr" => token::nt_attr(@p.parse_attribute(false)),
|
||||
"tt" => {
|
||||
*p.quote_depth += 1u; //but in theory, non-quoted tts might be useful
|
||||
p.quote_depth += 1u; //but in theory, non-quoted tts might be useful
|
||||
let res = token::nt_tt(@p.parse_token_tree());
|
||||
*p.quote_depth -= 1u;
|
||||
p.quote_depth -= 1u;
|
||||
res
|
||||
}
|
||||
"matchers" => token::nt_matchers(p.parse_matchers()),
|
||||
|
||||
@@ -24,10 +24,11 @@
|
||||
use parse::token::{get_ident_interner, special_idents, gensym_ident, ident_to_str};
|
||||
use parse::token::{FAT_ARROW, SEMI, nt_matchers, nt_tt, EOF};
|
||||
use print;
|
||||
use std::cell::RefCell;
|
||||
use util::small_vector::SmallVector;
|
||||
|
||||
struct ParserAnyMacro {
|
||||
parser: @Parser,
|
||||
parser: RefCell<Parser>,
|
||||
}
|
||||
|
||||
impl ParserAnyMacro {
|
||||
@@ -38,28 +39,36 @@ impl ParserAnyMacro {
|
||||
/// fail!(); } )` doesn't get picked up by .parse_expr(), but it's
|
||||
/// allowed to be there.
|
||||
fn ensure_complete_parse(&self, allow_semi: bool) {
|
||||
if allow_semi && *self.parser.token == SEMI {
|
||||
self.parser.bump()
|
||||
let mut parser = self.parser.borrow_mut();
|
||||
if allow_semi && parser.get().token == SEMI {
|
||||
parser.get().bump()
|
||||
}
|
||||
if *self.parser.token != EOF {
|
||||
let msg = format!("macro expansion ignores token `{}` and any following",
|
||||
self.parser.this_token_to_str());
|
||||
self.parser.span_err(*self.parser.span, msg);
|
||||
if parser.get().token != EOF {
|
||||
let token_str = parser.get().this_token_to_str();
|
||||
let msg = format!("macro expansion ignores token `{}` and any \
|
||||
following",
|
||||
token_str);
|
||||
let span = parser.get().span;
|
||||
parser.get().span_err(span, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AnyMacro for ParserAnyMacro {
|
||||
fn make_expr(&self) -> @ast::Expr {
|
||||
let ret = self.parser.parse_expr();
|
||||
let ret = {
|
||||
let mut parser = self.parser.borrow_mut();
|
||||
parser.get().parse_expr()
|
||||
};
|
||||
self.ensure_complete_parse(true);
|
||||
ret
|
||||
}
|
||||
fn make_items(&self) -> SmallVector<@ast::item> {
|
||||
let mut ret = SmallVector::zero();
|
||||
loop {
|
||||
let attrs = self.parser.parse_outer_attributes();
|
||||
match self.parser.parse_item(attrs) {
|
||||
let mut parser = self.parser.borrow_mut();
|
||||
let attrs = parser.get().parse_outer_attributes();
|
||||
match parser.get().parse_item(attrs) {
|
||||
Some(item) => ret.push(item),
|
||||
None => break
|
||||
}
|
||||
@@ -68,8 +77,11 @@ fn make_items(&self) -> SmallVector<@ast::item> {
|
||||
ret
|
||||
}
|
||||
fn make_stmt(&self) -> @ast::Stmt {
|
||||
let attrs = self.parser.parse_outer_attributes();
|
||||
let ret = self.parser.parse_stmt(attrs);
|
||||
let ret = {
|
||||
let mut parser = self.parser.borrow_mut();
|
||||
let attrs = parser.get().parse_outer_attributes();
|
||||
parser.get().parse_stmt(attrs)
|
||||
};
|
||||
self.ensure_complete_parse(true);
|
||||
ret
|
||||
}
|
||||
@@ -142,14 +154,14 @@ fn generic_extension(cx: &ExtCtxt,
|
||||
// rhs has holes ( `$id` and `$(...)` that need filled)
|
||||
let trncbr = new_tt_reader(s_d, Some(named_matches),
|
||||
rhs);
|
||||
let p = @Parser(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
trncbr as @mut reader);
|
||||
let p = Parser(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
trncbr as @mut reader);
|
||||
|
||||
// Let the context choose how to interpret the result.
|
||||
// Weird, but useful for X-macros.
|
||||
return MRAny(@ParserAnyMacro {
|
||||
parser: p,
|
||||
parser: RefCell::new(p),
|
||||
} as @AnyMacro)
|
||||
}
|
||||
failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo {
|
||||
|
||||
+23
-22
@@ -17,24 +17,23 @@
|
||||
|
||||
// a parser that can parse attributes.
|
||||
pub trait parser_attr {
|
||||
fn parse_outer_attributes(&self) -> ~[ast::Attribute];
|
||||
fn parse_attribute(&self, permit_inner: bool) -> ast::Attribute;
|
||||
fn parse_inner_attrs_and_next(&self) ->
|
||||
(~[ast::Attribute], ~[ast::Attribute]);
|
||||
fn parse_meta_item(&self) -> @ast::MetaItem;
|
||||
fn parse_meta_seq(&self) -> ~[@ast::MetaItem];
|
||||
fn parse_optional_meta(&self) -> ~[@ast::MetaItem];
|
||||
fn parse_outer_attributes(&mut self) -> ~[ast::Attribute];
|
||||
fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute;
|
||||
fn parse_inner_attrs_and_next(&mut self)
|
||||
-> (~[ast::Attribute], ~[ast::Attribute]);
|
||||
fn parse_meta_item(&mut self) -> @ast::MetaItem;
|
||||
fn parse_meta_seq(&mut self) -> ~[@ast::MetaItem];
|
||||
fn parse_optional_meta(&mut self) -> ~[@ast::MetaItem];
|
||||
}
|
||||
|
||||
impl parser_attr for Parser {
|
||||
|
||||
// Parse attributes that appear before an item
|
||||
fn parse_outer_attributes(&self) -> ~[ast::Attribute] {
|
||||
fn parse_outer_attributes(&mut self) -> ~[ast::Attribute] {
|
||||
let mut attrs: ~[ast::Attribute] = ~[];
|
||||
loop {
|
||||
debug!("parse_outer_attributes: self.token={:?}",
|
||||
self.token);
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::INTERPOLATED(token::nt_attr(..)) => {
|
||||
attrs.push(self.parse_attribute(false));
|
||||
}
|
||||
@@ -66,10 +65,10 @@ fn parse_outer_attributes(&self) -> ~[ast::Attribute] {
|
||||
//
|
||||
// if permit_inner is true, then a trailing `;` indicates an inner
|
||||
// attribute
|
||||
fn parse_attribute(&self, permit_inner: bool) -> ast::Attribute {
|
||||
fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
|
||||
debug!("parse_attributes: permit_inner={:?} self.token={:?}",
|
||||
permit_inner, self.token);
|
||||
let (span, value) = match *self.token {
|
||||
let (span, value) = match self.token {
|
||||
INTERPOLATED(token::nt_attr(attr)) => {
|
||||
assert!(attr.node.style == ast::AttrOuter);
|
||||
self.bump();
|
||||
@@ -85,11 +84,12 @@ fn parse_attribute(&self, permit_inner: bool) -> ast::Attribute {
|
||||
(mk_sp(lo, hi), meta_item)
|
||||
}
|
||||
_ => {
|
||||
let token_str = self.this_token_to_str();
|
||||
self.fatal(format!("expected `\\#` but found `{}`",
|
||||
self.this_token_to_str()));
|
||||
token_str));
|
||||
}
|
||||
};
|
||||
let style = if permit_inner && *self.token == token::SEMI {
|
||||
let style = if permit_inner && self.token == token::SEMI {
|
||||
self.bump();
|
||||
ast::AttrInner
|
||||
} else {
|
||||
@@ -115,12 +115,12 @@ fn parse_attribute(&self, permit_inner: bool) -> ast::Attribute {
|
||||
// matches inner_attrs* outer_attr?
|
||||
// you can make the 'next' field an Option, but the result is going to be
|
||||
// more useful as a vector.
|
||||
fn parse_inner_attrs_and_next(&self)
|
||||
fn parse_inner_attrs_and_next(&mut self)
|
||||
-> (~[ast::Attribute], ~[ast::Attribute]) {
|
||||
let mut inner_attrs: ~[ast::Attribute] = ~[];
|
||||
let mut next_outer_attrs: ~[ast::Attribute] = ~[];
|
||||
loop {
|
||||
let attr = match *self.token {
|
||||
let attr = match self.token {
|
||||
token::INTERPOLATED(token::nt_attr(..)) => {
|
||||
self.parse_attribute(true)
|
||||
}
|
||||
@@ -154,10 +154,11 @@ fn parse_inner_attrs_and_next(&self)
|
||||
// matches meta_item = IDENT
|
||||
// | IDENT = lit
|
||||
// | IDENT meta_seq
|
||||
fn parse_meta_item(&self) -> @ast::MetaItem {
|
||||
fn parse_meta_item(&mut self) -> @ast::MetaItem {
|
||||
let lo = self.span.lo;
|
||||
let name = self.id_to_str(self.parse_ident());
|
||||
match *self.token {
|
||||
let ident = self.parse_ident();
|
||||
let name = self.id_to_str(ident);
|
||||
match self.token {
|
||||
token::EQ => {
|
||||
self.bump();
|
||||
let lit = self.parse_lit();
|
||||
@@ -187,15 +188,15 @@ fn parse_meta_item(&self) -> @ast::MetaItem {
|
||||
}
|
||||
|
||||
// matches meta_seq = ( COMMASEP(meta_item) )
|
||||
fn parse_meta_seq(&self) -> ~[@ast::MetaItem] {
|
||||
fn parse_meta_seq(&mut self) -> ~[@ast::MetaItem] {
|
||||
self.parse_seq(&token::LPAREN,
|
||||
&token::RPAREN,
|
||||
seq_sep_trailing_disallowed(token::COMMA),
|
||||
|p| p.parse_meta_item()).node
|
||||
}
|
||||
|
||||
fn parse_optional_meta(&self) -> ~[@ast::MetaItem] {
|
||||
match *self.token {
|
||||
fn parse_optional_meta(&mut self) -> ~[@ast::MetaItem] {
|
||||
match self.token {
|
||||
token::LPAREN => self.parse_meta_seq(),
|
||||
_ => ~[]
|
||||
}
|
||||
|
||||
+22
-37
@@ -84,7 +84,7 @@ pub fn parse_crate_attrs_from_file(
|
||||
cfg: ast::CrateConfig,
|
||||
sess: @mut ParseSess
|
||||
) -> ~[ast::Attribute] {
|
||||
let parser = new_parser_from_file(sess, cfg, input);
|
||||
let mut parser = new_parser_from_file(sess, cfg, input);
|
||||
let (inner, _) = parser.parse_inner_attrs_and_next();
|
||||
return inner;
|
||||
}
|
||||
@@ -95,10 +95,10 @@ pub fn parse_crate_from_source_str(
|
||||
cfg: ast::CrateConfig,
|
||||
sess: @mut ParseSess
|
||||
) -> ast::Crate {
|
||||
let p = new_parser_from_source_str(sess,
|
||||
/*bad*/ cfg.clone(),
|
||||
name,
|
||||
source);
|
||||
let mut p = new_parser_from_source_str(sess,
|
||||
/*bad*/ cfg.clone(),
|
||||
name,
|
||||
source);
|
||||
maybe_aborted(p.parse_crate_mod(),p)
|
||||
}
|
||||
|
||||
@@ -108,10 +108,10 @@ pub fn parse_crate_attrs_from_source_str(
|
||||
cfg: ast::CrateConfig,
|
||||
sess: @mut ParseSess
|
||||
) -> ~[ast::Attribute] {
|
||||
let p = new_parser_from_source_str(sess,
|
||||
/*bad*/ cfg.clone(),
|
||||
name,
|
||||
source);
|
||||
let mut p = new_parser_from_source_str(sess,
|
||||
/*bad*/ cfg.clone(),
|
||||
name,
|
||||
source);
|
||||
let (inner, _) = maybe_aborted(p.parse_inner_attrs_and_next(),p);
|
||||
return inner;
|
||||
}
|
||||
@@ -122,12 +122,7 @@ pub fn parse_expr_from_source_str(
|
||||
cfg: ast::CrateConfig,
|
||||
sess: @mut ParseSess
|
||||
) -> @ast::Expr {
|
||||
let p = new_parser_from_source_str(
|
||||
sess,
|
||||
cfg,
|
||||
name,
|
||||
source
|
||||
);
|
||||
let mut p = new_parser_from_source_str(sess, cfg, name, source);
|
||||
maybe_aborted(p.parse_expr(), p)
|
||||
}
|
||||
|
||||
@@ -138,12 +133,7 @@ pub fn parse_item_from_source_str(
|
||||
attrs: ~[ast::Attribute],
|
||||
sess: @mut ParseSess
|
||||
) -> Option<@ast::item> {
|
||||
let p = new_parser_from_source_str(
|
||||
sess,
|
||||
cfg,
|
||||
name,
|
||||
source
|
||||
);
|
||||
let mut p = new_parser_from_source_str(sess, cfg, name, source);
|
||||
maybe_aborted(p.parse_item(attrs),p)
|
||||
}
|
||||
|
||||
@@ -153,12 +143,7 @@ pub fn parse_meta_from_source_str(
|
||||
cfg: ast::CrateConfig,
|
||||
sess: @mut ParseSess
|
||||
) -> @ast::MetaItem {
|
||||
let p = new_parser_from_source_str(
|
||||
sess,
|
||||
cfg,
|
||||
name,
|
||||
source
|
||||
);
|
||||
let mut p = new_parser_from_source_str(sess, cfg, name, source);
|
||||
maybe_aborted(p.parse_meta_item(),p)
|
||||
}
|
||||
|
||||
@@ -169,7 +154,7 @@ pub fn parse_stmt_from_source_str(
|
||||
attrs: ~[ast::Attribute],
|
||||
sess: @mut ParseSess
|
||||
) -> @ast::Stmt {
|
||||
let p = new_parser_from_source_str(
|
||||
let mut p = new_parser_from_source_str(
|
||||
sess,
|
||||
cfg,
|
||||
name,
|
||||
@@ -184,13 +169,13 @@ pub fn parse_tts_from_source_str(
|
||||
cfg: ast::CrateConfig,
|
||||
sess: @mut ParseSess
|
||||
) -> ~[ast::token_tree] {
|
||||
let p = new_parser_from_source_str(
|
||||
let mut p = new_parser_from_source_str(
|
||||
sess,
|
||||
cfg,
|
||||
name,
|
||||
source
|
||||
);
|
||||
*p.quote_depth += 1u;
|
||||
p.quote_depth += 1u;
|
||||
// right now this is re-creating the token trees from ... token trees.
|
||||
maybe_aborted(p.parse_all_token_trees(),p)
|
||||
}
|
||||
@@ -201,15 +186,15 @@ pub fn parse_tts_from_source_str(
|
||||
// consumed all of the input before returning the function's
|
||||
// result.
|
||||
pub fn parse_from_source_str<T>(
|
||||
f: |&Parser| -> T,
|
||||
f: |&mut Parser| -> T,
|
||||
name: @str,
|
||||
ss: codemap::FileSubstr,
|
||||
source: @str,
|
||||
cfg: ast::CrateConfig,
|
||||
sess: @mut ParseSess)
|
||||
-> T {
|
||||
let p = new_parser_from_source_substr(sess, cfg, name, ss, source);
|
||||
let r = f(&p);
|
||||
let mut p = new_parser_from_source_substr(sess, cfg, name, ss, source);
|
||||
let r = f(&mut p);
|
||||
if !p.reader.is_eof() {
|
||||
p.reader.fatal(~"expected end-of-string");
|
||||
}
|
||||
@@ -326,7 +311,7 @@ pub fn filemap_to_tts(sess: @mut ParseSess, filemap: @FileMap)
|
||||
// parsing tt's probably shouldn't require a parser at all.
|
||||
let cfg = ~[];
|
||||
let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap);
|
||||
let p1 = Parser(sess, cfg, srdr as @mut reader);
|
||||
let mut p1 = Parser(sess, cfg, srdr as @mut reader);
|
||||
p1.parse_all_token_trees()
|
||||
}
|
||||
|
||||
@@ -339,7 +324,7 @@ pub fn tts_to_parser(sess: @mut ParseSess,
|
||||
}
|
||||
|
||||
// abort if necessary
|
||||
pub fn maybe_aborted<T>(result : T, p: Parser) -> T {
|
||||
pub fn maybe_aborted<T>(result: T, mut p: Parser) -> T {
|
||||
p.abort_if_errors();
|
||||
result
|
||||
}
|
||||
@@ -646,11 +631,11 @@ fn sp(a: u32, b: u32) -> Span {
|
||||
}
|
||||
|
||||
fn parser_done(p: Parser){
|
||||
assert_eq!((*p.token).clone(), token::EOF);
|
||||
assert_eq!(p.token.clone(), token::EOF);
|
||||
}
|
||||
|
||||
#[test] fn parse_ident_pat () {
|
||||
let parser = string_to_parser(@"b");
|
||||
let mut parser = string_to_parser(@"b");
|
||||
assert_eq!(parser.parse_pat(),
|
||||
@ast::Pat{id: ast::DUMMY_NODE_ID,
|
||||
node: ast::PatIdent(
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
use ast::{Expr, ExprLit, lit_nil};
|
||||
use codemap::{Span, respan};
|
||||
use parse::parser::Parser;
|
||||
use parse::token::Token;
|
||||
use parse::token;
|
||||
|
||||
use std::str;
|
||||
@@ -57,23 +56,22 @@ fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
|
||||
|
||||
pub trait ParserObsoleteMethods {
|
||||
/// Reports an obsolete syntax non-fatal error.
|
||||
fn obsolete(&self, sp: Span, kind: ObsoleteSyntax);
|
||||
fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
|
||||
// Reports an obsolete syntax non-fatal error, and returns
|
||||
// a placeholder expression
|
||||
fn obsolete_expr(&self, sp: Span, kind: ObsoleteSyntax) -> @Expr;
|
||||
fn report(&self,
|
||||
fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> @Expr;
|
||||
fn report(&mut self,
|
||||
sp: Span,
|
||||
kind: ObsoleteSyntax,
|
||||
kind_str: &str,
|
||||
desc: &str);
|
||||
fn token_is_obsolete_ident(&self, ident: &str, token: &Token) -> bool;
|
||||
fn is_obsolete_ident(&self, ident: &str) -> bool;
|
||||
fn eat_obsolete_ident(&self, ident: &str) -> bool;
|
||||
fn is_obsolete_ident(&mut self, ident: &str) -> bool;
|
||||
fn eat_obsolete_ident(&mut self, ident: &str) -> bool;
|
||||
}
|
||||
|
||||
impl ParserObsoleteMethods for Parser {
|
||||
/// Reports an obsolete syntax non-fatal error.
|
||||
fn obsolete(&self, sp: Span, kind: ObsoleteSyntax) {
|
||||
fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
|
||||
let (kind_str, desc) = match kind {
|
||||
ObsoleteSwap => (
|
||||
"swap",
|
||||
@@ -158,12 +156,12 @@ fn obsolete(&self, sp: Span, kind: ObsoleteSyntax) {
|
||||
|
||||
// Reports an obsolete syntax non-fatal error, and returns
|
||||
// a placeholder expression
|
||||
fn obsolete_expr(&self, sp: Span, kind: ObsoleteSyntax) -> @Expr {
|
||||
fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> @Expr {
|
||||
self.obsolete(sp, kind);
|
||||
self.mk_expr(sp.lo, sp.hi, ExprLit(@respan(sp, lit_nil)))
|
||||
}
|
||||
|
||||
fn report(&self,
|
||||
fn report(&mut self,
|
||||
sp: Span,
|
||||
kind: ObsoleteSyntax,
|
||||
kind_str: &str,
|
||||
@@ -176,9 +174,8 @@ fn report(&self,
|
||||
}
|
||||
}
|
||||
|
||||
fn token_is_obsolete_ident(&self, ident: &str, token: &Token)
|
||||
-> bool {
|
||||
match *token {
|
||||
fn is_obsolete_ident(&mut self, ident: &str) -> bool {
|
||||
match self.token {
|
||||
token::IDENT(sid, _) => {
|
||||
str::eq_slice(self.id_to_str(sid), ident)
|
||||
}
|
||||
@@ -186,11 +183,7 @@ fn token_is_obsolete_ident(&self, ident: &str, token: &Token)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_obsolete_ident(&self, ident: &str) -> bool {
|
||||
self.token_is_obsolete_ident(ident, self.token)
|
||||
}
|
||||
|
||||
fn eat_obsolete_ident(&self, ident: &str) -> bool {
|
||||
fn eat_obsolete_ident(&mut self, ident: &str) -> bool {
|
||||
if self.is_obsolete_ident(ident) {
|
||||
self.bump();
|
||||
true
|
||||
|
||||
+728
-689
@@ -143,15 +143,17 @@ macro_rules! maybe_whole_expr (
|
||||
{
|
||||
// This horrible convolution is brought to you by
|
||||
// @mut, have a terrible day
|
||||
let ret = match *($p).token {
|
||||
let mut maybe_path = match ($p).token {
|
||||
INTERPOLATED(token::nt_path(ref pt)) => Some((**pt).clone()),
|
||||
_ => None,
|
||||
};
|
||||
let ret = match ($p).token {
|
||||
INTERPOLATED(token::nt_expr(e)) => {
|
||||
Some(e)
|
||||
}
|
||||
INTERPOLATED(token::nt_path(ref pt)) => {
|
||||
Some($p.mk_expr(
|
||||
($p).span.lo,
|
||||
($p).span.hi,
|
||||
ExprPath(/* bad */ (**pt).clone())))
|
||||
INTERPOLATED(token::nt_path(_)) => {
|
||||
let pt = maybe_path.take_unwrap();
|
||||
Some($p.mk_expr(($p).span.lo, ($p).span.hi, ExprPath(pt)))
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
@@ -169,7 +171,7 @@ macro_rules! maybe_whole_expr (
|
||||
macro_rules! maybe_whole (
|
||||
($p:expr, $constructor:ident) => (
|
||||
{
|
||||
let __found__ = match *($p).token {
|
||||
let __found__ = match ($p).token {
|
||||
INTERPOLATED(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
@@ -185,7 +187,7 @@ macro_rules! maybe_whole (
|
||||
);
|
||||
(no_clone $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let __found__ = match *($p).token {
|
||||
let __found__ = match ($p).token {
|
||||
INTERPOLATED(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
@@ -201,7 +203,7 @@ macro_rules! maybe_whole (
|
||||
);
|
||||
(deref $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let __found__ = match *($p).token {
|
||||
let __found__ = match ($p).token {
|
||||
INTERPOLATED(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
@@ -217,7 +219,7 @@ macro_rules! maybe_whole (
|
||||
);
|
||||
(Some $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let __found__ = match *($p).token {
|
||||
let __found__ = match ($p).token {
|
||||
INTERPOLATED(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
@@ -233,7 +235,7 @@ macro_rules! maybe_whole (
|
||||
);
|
||||
(iovi $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let __found__ = match *($p).token {
|
||||
let __found__ = match ($p).token {
|
||||
INTERPOLATED(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
@@ -249,7 +251,7 @@ macro_rules! maybe_whole (
|
||||
);
|
||||
(pair_empty $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let __found__ = match *($p).token {
|
||||
let __found__ = match ($p).token {
|
||||
INTERPOLATED(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
@@ -284,9 +286,7 @@ struct ParsedItemsAndViewItems {
|
||||
|
||||
/* ident is handled by common.rs */
|
||||
|
||||
pub fn Parser(sess: @mut ParseSess,
|
||||
cfg: ast::CrateConfig,
|
||||
rdr: @mut reader)
|
||||
pub fn Parser(sess: @mut ParseSess, cfg: ast::CrateConfig, rdr: @mut reader)
|
||||
-> Parser {
|
||||
let tok0 = rdr.next_token();
|
||||
let interner = get_ident_interner();
|
||||
@@ -301,55 +301,54 @@ pub fn Parser(sess: @mut ParseSess,
|
||||
interner: interner,
|
||||
sess: sess,
|
||||
cfg: cfg,
|
||||
token: @mut tok0.tok,
|
||||
span: @mut span,
|
||||
last_span: @mut span,
|
||||
last_token: @mut None,
|
||||
buffer: @mut ([
|
||||
token: tok0.tok,
|
||||
span: span,
|
||||
last_span: span,
|
||||
last_token: None,
|
||||
buffer: [
|
||||
placeholder.clone(),
|
||||
placeholder.clone(),
|
||||
placeholder.clone(),
|
||||
placeholder.clone(),
|
||||
]),
|
||||
buffer_start: @mut 0,
|
||||
buffer_end: @mut 0,
|
||||
tokens_consumed: @mut 0,
|
||||
restriction: @mut UNRESTRICTED,
|
||||
quote_depth: @mut 0,
|
||||
obsolete_set: @mut HashSet::new(),
|
||||
mod_path_stack: @mut ~[],
|
||||
open_braces: @mut ~[],
|
||||
],
|
||||
buffer_start: 0,
|
||||
buffer_end: 0,
|
||||
tokens_consumed: 0,
|
||||
restriction: UNRESTRICTED,
|
||||
quote_depth: 0,
|
||||
obsolete_set: HashSet::new(),
|
||||
mod_path_stack: ~[],
|
||||
open_braces: ~[],
|
||||
non_copyable: util::NonCopyable
|
||||
}
|
||||
}
|
||||
|
||||
// ooh, nasty mutable fields everywhere....
|
||||
pub struct Parser {
|
||||
sess: @mut ParseSess,
|
||||
cfg: CrateConfig,
|
||||
// the current token:
|
||||
token: @mut token::Token,
|
||||
token: token::Token,
|
||||
// the span of the current token:
|
||||
span: @mut Span,
|
||||
span: Span,
|
||||
// the span of the prior token:
|
||||
last_span: @mut Span,
|
||||
last_span: Span,
|
||||
// the previous token or None (only stashed sometimes).
|
||||
last_token: @mut Option<~token::Token>,
|
||||
buffer: @mut [TokenAndSpan, ..4],
|
||||
buffer_start: @mut int,
|
||||
buffer_end: @mut int,
|
||||
tokens_consumed: @mut uint,
|
||||
restriction: @mut restriction,
|
||||
quote_depth: @mut uint, // not (yet) related to the quasiquoter
|
||||
last_token: Option<~token::Token>,
|
||||
buffer: [TokenAndSpan, ..4],
|
||||
buffer_start: int,
|
||||
buffer_end: int,
|
||||
tokens_consumed: uint,
|
||||
restriction: restriction,
|
||||
quote_depth: uint, // not (yet) related to the quasiquoter
|
||||
reader: @mut reader,
|
||||
interner: @token::ident_interner,
|
||||
/// The set of seen errors about obsolete syntax. Used to suppress
|
||||
/// extra detail when the same error is seen twice
|
||||
obsolete_set: @mut HashSet<ObsoleteSyntax>,
|
||||
obsolete_set: HashSet<ObsoleteSyntax>,
|
||||
/// Used to determine the path to externally loaded source files
|
||||
mod_path_stack: @mut ~[@str],
|
||||
mod_path_stack: ~[@str],
|
||||
/// Stack of spans of open delimiters. Used for error message.
|
||||
open_braces: @mut ~[Span],
|
||||
open_braces: ~[Span],
|
||||
/* do not copy the parser; its state is tied to outside state */
|
||||
priv non_copyable: util::NonCopyable
|
||||
}
|
||||
@@ -360,67 +359,59 @@ fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
|
||||
|
||||
impl Parser {
|
||||
// convert a token to a string using self's reader
|
||||
pub fn token_to_str(&self, token: &token::Token) -> ~str {
|
||||
pub fn token_to_str(token: &token::Token) -> ~str {
|
||||
token::to_str(get_ident_interner(), token)
|
||||
}
|
||||
|
||||
// convert the current token to a string using self's reader
|
||||
pub fn this_token_to_str(&self) -> ~str {
|
||||
self.token_to_str(self.token)
|
||||
pub fn this_token_to_str(&mut self) -> ~str {
|
||||
Parser::token_to_str(&self.token)
|
||||
}
|
||||
|
||||
pub fn unexpected_last(&self, t: &token::Token) -> ! {
|
||||
self.span_fatal(
|
||||
*self.last_span,
|
||||
format!(
|
||||
"unexpected token: `{}`",
|
||||
self.token_to_str(t)
|
||||
)
|
||||
);
|
||||
pub fn unexpected_last(&mut self, t: &token::Token) -> ! {
|
||||
let token_str = Parser::token_to_str(t);
|
||||
self.span_fatal(self.last_span, format!("unexpected token: `{}`",
|
||||
token_str));
|
||||
}
|
||||
|
||||
pub fn unexpected(&self) -> ! {
|
||||
self.fatal(
|
||||
format!(
|
||||
"unexpected token: `{}`",
|
||||
self.this_token_to_str()
|
||||
)
|
||||
);
|
||||
pub fn unexpected(&mut self) -> ! {
|
||||
let this_token = self.this_token_to_str();
|
||||
self.fatal(format!("unexpected token: `{}`", this_token));
|
||||
}
|
||||
|
||||
// expect and consume the token t. Signal an error if
|
||||
// the next token is not t.
|
||||
pub fn expect(&self, t: &token::Token) {
|
||||
if *self.token == *t {
|
||||
pub fn expect(&mut self, t: &token::Token) {
|
||||
if self.token == *t {
|
||||
self.bump();
|
||||
} else {
|
||||
self.fatal(
|
||||
format!(
|
||||
"expected `{}` but found `{}`",
|
||||
self.token_to_str(t),
|
||||
self.this_token_to_str()
|
||||
)
|
||||
)
|
||||
let token_str = Parser::token_to_str(t);
|
||||
let this_token_str = self.this_token_to_str();
|
||||
self.fatal(format!("expected `{}` but found `{}`",
|
||||
token_str,
|
||||
this_token_str))
|
||||
}
|
||||
}
|
||||
|
||||
// Expect next token to be edible or inedible token. If edible,
|
||||
// then consume it; if inedible, then return without consuming
|
||||
// anything. Signal a fatal error if next token is unexpected.
|
||||
pub fn expect_one_of(&self, edible: &[token::Token], inedible: &[token::Token]) {
|
||||
fn tokens_to_str(p:&Parser, tokens: &[token::Token]) -> ~str {
|
||||
pub fn expect_one_of(&mut self,
|
||||
edible: &[token::Token],
|
||||
inedible: &[token::Token]) {
|
||||
fn tokens_to_str(tokens: &[token::Token]) -> ~str {
|
||||
let mut i = tokens.iter();
|
||||
// This might be a sign we need a connect method on Iterator.
|
||||
let b = i.next().map_default(~"", |t| p.token_to_str(t));
|
||||
i.fold(b, |b,a| b + "`, `" + p.token_to_str(a))
|
||||
let b = i.next().map_default(~"", |t| Parser::token_to_str(t));
|
||||
i.fold(b, |b,a| b + "`, `" + Parser::token_to_str(a))
|
||||
}
|
||||
if edible.contains(self.token) {
|
||||
if edible.contains(&self.token) {
|
||||
self.bump();
|
||||
} else if inedible.contains(self.token) {
|
||||
} else if inedible.contains(&self.token) {
|
||||
// leave it in the input
|
||||
} else {
|
||||
let expected = vec::append(edible.to_owned(), inedible);
|
||||
let expect = tokens_to_str(self, expected);
|
||||
let expect = tokens_to_str(expected);
|
||||
let actual = self.this_token_to_str();
|
||||
self.fatal(
|
||||
if expected.len() != 1 {
|
||||
@@ -435,12 +426,12 @@ fn tokens_to_str(p:&Parser, tokens: &[token::Token]) -> ~str {
|
||||
// Check for erroneous `ident { }`; if matches, signal error and
|
||||
// recover (without consuming any expected input token). Returns
|
||||
// true if and only if input was consumed for recovery.
|
||||
pub fn check_for_erroneous_unit_struct_expecting(&self, expected: &[token::Token]) -> bool {
|
||||
if *self.token == token::LBRACE
|
||||
pub fn check_for_erroneous_unit_struct_expecting(&mut self, expected: &[token::Token]) -> bool {
|
||||
if self.token == token::LBRACE
|
||||
&& expected.iter().all(|t| *t != token::LBRACE)
|
||||
&& self.look_ahead(1, |t| *t == token::RBRACE) {
|
||||
// matched; signal non-fatal error and recover.
|
||||
self.span_err(*self.span,
|
||||
self.span_err(self.span,
|
||||
"Unit-like struct construction is written with no trailing `{ }`");
|
||||
self.eat(&token::LBRACE);
|
||||
self.eat(&token::RBRACE);
|
||||
@@ -453,7 +444,7 @@ pub fn check_for_erroneous_unit_struct_expecting(&self, expected: &[token::Token
|
||||
// Commit to parsing a complete expression `e` expected to be
|
||||
// followed by some token from the set edible + inedible. Recover
|
||||
// from anticipated input errors, discarding erroneous characters.
|
||||
pub fn commit_expr(&self, e: @Expr, edible: &[token::Token], inedible: &[token::Token]) {
|
||||
pub fn commit_expr(&mut self, e: @Expr, edible: &[token::Token], inedible: &[token::Token]) {
|
||||
debug!("commit_expr {:?}", e);
|
||||
match e.node {
|
||||
ExprPath(..) => {
|
||||
@@ -466,14 +457,14 @@ pub fn commit_expr(&self, e: @Expr, edible: &[token::Token], inedible: &[token::
|
||||
self.expect_one_of(edible, inedible)
|
||||
}
|
||||
|
||||
pub fn commit_expr_expecting(&self, e: @Expr, edible: token::Token) {
|
||||
pub fn commit_expr_expecting(&mut self, e: @Expr, edible: token::Token) {
|
||||
self.commit_expr(e, &[edible], &[])
|
||||
}
|
||||
|
||||
// Commit to parsing a complete statement `s`, which expects to be
|
||||
// followed by some token from the set edible + inedible. Check
|
||||
// for recoverable input errors, discarding erroneous characters.
|
||||
pub fn commit_stmt(&self, s: @Stmt, edible: &[token::Token], inedible: &[token::Token]) {
|
||||
pub fn commit_stmt(&mut self, s: @Stmt, edible: &[token::Token], inedible: &[token::Token]) {
|
||||
debug!("commit_stmt {:?}", s);
|
||||
let _s = s; // unused, but future checks might want to inspect `s`.
|
||||
if self.last_token.as_ref().map_default(false, |t| is_ident_or_path(*t)) {
|
||||
@@ -483,14 +474,14 @@ pub fn commit_stmt(&self, s: @Stmt, edible: &[token::Token], inedible: &[token::
|
||||
self.expect_one_of(edible, inedible)
|
||||
}
|
||||
|
||||
pub fn commit_stmt_expecting(&self, s: @Stmt, edible: token::Token) {
|
||||
pub fn commit_stmt_expecting(&mut self, s: @Stmt, edible: token::Token) {
|
||||
self.commit_stmt(s, &[edible], &[])
|
||||
}
|
||||
|
||||
pub fn parse_ident(&self) -> ast::Ident {
|
||||
pub fn parse_ident(&mut self) -> ast::Ident {
|
||||
self.check_strict_keywords();
|
||||
self.check_reserved_keywords();
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::IDENT(i, _) => {
|
||||
self.bump();
|
||||
i
|
||||
@@ -499,17 +490,13 @@ pub fn parse_ident(&self) -> ast::Ident {
|
||||
self.bug("ident interpolation not converted to real token");
|
||||
}
|
||||
_ => {
|
||||
self.fatal(
|
||||
format!(
|
||||
"expected ident, found `{}`",
|
||||
self.this_token_to_str()
|
||||
)
|
||||
);
|
||||
let token_str = self.this_token_to_str();
|
||||
self.fatal(format!( "expected ident, found `{}`", token_str))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_path_list_ident(&self) -> ast::path_list_ident {
|
||||
pub fn parse_path_list_ident(&mut self) -> ast::path_list_ident {
|
||||
let lo = self.span.lo;
|
||||
let ident = self.parse_ident();
|
||||
let hi = self.last_span.hi;
|
||||
@@ -519,20 +506,20 @@ pub fn parse_path_list_ident(&self) -> ast::path_list_ident {
|
||||
|
||||
// consume token 'tok' if it exists. Returns true if the given
|
||||
// token was present, false otherwise.
|
||||
pub fn eat(&self, tok: &token::Token) -> bool {
|
||||
let is_present = *self.token == *tok;
|
||||
pub fn eat(&mut self, tok: &token::Token) -> bool {
|
||||
let is_present = self.token == *tok;
|
||||
if is_present { self.bump() }
|
||||
is_present
|
||||
}
|
||||
|
||||
pub fn is_keyword(&self, kw: keywords::Keyword) -> bool {
|
||||
token::is_keyword(kw, self.token)
|
||||
pub fn is_keyword(&mut self, kw: keywords::Keyword) -> bool {
|
||||
token::is_keyword(kw, &self.token)
|
||||
}
|
||||
|
||||
// if the next token is the given keyword, eat it and return
|
||||
// true. Otherwise, return false.
|
||||
pub fn eat_keyword(&self, kw: keywords::Keyword) -> bool {
|
||||
let is_kw = match *self.token {
|
||||
pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
|
||||
let is_kw = match self.token {
|
||||
token::IDENT(sid, false) => kw.to_ident().name == sid.name,
|
||||
_ => false
|
||||
};
|
||||
@@ -543,59 +530,63 @@ pub fn eat_keyword(&self, kw: keywords::Keyword) -> bool {
|
||||
// if the given word is not a keyword, signal an error.
|
||||
// if the next token is not the given word, signal an error.
|
||||
// otherwise, eat it.
|
||||
pub fn expect_keyword(&self, kw: keywords::Keyword) {
|
||||
pub fn expect_keyword(&mut self, kw: keywords::Keyword) {
|
||||
if !self.eat_keyword(kw) {
|
||||
self.fatal(
|
||||
format!(
|
||||
"expected `{}`, found `{}`",
|
||||
self.id_to_str(kw.to_ident()).to_str(),
|
||||
self.this_token_to_str()
|
||||
)
|
||||
);
|
||||
let id_str = self.id_to_str(kw.to_ident()).to_str();
|
||||
let token_str = self.this_token_to_str();
|
||||
self.fatal(format!("expected `{}`, found `{}`",
|
||||
id_str,
|
||||
token_str))
|
||||
}
|
||||
}
|
||||
|
||||
// signal an error if the given string is a strict keyword
|
||||
pub fn check_strict_keywords(&self) {
|
||||
if token::is_strict_keyword(self.token) {
|
||||
self.span_err(*self.span,
|
||||
format!("found `{}` in ident position", self.this_token_to_str()));
|
||||
pub fn check_strict_keywords(&mut self) {
|
||||
if token::is_strict_keyword(&self.token) {
|
||||
let token_str = self.this_token_to_str();
|
||||
self.span_err(self.span,
|
||||
format!("found `{}` in ident position", token_str));
|
||||
}
|
||||
}
|
||||
|
||||
// signal an error if the current token is a reserved keyword
|
||||
pub fn check_reserved_keywords(&self) {
|
||||
if token::is_reserved_keyword(self.token) {
|
||||
self.fatal(format!("`{}` is a reserved keyword", self.this_token_to_str()));
|
||||
pub fn check_reserved_keywords(&mut self) {
|
||||
if token::is_reserved_keyword(&self.token) {
|
||||
let token_str = self.this_token_to_str();
|
||||
self.fatal(format!("`{}` is a reserved keyword", token_str))
|
||||
}
|
||||
}
|
||||
|
||||
// Expect and consume a `|`. If `||` is seen, replace it with a single
|
||||
// `|` and continue. If a `|` is not seen, signal an error.
|
||||
fn expect_or(&self) {
|
||||
match *self.token {
|
||||
fn expect_or(&mut self) {
|
||||
match self.token {
|
||||
token::BINOP(token::OR) => self.bump(),
|
||||
token::OROR => {
|
||||
self.replace_token(token::BINOP(token::OR),
|
||||
self.span.lo + BytePos(1),
|
||||
self.span.hi)
|
||||
let lo = self.span.lo + BytePos(1);
|
||||
self.replace_token(token::BINOP(token::OR), lo, self.span.hi)
|
||||
}
|
||||
_ => {
|
||||
let found_token = self.token_to_str(&token::BINOP(token::OR));
|
||||
let token_str = self.this_token_to_str();
|
||||
let found_token =
|
||||
Parser::token_to_str(&token::BINOP(token::OR));
|
||||
self.fatal(format!("expected `{}`, found `{}`",
|
||||
found_token,
|
||||
self.this_token_to_str()))
|
||||
token_str))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
|
||||
fn parse_seq_to_before_or<T>(&self, sep: &token::Token, f: |&Parser| -> T)
|
||||
fn parse_seq_to_before_or<T>(
|
||||
&mut self,
|
||||
sep: &token::Token,
|
||||
f: |&mut Parser| -> T)
|
||||
-> ~[T] {
|
||||
let mut first = true;
|
||||
let mut vector = ~[];
|
||||
while *self.token != token::BINOP(token::OR) &&
|
||||
*self.token != token::OROR {
|
||||
while self.token != token::BINOP(token::OR) &&
|
||||
self.token != token::OROR {
|
||||
if first {
|
||||
first = false
|
||||
} else {
|
||||
@@ -610,31 +601,34 @@ fn parse_seq_to_before_or<T>(&self, sep: &token::Token, f: |&Parser| -> T)
|
||||
// expect and consume a GT. if a >> is seen, replace it
|
||||
// with a single > and continue. If a GT is not seen,
|
||||
// signal an error.
|
||||
pub fn expect_gt(&self) {
|
||||
match *self.token {
|
||||
pub fn expect_gt(&mut self) {
|
||||
match self.token {
|
||||
token::GT => self.bump(),
|
||||
token::BINOP(token::SHR) => self.replace_token(
|
||||
token::GT,
|
||||
self.span.lo + BytePos(1),
|
||||
self.span.hi
|
||||
),
|
||||
_ => self.fatal(format!("expected `{}`, found `{}`",
|
||||
self.token_to_str(&token::GT),
|
||||
self.this_token_to_str()))
|
||||
token::BINOP(token::SHR) => {
|
||||
let lo = self.span.lo + BytePos(1);
|
||||
self.replace_token(token::GT, lo, self.span.hi)
|
||||
}
|
||||
_ => {
|
||||
let gt_str = Parser::token_to_str(&token::GT);
|
||||
let this_token_str = self.this_token_to_str();
|
||||
self.fatal(format!("expected `{}`, found `{}`",
|
||||
gt_str,
|
||||
this_token_str))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse a sequence bracketed by '<' and '>', stopping
|
||||
// before the '>'.
|
||||
pub fn parse_seq_to_before_gt<T>(
|
||||
&self,
|
||||
&mut self,
|
||||
sep: Option<token::Token>,
|
||||
f: |&Parser| -> T)
|
||||
f: |&mut Parser| -> T)
|
||||
-> OptVec<T> {
|
||||
let mut first = true;
|
||||
let mut v = opt_vec::Empty;
|
||||
while *self.token != token::GT
|
||||
&& *self.token != token::BINOP(token::SHR) {
|
||||
while self.token != token::GT
|
||||
&& self.token != token::BINOP(token::SHR) {
|
||||
match sep {
|
||||
Some(ref t) => {
|
||||
if first { first = false; }
|
||||
@@ -648,9 +642,9 @@ pub fn parse_seq_to_before_gt<T>(
|
||||
}
|
||||
|
||||
pub fn parse_seq_to_gt<T>(
|
||||
&self,
|
||||
&mut self,
|
||||
sep: Option<token::Token>,
|
||||
f: |&Parser| -> T)
|
||||
f: |&mut Parser| -> T)
|
||||
-> OptVec<T> {
|
||||
let v = self.parse_seq_to_before_gt(sep, f);
|
||||
self.expect_gt();
|
||||
@@ -661,10 +655,10 @@ pub fn parse_seq_to_gt<T>(
|
||||
// f must consume tokens until reaching the next separator or
|
||||
// closing bracket.
|
||||
pub fn parse_seq_to_end<T>(
|
||||
&self,
|
||||
&mut self,
|
||||
ket: &token::Token,
|
||||
sep: SeqSep,
|
||||
f: |&Parser| -> T)
|
||||
f: |&mut Parser| -> T)
|
||||
-> ~[T] {
|
||||
let val = self.parse_seq_to_before_end(ket, sep, f);
|
||||
self.bump();
|
||||
@@ -675,14 +669,14 @@ pub fn parse_seq_to_end<T>(
|
||||
// f must consume tokens until reaching the next separator or
|
||||
// closing bracket.
|
||||
pub fn parse_seq_to_before_end<T>(
|
||||
&self,
|
||||
&mut self,
|
||||
ket: &token::Token,
|
||||
sep: SeqSep,
|
||||
f: |&Parser| -> T)
|
||||
f: |&mut Parser| -> T)
|
||||
-> ~[T] {
|
||||
let mut first: bool = true;
|
||||
let mut v: ~[T] = ~[];
|
||||
while *self.token != *ket {
|
||||
while self.token != *ket {
|
||||
match sep.sep {
|
||||
Some(ref t) => {
|
||||
if first { first = false; }
|
||||
@@ -690,7 +684,7 @@ pub fn parse_seq_to_before_end<T>(
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
if sep.trailing_sep_allowed && *self.token == *ket { break; }
|
||||
if sep.trailing_sep_allowed && self.token == *ket { break; }
|
||||
v.push(f(self));
|
||||
}
|
||||
return v;
|
||||
@@ -700,11 +694,11 @@ pub fn parse_seq_to_before_end<T>(
|
||||
// f must consume tokens until reaching the next separator or
|
||||
// closing bracket.
|
||||
pub fn parse_unspanned_seq<T>(
|
||||
&self,
|
||||
&mut self,
|
||||
bra: &token::Token,
|
||||
ket: &token::Token,
|
||||
sep: SeqSep,
|
||||
f: |&Parser| -> T)
|
||||
f: |&mut Parser| -> T)
|
||||
-> ~[T] {
|
||||
self.expect(bra);
|
||||
let result = self.parse_seq_to_before_end(ket, sep, f);
|
||||
@@ -715,11 +709,11 @@ pub fn parse_unspanned_seq<T>(
|
||||
// NB: Do not use this function unless you actually plan to place the
|
||||
// spanned list in the AST.
|
||||
pub fn parse_seq<T>(
|
||||
&self,
|
||||
&mut self,
|
||||
bra: &token::Token,
|
||||
ket: &token::Token,
|
||||
sep: SeqSep,
|
||||
f: |&Parser| -> T)
|
||||
f: |&mut Parser| -> T)
|
||||
-> Spanned<~[T]> {
|
||||
let lo = self.span.lo;
|
||||
self.expect(bra);
|
||||
@@ -730,98 +724,98 @@ pub fn parse_seq<T>(
|
||||
}
|
||||
|
||||
// advance the parser by one token
|
||||
pub fn bump(&self) {
|
||||
*self.last_span = *self.span;
|
||||
pub fn bump(&mut self) {
|
||||
self.last_span = self.span;
|
||||
// Stash token for error recovery (sometimes; clone is not necessarily cheap).
|
||||
*self.last_token = if is_ident_or_path(self.token) {
|
||||
Some(~(*self.token).clone())
|
||||
self.last_token = if is_ident_or_path(&self.token) {
|
||||
Some(~self.token.clone())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let next = if *self.buffer_start == *self.buffer_end {
|
||||
let next = if self.buffer_start == self.buffer_end {
|
||||
self.reader.next_token()
|
||||
} else {
|
||||
// Avoid token copies with `util::replace`.
|
||||
let buffer_start = *self.buffer_start as uint;
|
||||
let buffer_start = self.buffer_start as uint;
|
||||
let next_index = (buffer_start + 1) & 3 as uint;
|
||||
*self.buffer_start = next_index as int;
|
||||
self.buffer_start = next_index as int;
|
||||
|
||||
let placeholder = TokenAndSpan {
|
||||
tok: token::UNDERSCORE,
|
||||
sp: *self.span,
|
||||
sp: self.span,
|
||||
};
|
||||
util::replace(&mut self.buffer[buffer_start], placeholder)
|
||||
};
|
||||
*self.span = next.sp;
|
||||
*self.token = next.tok;
|
||||
*self.tokens_consumed += 1u;
|
||||
self.span = next.sp;
|
||||
self.token = next.tok;
|
||||
self.tokens_consumed += 1u;
|
||||
}
|
||||
|
||||
// Advance the parser by one token and return the bumped token.
|
||||
pub fn bump_and_get(&self) -> token::Token {
|
||||
let old_token = util::replace(self.token, token::UNDERSCORE);
|
||||
pub fn bump_and_get(&mut self) -> token::Token {
|
||||
let old_token = util::replace(&mut self.token, token::UNDERSCORE);
|
||||
self.bump();
|
||||
old_token
|
||||
}
|
||||
|
||||
// EFFECT: replace the current token and span with the given one
|
||||
pub fn replace_token(&self,
|
||||
pub fn replace_token(&mut self,
|
||||
next: token::Token,
|
||||
lo: BytePos,
|
||||
hi: BytePos) {
|
||||
*self.token = next;
|
||||
*self.span = mk_sp(lo, hi);
|
||||
self.token = next;
|
||||
self.span = mk_sp(lo, hi);
|
||||
}
|
||||
pub fn buffer_length(&self) -> int {
|
||||
if *self.buffer_start <= *self.buffer_end {
|
||||
return *self.buffer_end - *self.buffer_start;
|
||||
pub fn buffer_length(&mut self) -> int {
|
||||
if self.buffer_start <= self.buffer_end {
|
||||
return self.buffer_end - self.buffer_start;
|
||||
}
|
||||
return (4 - *self.buffer_start) + *self.buffer_end;
|
||||
return (4 - self.buffer_start) + self.buffer_end;
|
||||
}
|
||||
pub fn look_ahead<R>(&self, distance: uint, f: |&token::Token| -> R)
|
||||
pub fn look_ahead<R>(&mut self, distance: uint, f: |&token::Token| -> R)
|
||||
-> R {
|
||||
let dist = distance as int;
|
||||
while self.buffer_length() < dist {
|
||||
self.buffer[*self.buffer_end] = self.reader.next_token();
|
||||
*self.buffer_end = (*self.buffer_end + 1) & 3;
|
||||
self.buffer[self.buffer_end] = self.reader.next_token();
|
||||
self.buffer_end = (self.buffer_end + 1) & 3;
|
||||
}
|
||||
f(&self.buffer[(*self.buffer_start + dist - 1) & 3].tok)
|
||||
f(&self.buffer[(self.buffer_start + dist - 1) & 3].tok)
|
||||
}
|
||||
pub fn fatal(&self, m: &str) -> ! {
|
||||
self.sess.span_diagnostic.span_fatal(*self.span, m)
|
||||
pub fn fatal(&mut self, m: &str) -> ! {
|
||||
self.sess.span_diagnostic.span_fatal(self.span, m)
|
||||
}
|
||||
pub fn span_fatal(&self, sp: Span, m: &str) -> ! {
|
||||
pub fn span_fatal(&mut self, sp: Span, m: &str) -> ! {
|
||||
self.sess.span_diagnostic.span_fatal(sp, m)
|
||||
}
|
||||
pub fn span_note(&self, sp: Span, m: &str) {
|
||||
pub fn span_note(&mut self, sp: Span, m: &str) {
|
||||
self.sess.span_diagnostic.span_note(sp, m)
|
||||
}
|
||||
pub fn bug(&self, m: &str) -> ! {
|
||||
self.sess.span_diagnostic.span_bug(*self.span, m)
|
||||
pub fn bug(&mut self, m: &str) -> ! {
|
||||
self.sess.span_diagnostic.span_bug(self.span, m)
|
||||
}
|
||||
pub fn warn(&self, m: &str) {
|
||||
self.sess.span_diagnostic.span_warn(*self.span, m)
|
||||
pub fn warn(&mut self, m: &str) {
|
||||
self.sess.span_diagnostic.span_warn(self.span, m)
|
||||
}
|
||||
pub fn span_err(&self, sp: Span, m: &str) {
|
||||
pub fn span_err(&mut self, sp: Span, m: &str) {
|
||||
self.sess.span_diagnostic.span_err(sp, m)
|
||||
}
|
||||
pub fn abort_if_errors(&self) {
|
||||
pub fn abort_if_errors(&mut self) {
|
||||
self.sess.span_diagnostic.handler().abort_if_errors();
|
||||
}
|
||||
|
||||
pub fn id_to_str(&self, id: Ident) -> @str {
|
||||
pub fn id_to_str(&mut self, id: Ident) -> @str {
|
||||
get_ident_interner().get(id.name)
|
||||
}
|
||||
|
||||
// Is the current token one of the keywords that signals a bare function
|
||||
// type?
|
||||
pub fn token_is_bare_fn_keyword(&self) -> bool {
|
||||
if token::is_keyword(keywords::Fn, self.token) {
|
||||
pub fn token_is_bare_fn_keyword(&mut self) -> bool {
|
||||
if token::is_keyword(keywords::Fn, &self.token) {
|
||||
return true
|
||||
}
|
||||
|
||||
if token::is_keyword(keywords::Unsafe, self.token) ||
|
||||
token::is_keyword(keywords::Once, self.token) {
|
||||
if token::is_keyword(keywords::Unsafe, &self.token) ||
|
||||
token::is_keyword(keywords::Once, &self.token) {
|
||||
return self.look_ahead(1, |t| token::is_keyword(keywords::Fn, t))
|
||||
}
|
||||
|
||||
@@ -829,35 +823,35 @@ pub fn token_is_bare_fn_keyword(&self) -> bool {
|
||||
}
|
||||
|
||||
// Is the current token one of the keywords that signals a closure type?
|
||||
pub fn token_is_closure_keyword(&self) -> bool {
|
||||
token::is_keyword(keywords::Unsafe, self.token) ||
|
||||
token::is_keyword(keywords::Once, self.token)
|
||||
pub fn token_is_closure_keyword(&mut self) -> bool {
|
||||
token::is_keyword(keywords::Unsafe, &self.token) ||
|
||||
token::is_keyword(keywords::Once, &self.token)
|
||||
}
|
||||
|
||||
// Is the current token one of the keywords that signals an old-style
|
||||
// closure type (with explicit sigil)?
|
||||
pub fn token_is_old_style_closure_keyword(&self) -> bool {
|
||||
token::is_keyword(keywords::Unsafe, self.token) ||
|
||||
token::is_keyword(keywords::Once, self.token) ||
|
||||
token::is_keyword(keywords::Fn, self.token)
|
||||
pub fn token_is_old_style_closure_keyword(&mut self) -> bool {
|
||||
token::is_keyword(keywords::Unsafe, &self.token) ||
|
||||
token::is_keyword(keywords::Once, &self.token) ||
|
||||
token::is_keyword(keywords::Fn, &self.token)
|
||||
}
|
||||
|
||||
pub fn token_is_lifetime(&self, tok: &token::Token) -> bool {
|
||||
pub fn token_is_lifetime(tok: &token::Token) -> bool {
|
||||
match *tok {
|
||||
token::LIFETIME(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_lifetime(&self, tok: &token::Token) -> ast::Ident {
|
||||
match *tok {
|
||||
pub fn get_lifetime(&mut self) -> ast::Ident {
|
||||
match self.token {
|
||||
token::LIFETIME(ref ident) => *ident,
|
||||
_ => self.bug("not a lifetime"),
|
||||
}
|
||||
}
|
||||
|
||||
// parse a ty_bare_fun type:
|
||||
pub fn parse_ty_bare_fn(&self) -> ty_ {
|
||||
pub fn parse_ty_bare_fn(&mut self) -> ty_ {
|
||||
/*
|
||||
|
||||
[extern "ABI"] [unsafe] fn <'lt> (S) -> T
|
||||
@@ -887,7 +881,7 @@ pub fn parse_ty_bare_fn(&self) -> ty_ {
|
||||
|
||||
// Parses a procedure type (`proc`). The initial `proc` keyword must
|
||||
// already have been parsed.
|
||||
pub fn parse_proc_type(&self) -> ty_ {
|
||||
pub fn parse_proc_type(&mut self) -> ty_ {
|
||||
let (decl, lifetimes) = self.parse_ty_fn_decl(false);
|
||||
ty_closure(@TyClosure {
|
||||
sigil: OwnedSigil,
|
||||
@@ -901,7 +895,7 @@ pub fn parse_proc_type(&self) -> ty_ {
|
||||
}
|
||||
|
||||
// parse a ty_closure type
|
||||
pub fn parse_ty_closure(&self,
|
||||
pub fn parse_ty_closure(&mut self,
|
||||
opt_sigil: Option<ast::Sigil>,
|
||||
mut region: Option<ast::Lifetime>)
|
||||
-> ty_ {
|
||||
@@ -943,7 +937,7 @@ pub fn parse_ty_closure(&self,
|
||||
|
||||
// Re-parse the region here. What a hack.
|
||||
if region.is_some() {
|
||||
self.span_err(*self.last_span,
|
||||
self.span_err(self.last_span,
|
||||
"lifetime declarations must precede \
|
||||
the lifetime associated with a \
|
||||
closure");
|
||||
@@ -990,7 +984,7 @@ pub fn parse_ty_closure(&self,
|
||||
lifetimes: lifetimes,
|
||||
});
|
||||
|
||||
fn parse_onceness(this: &Parser) -> Onceness {
|
||||
fn parse_onceness(this: &mut Parser) -> Onceness {
|
||||
if this.eat_keyword(keywords::Once) {
|
||||
Once
|
||||
} else {
|
||||
@@ -999,7 +993,7 @@ fn parse_onceness(this: &Parser) -> Onceness {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_unsafety(&self) -> purity {
|
||||
pub fn parse_unsafety(&mut self) -> purity {
|
||||
if self.eat_keyword(keywords::Unsafe) {
|
||||
return unsafe_fn;
|
||||
} else {
|
||||
@@ -1008,7 +1002,8 @@ pub fn parse_unsafety(&self) -> purity {
|
||||
}
|
||||
|
||||
// parse a function type (following the 'fn')
|
||||
pub fn parse_ty_fn_decl(&self, allow_variadic: bool) -> (P<fn_decl>, OptVec<ast::Lifetime>) {
|
||||
pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool)
|
||||
-> (P<fn_decl>, OptVec<ast::Lifetime>) {
|
||||
/*
|
||||
|
||||
(fn) <'lt> (S) -> T
|
||||
@@ -1039,7 +1034,7 @@ pub fn parse_ty_fn_decl(&self, allow_variadic: bool) -> (P<fn_decl>, OptVec<ast:
|
||||
}
|
||||
|
||||
// parse the methods in a trait declaration
|
||||
pub fn parse_trait_methods(&self) -> ~[trait_method] {
|
||||
pub fn parse_trait_methods(&mut self) -> ~[trait_method] {
|
||||
self.parse_unspanned_seq(
|
||||
&token::LBRACE,
|
||||
&token::RBRACE,
|
||||
@@ -1048,7 +1043,7 @@ pub fn parse_trait_methods(&self) -> ~[trait_method] {
|
||||
let attrs = p.parse_outer_attributes();
|
||||
let lo = p.span.lo;
|
||||
|
||||
let vis_span = *self.span;
|
||||
let vis_span = p.span;
|
||||
let vis = p.parse_visibility();
|
||||
let pur = p.parse_fn_purity();
|
||||
// NB: at the moment, trait methods are public by default; this
|
||||
@@ -1057,25 +1052,21 @@ pub fn parse_trait_methods(&self) -> ~[trait_method] {
|
||||
|
||||
let generics = p.parse_generics();
|
||||
|
||||
let (explicit_self, d) = self.parse_fn_decl_with_self(|p| {
|
||||
let (explicit_self, d) = p.parse_fn_decl_with_self(|p| {
|
||||
// This is somewhat dubious; We don't want to allow argument
|
||||
// names to be left off if there is a definition...
|
||||
p.parse_arg_general(false)
|
||||
});
|
||||
|
||||
let hi = p.last_span.hi;
|
||||
debug!("parse_trait_methods(): trait method signature ends in \
|
||||
`{}`",
|
||||
self.this_token_to_str());
|
||||
match *p.token {
|
||||
match p.token {
|
||||
token::SEMI => {
|
||||
p.bump();
|
||||
debug!("parse_trait_methods(): parsing required method");
|
||||
// NB: at the moment, visibility annotations on required
|
||||
// methods are ignored; this could change.
|
||||
if vis != ast::inherited {
|
||||
self.obsolete(vis_span,
|
||||
ObsoleteTraitFuncVisibility);
|
||||
p.obsolete(vis_span, ObsoleteTraitFuncVisibility);
|
||||
}
|
||||
required(TypeMethod {
|
||||
ident: ident,
|
||||
@@ -1109,19 +1100,16 @@ pub fn parse_trait_methods(&self) -> ~[trait_method] {
|
||||
}
|
||||
|
||||
_ => {
|
||||
p.fatal(
|
||||
format!(
|
||||
"expected `;` or `\\{` but found `{}`",
|
||||
self.this_token_to_str()
|
||||
)
|
||||
);
|
||||
}
|
||||
let token_str = p.this_token_to_str();
|
||||
p.fatal(format!("expected `;` or `\\{` but found `{}`",
|
||||
token_str))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// parse a possibly mutable type
|
||||
pub fn parse_mt(&self) -> mt {
|
||||
pub fn parse_mt(&mut self) -> mt {
|
||||
let mutbl = self.parse_mutability();
|
||||
let t = self.parse_ty(false);
|
||||
mt { ty: t, mutbl: mutbl }
|
||||
@@ -1129,7 +1117,7 @@ pub fn parse_mt(&self) -> mt {
|
||||
|
||||
// parse [mut/const/imm] ID : TY
|
||||
// now used only by obsolete record syntax parser...
|
||||
pub fn parse_ty_field(&self) -> TypeField {
|
||||
pub fn parse_ty_field(&mut self) -> TypeField {
|
||||
let lo = self.span.lo;
|
||||
let mutbl = self.parse_mutability();
|
||||
let id = self.parse_ident();
|
||||
@@ -1144,7 +1132,7 @@ pub fn parse_ty_field(&self) -> TypeField {
|
||||
}
|
||||
|
||||
// parse optional return type [ -> TY ] in function decl
|
||||
pub fn parse_ret_ty(&self) -> (ret_style, P<Ty>) {
|
||||
pub fn parse_ret_ty(&mut self) -> (ret_style, P<Ty>) {
|
||||
return if self.eat(&token::RARROW) {
|
||||
let lo = self.span.lo;
|
||||
if self.eat(&token::NOT) {
|
||||
@@ -1175,14 +1163,14 @@ pub fn parse_ret_ty(&self) -> (ret_style, P<Ty>) {
|
||||
// parse a type.
|
||||
// Useless second parameter for compatibility with quasiquote macros.
|
||||
// Bleh!
|
||||
pub fn parse_ty(&self, _: bool) -> P<Ty> {
|
||||
pub fn parse_ty(&mut self, _: bool) -> P<Ty> {
|
||||
maybe_whole!(no_clone self, nt_ty);
|
||||
|
||||
let lo = self.span.lo;
|
||||
|
||||
let t = if *self.token == token::LPAREN {
|
||||
let t = if self.token == token::LPAREN {
|
||||
self.bump();
|
||||
if *self.token == token::RPAREN {
|
||||
if self.token == token::RPAREN {
|
||||
self.bump();
|
||||
ty_nil
|
||||
} else {
|
||||
@@ -1191,9 +1179,9 @@ pub fn parse_ty(&self, _: bool) -> P<Ty> {
|
||||
// of type t
|
||||
let mut ts = ~[self.parse_ty(false)];
|
||||
let mut one_tuple = false;
|
||||
while *self.token == token::COMMA {
|
||||
while self.token == token::COMMA {
|
||||
self.bump();
|
||||
if *self.token != token::RPAREN {
|
||||
if self.token != token::RPAREN {
|
||||
ts.push(self.parse_ty(false));
|
||||
}
|
||||
else {
|
||||
@@ -1210,19 +1198,19 @@ pub fn parse_ty(&self, _: bool) -> P<Ty> {
|
||||
self.expect(&token::RPAREN);
|
||||
t
|
||||
}
|
||||
} else if *self.token == token::AT {
|
||||
} else if self.token == token::AT {
|
||||
// MANAGED POINTER
|
||||
self.bump();
|
||||
self.parse_box_or_uniq_pointee(ManagedSigil)
|
||||
} else if *self.token == token::TILDE {
|
||||
} else if self.token == token::TILDE {
|
||||
// OWNED POINTER
|
||||
self.bump();
|
||||
self.parse_box_or_uniq_pointee(OwnedSigil)
|
||||
} else if *self.token == token::BINOP(token::STAR) {
|
||||
} else if self.token == token::BINOP(token::STAR) {
|
||||
// STAR POINTER (bare pointer?)
|
||||
self.bump();
|
||||
ty_ptr(self.parse_mt())
|
||||
} else if *self.token == token::LBRACKET {
|
||||
} else if self.token == token::LBRACKET {
|
||||
// VECTOR
|
||||
self.expect(&token::LBRACKET);
|
||||
let t = self.parse_ty(false);
|
||||
@@ -1235,7 +1223,7 @@ pub fn parse_ty(&self, _: bool) -> P<Ty> {
|
||||
};
|
||||
self.expect(&token::RBRACKET);
|
||||
t
|
||||
} else if *self.token == token::BINOP(token::AND) {
|
||||
} else if self.token == token::BINOP(token::AND) {
|
||||
// BORROWED POINTER
|
||||
self.bump();
|
||||
self.parse_borrowed_pointee()
|
||||
@@ -1244,10 +1232,10 @@ pub fn parse_ty(&self, _: bool) -> P<Ty> {
|
||||
// BARE FUNCTION
|
||||
self.parse_ty_bare_fn()
|
||||
} else if self.token_is_closure_keyword() ||
|
||||
*self.token == token::BINOP(token::OR) ||
|
||||
*self.token == token::OROR ||
|
||||
*self.token == token::LT ||
|
||||
self.token_is_lifetime(self.token) {
|
||||
self.token == token::BINOP(token::OR) ||
|
||||
self.token == token::OROR ||
|
||||
self.token == token::LT ||
|
||||
Parser::token_is_lifetime(&self.token) {
|
||||
// CLOSURE
|
||||
//
|
||||
// XXX(pcwalton): Eventually `token::LT` will not unambiguously
|
||||
@@ -1266,8 +1254,8 @@ pub fn parse_ty(&self, _: bool) -> P<Ty> {
|
||||
ty_typeof(e)
|
||||
} else if self.eat_keyword(keywords::Proc) {
|
||||
self.parse_proc_type()
|
||||
} else if *self.token == token::MOD_SEP
|
||||
|| is_ident_or_path(self.token) {
|
||||
} else if self.token == token::MOD_SEP
|
||||
|| is_ident_or_path(&self.token) {
|
||||
// NAMED TYPE
|
||||
let PathAndBounds {
|
||||
path,
|
||||
@@ -1275,7 +1263,8 @@ pub fn parse_ty(&self, _: bool) -> P<Ty> {
|
||||
} = self.parse_path(LifetimeAndTypesAndBounds);
|
||||
ty_path(path, bounds, ast::DUMMY_NODE_ID)
|
||||
} else {
|
||||
self.fatal(format!("expected type, found token {:?}", *self.token));
|
||||
let msg = format!("expected type, found token {:?}", self.token);
|
||||
self.fatal(msg);
|
||||
};
|
||||
|
||||
let sp = mk_sp(lo, self.last_span.hi);
|
||||
@@ -1283,20 +1272,20 @@ pub fn parse_ty(&self, _: bool) -> P<Ty> {
|
||||
}
|
||||
|
||||
// parse the type following a @ or a ~
|
||||
pub fn parse_box_or_uniq_pointee(&self,
|
||||
pub fn parse_box_or_uniq_pointee(&mut self,
|
||||
sigil: ast::Sigil)
|
||||
-> ty_ {
|
||||
// ~'foo fn() or ~fn() are parsed directly as obsolete fn types:
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::LIFETIME(..) => {
|
||||
let lifetime = self.parse_lifetime();
|
||||
self.obsolete(*self.last_span, ObsoleteBoxedClosure);
|
||||
self.obsolete(self.last_span, ObsoleteBoxedClosure);
|
||||
return self.parse_ty_closure(Some(sigil), Some(lifetime));
|
||||
}
|
||||
|
||||
token::IDENT(..) => {
|
||||
if self.token_is_old_style_closure_keyword() {
|
||||
self.obsolete(*self.last_span, ObsoleteBoxedClosure);
|
||||
self.obsolete(self.last_span, ObsoleteBoxedClosure);
|
||||
return self.parse_ty_closure(Some(sigil), None);
|
||||
}
|
||||
}
|
||||
@@ -1314,12 +1303,12 @@ pub fn parse_box_or_uniq_pointee(&self,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_borrowed_pointee(&self) -> ty_ {
|
||||
pub fn parse_borrowed_pointee(&mut self) -> ty_ {
|
||||
// look for `&'lt` or `&'foo ` and interpret `foo` as the region name:
|
||||
let opt_lifetime = self.parse_opt_lifetime();
|
||||
|
||||
if self.token_is_old_style_closure_keyword() {
|
||||
self.obsolete(*self.last_span, ObsoleteClosureType);
|
||||
self.obsolete(self.last_span, ObsoleteClosureType);
|
||||
return self.parse_ty_closure(Some(BorrowedSigil), opt_lifetime);
|
||||
}
|
||||
|
||||
@@ -1327,18 +1316,18 @@ pub fn parse_borrowed_pointee(&self) -> ty_ {
|
||||
return ty_rptr(opt_lifetime, mt);
|
||||
}
|
||||
|
||||
pub fn is_named_argument(&self) -> bool {
|
||||
let offset = match *self.token {
|
||||
pub fn is_named_argument(&mut self) -> bool {
|
||||
let offset = match self.token {
|
||||
token::BINOP(token::AND) => 1,
|
||||
token::ANDAND => 1,
|
||||
_ if token::is_keyword(keywords::Mut, self.token) => 1,
|
||||
_ if token::is_keyword(keywords::Mut, &self.token) => 1,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
debug!("parser is_named_argument offset:{}", offset);
|
||||
|
||||
if offset == 0 {
|
||||
is_plain_ident_or_underscore(&*self.token)
|
||||
is_plain_ident_or_underscore(&self.token)
|
||||
&& self.look_ahead(1, |t| *t == token::COLON)
|
||||
} else {
|
||||
self.look_ahead(offset, |t| is_plain_ident_or_underscore(t))
|
||||
@@ -1348,7 +1337,7 @@ pub fn is_named_argument(&self) -> bool {
|
||||
|
||||
// This version of parse arg doesn't necessarily require
|
||||
// identifier names.
|
||||
pub fn parse_arg_general(&self, require_name: bool) -> arg {
|
||||
pub fn parse_arg_general(&mut self, require_name: bool) -> arg {
|
||||
let pat = if require_name || self.is_named_argument() {
|
||||
debug!("parse_arg_general parse_pat (require_name:{:?})",
|
||||
require_name);
|
||||
@@ -1359,7 +1348,7 @@ pub fn parse_arg_general(&self, require_name: bool) -> arg {
|
||||
} else {
|
||||
debug!("parse_arg_general ident_to_pat");
|
||||
ast_util::ident_to_pat(ast::DUMMY_NODE_ID,
|
||||
*self.last_span,
|
||||
self.last_span,
|
||||
special_idents::invalid)
|
||||
};
|
||||
|
||||
@@ -1373,12 +1362,12 @@ pub fn parse_arg_general(&self, require_name: bool) -> arg {
|
||||
}
|
||||
|
||||
// parse a single function argument
|
||||
pub fn parse_arg(&self) -> arg {
|
||||
pub fn parse_arg(&mut self) -> arg {
|
||||
self.parse_arg_general(true)
|
||||
}
|
||||
|
||||
// parse an argument in a lambda header e.g. |arg, arg|
|
||||
pub fn parse_fn_block_arg(&self) -> arg {
|
||||
pub fn parse_fn_block_arg(&mut self) -> arg {
|
||||
let pat = self.parse_pat();
|
||||
let t = if self.eat(&token::COLON) {
|
||||
self.parse_ty(false)
|
||||
@@ -1396,8 +1385,8 @@ pub fn parse_fn_block_arg(&self) -> arg {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn maybe_parse_fixed_vstore(&self) -> Option<@ast::Expr> {
|
||||
if *self.token == token::COMMA &&
|
||||
pub fn maybe_parse_fixed_vstore(&mut self) -> Option<@ast::Expr> {
|
||||
if self.token == token::COMMA &&
|
||||
self.look_ahead(1, |t| *t == token::DOTDOT) {
|
||||
self.bump();
|
||||
self.bump();
|
||||
@@ -1408,7 +1397,7 @@ pub fn maybe_parse_fixed_vstore(&self) -> Option<@ast::Expr> {
|
||||
}
|
||||
|
||||
// matches token_lit = LIT_INT | ...
|
||||
pub fn lit_from_token(&self, tok: &token::Token) -> lit_ {
|
||||
pub fn lit_from_token(&mut self, tok: &token::Token) -> lit_ {
|
||||
match *tok {
|
||||
token::LIT_CHAR(i) => lit_char(i),
|
||||
token::LIT_INT(i, it) => lit_int(i, it),
|
||||
@@ -1425,7 +1414,7 @@ pub fn lit_from_token(&self, tok: &token::Token) -> lit_ {
|
||||
}
|
||||
|
||||
// matches lit = true | false | token_lit
|
||||
pub fn parse_lit(&self) -> lit {
|
||||
pub fn parse_lit(&mut self) -> lit {
|
||||
let lo = self.span.lo;
|
||||
let lit = if self.eat_keyword(keywords::True) {
|
||||
lit_bool(true)
|
||||
@@ -1440,7 +1429,7 @@ pub fn parse_lit(&self) -> lit {
|
||||
}
|
||||
|
||||
// matches '-' lit | lit
|
||||
pub fn parse_literal_maybe_minus(&self) -> @Expr {
|
||||
pub fn parse_literal_maybe_minus(&mut self) -> @Expr {
|
||||
let minus_lo = self.span.lo;
|
||||
let minus_present = self.eat(&token::BINOP(token::MINUS));
|
||||
|
||||
@@ -1451,7 +1440,8 @@ pub fn parse_literal_maybe_minus(&self) -> @Expr {
|
||||
|
||||
if minus_present {
|
||||
let minus_hi = self.span.hi;
|
||||
self.mk_expr(minus_lo, minus_hi, self.mk_unary(UnNeg, expr))
|
||||
let unary = self.mk_unary(UnNeg, expr);
|
||||
self.mk_expr(minus_lo, minus_hi, unary)
|
||||
} else {
|
||||
expr
|
||||
}
|
||||
@@ -1461,9 +1451,9 @@ pub fn parse_literal_maybe_minus(&self) -> @Expr {
|
||||
/// mode. The `mode` parameter determines whether lifetimes, types, and/or
|
||||
/// bounds are permitted and whether `::` must precede type parameter
|
||||
/// groups.
|
||||
pub fn parse_path(&self, mode: PathParsingMode) -> PathAndBounds {
|
||||
pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds {
|
||||
// Check for a whole path...
|
||||
let found = match *self.token {
|
||||
let found = match self.token {
|
||||
INTERPOLATED(token::nt_path(_)) => Some(self.bump_and_get()),
|
||||
_ => None,
|
||||
};
|
||||
@@ -1580,8 +1570,8 @@ pub fn parse_path(&self, mode: PathParsingMode) -> PathAndBounds {
|
||||
}
|
||||
|
||||
/// parses 0 or 1 lifetime
|
||||
pub fn parse_opt_lifetime(&self) -> Option<ast::Lifetime> {
|
||||
match *self.token {
|
||||
pub fn parse_opt_lifetime(&mut self) -> Option<ast::Lifetime> {
|
||||
match self.token {
|
||||
token::LIFETIME(..) => {
|
||||
Some(self.parse_lifetime())
|
||||
}
|
||||
@@ -1593,10 +1583,10 @@ pub fn parse_opt_lifetime(&self) -> Option<ast::Lifetime> {
|
||||
|
||||
/// Parses a single lifetime
|
||||
// matches lifetime = LIFETIME
|
||||
pub fn parse_lifetime(&self) -> ast::Lifetime {
|
||||
match *self.token {
|
||||
pub fn parse_lifetime(&mut self) -> ast::Lifetime {
|
||||
match self.token {
|
||||
token::LIFETIME(i) => {
|
||||
let span = *self.span;
|
||||
let span = self.span;
|
||||
self.bump();
|
||||
return ast::Lifetime {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
@@ -1613,7 +1603,7 @@ pub fn parse_lifetime(&self) -> ast::Lifetime {
|
||||
// matches lifetimes = ( lifetime ) | ( lifetime , lifetimes )
|
||||
// actually, it matches the empty one too, but putting that in there
|
||||
// messes up the grammar....
|
||||
pub fn parse_lifetimes(&self) -> OptVec<ast::Lifetime> {
|
||||
pub fn parse_lifetimes(&mut self) -> OptVec<ast::Lifetime> {
|
||||
/*!
|
||||
*
|
||||
* Parses zero or more comma separated lifetimes.
|
||||
@@ -1624,7 +1614,7 @@ pub fn parse_lifetimes(&self) -> OptVec<ast::Lifetime> {
|
||||
|
||||
let mut res = opt_vec::Empty;
|
||||
loop {
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::LIFETIME(_) => {
|
||||
res.push(self.parse_lifetime());
|
||||
}
|
||||
@@ -1633,29 +1623,31 @@ pub fn parse_lifetimes(&self) -> OptVec<ast::Lifetime> {
|
||||
}
|
||||
}
|
||||
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::COMMA => { self.bump();}
|
||||
token::GT => { return res; }
|
||||
token::BINOP(token::SHR) => { return res; }
|
||||
_ => {
|
||||
self.fatal(format!("expected `,` or `>` after lifetime name, got: {:?}",
|
||||
*self.token));
|
||||
let msg = format!("expected `,` or `>` after lifetime \
|
||||
name, got: {:?}",
|
||||
self.token);
|
||||
self.fatal(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn token_is_mutability(&self, tok: &token::Token) -> bool {
|
||||
pub fn token_is_mutability(tok: &token::Token) -> bool {
|
||||
token::is_keyword(keywords::Mut, tok) ||
|
||||
token::is_keyword(keywords::Const, tok)
|
||||
}
|
||||
|
||||
// parse mutability declaration (mut/const/imm)
|
||||
pub fn parse_mutability(&self) -> Mutability {
|
||||
pub fn parse_mutability(&mut self) -> Mutability {
|
||||
if self.eat_keyword(keywords::Mut) {
|
||||
MutMutable
|
||||
} else if self.eat_keyword(keywords::Const) {
|
||||
self.obsolete(*self.last_span, ObsoleteConstPointer);
|
||||
self.obsolete(self.last_span, ObsoleteConstPointer);
|
||||
MutImmutable
|
||||
} else {
|
||||
MutImmutable
|
||||
@@ -1663,7 +1655,7 @@ pub fn parse_mutability(&self) -> Mutability {
|
||||
}
|
||||
|
||||
// parse ident COLON expr
|
||||
pub fn parse_field(&self) -> Field {
|
||||
pub fn parse_field(&mut self) -> Field {
|
||||
let lo = self.span.lo;
|
||||
let i = self.parse_ident();
|
||||
let hi = self.last_span.hi;
|
||||
@@ -1676,7 +1668,7 @@ pub fn parse_field(&self) -> Field {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mk_expr(&self, lo: BytePos, hi: BytePos, node: Expr_) -> @Expr {
|
||||
pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, node: Expr_) -> @Expr {
|
||||
@Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: node,
|
||||
@@ -1684,19 +1676,19 @@ pub fn mk_expr(&self, lo: BytePos, hi: BytePos, node: Expr_) -> @Expr {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mk_unary(&self, unop: ast::UnOp, expr: @Expr) -> ast::Expr_ {
|
||||
pub fn mk_unary(&mut self, unop: ast::UnOp, expr: @Expr) -> ast::Expr_ {
|
||||
ExprUnary(ast::DUMMY_NODE_ID, unop, expr)
|
||||
}
|
||||
|
||||
pub fn mk_binary(&self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
|
||||
pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
|
||||
ExprBinary(ast::DUMMY_NODE_ID, binop, lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn mk_call(&self, f: @Expr, args: ~[@Expr], sugar: CallSugar) -> ast::Expr_ {
|
||||
pub fn mk_call(&mut self, f: @Expr, args: ~[@Expr], sugar: CallSugar) -> ast::Expr_ {
|
||||
ExprCall(f, args, sugar)
|
||||
}
|
||||
|
||||
pub fn mk_method_call(&self,
|
||||
pub fn mk_method_call(&mut self,
|
||||
rcvr: @Expr,
|
||||
ident: Ident,
|
||||
tps: ~[P<Ty>],
|
||||
@@ -1705,19 +1697,19 @@ pub fn mk_method_call(&self,
|
||||
ExprMethodCall(ast::DUMMY_NODE_ID, rcvr, ident, tps, args, sugar)
|
||||
}
|
||||
|
||||
pub fn mk_index(&self, expr: @Expr, idx: @Expr) -> ast::Expr_ {
|
||||
pub fn mk_index(&mut self, expr: @Expr, idx: @Expr) -> ast::Expr_ {
|
||||
ExprIndex(ast::DUMMY_NODE_ID, expr, idx)
|
||||
}
|
||||
|
||||
pub fn mk_field(&self, expr: @Expr, ident: Ident, tys: ~[P<Ty>]) -> ast::Expr_ {
|
||||
pub fn mk_field(&mut self, expr: @Expr, ident: Ident, tys: ~[P<Ty>]) -> ast::Expr_ {
|
||||
ExprField(expr, ident, tys)
|
||||
}
|
||||
|
||||
pub fn mk_assign_op(&self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
|
||||
pub fn mk_assign_op(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
|
||||
ExprAssignOp(ast::DUMMY_NODE_ID, binop, lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn mk_mac_expr(&self, lo: BytePos, hi: BytePos, m: mac_) -> @Expr {
|
||||
pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: mac_) -> @Expr {
|
||||
@Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ExprMac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}),
|
||||
@@ -1725,8 +1717,8 @@ pub fn mk_mac_expr(&self, lo: BytePos, hi: BytePos, m: mac_) -> @Expr {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mk_lit_u32(&self, i: u32) -> @Expr {
|
||||
let span = self.span;
|
||||
pub fn mk_lit_u32(&mut self, i: u32) -> @Expr {
|
||||
let span = &self.span;
|
||||
let lv_lit = @codemap::Spanned {
|
||||
node: lit_uint(i as u64, ty_u32),
|
||||
span: *span
|
||||
@@ -1742,7 +1734,7 @@ pub fn mk_lit_u32(&self, i: u32) -> @Expr {
|
||||
// at the bottom (top?) of the precedence hierarchy,
|
||||
// parse things like parenthesized exprs,
|
||||
// macros, return, etc.
|
||||
pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
pub fn parse_bottom_expr(&mut self) -> @Expr {
|
||||
maybe_whole_expr!(self);
|
||||
|
||||
let lo = self.span.lo;
|
||||
@@ -1750,12 +1742,12 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
|
||||
let ex: Expr_;
|
||||
|
||||
if *self.token == token::LPAREN {
|
||||
if self.token == token::LPAREN {
|
||||
self.bump();
|
||||
// (e) is parenthesized e
|
||||
// (e,) is a tuple with only one field, e
|
||||
let mut trailing_comma = false;
|
||||
if *self.token == token::RPAREN {
|
||||
if self.token == token::RPAREN {
|
||||
hi = self.span.hi;
|
||||
self.bump();
|
||||
let lit = @spanned(lo, hi, lit_nil);
|
||||
@@ -1763,9 +1755,9 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
}
|
||||
let mut es = ~[self.parse_expr()];
|
||||
self.commit_expr(*es.last(), &[], &[token::COMMA, token::RPAREN]);
|
||||
while *self.token == token::COMMA {
|
||||
while self.token == token::COMMA {
|
||||
self.bump();
|
||||
if *self.token != token::RPAREN {
|
||||
if self.token != token::RPAREN {
|
||||
es.push(self.parse_expr());
|
||||
self.commit_expr(*es.last(), &[], &[token::COMMA, token::RPAREN]);
|
||||
}
|
||||
@@ -1782,12 +1774,12 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
else {
|
||||
self.mk_expr(lo, hi, ExprTup(es))
|
||||
}
|
||||
} else if *self.token == token::LBRACE {
|
||||
} else if self.token == token::LBRACE {
|
||||
self.bump();
|
||||
let blk = self.parse_block_tail(lo, DefaultBlock);
|
||||
return self.mk_expr(blk.span.lo, blk.span.hi,
|
||||
ExprBlock(blk));
|
||||
} else if token::is_bar(&*self.token) {
|
||||
} else if token::is_bar(&self.token) {
|
||||
return self.parse_lambda_expr();
|
||||
} else if self.eat_keyword(keywords::Proc) {
|
||||
let decl = self.parse_proc_decl();
|
||||
@@ -1814,8 +1806,8 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
ExprDoBody);
|
||||
} else if self.eat_keyword(keywords::While) {
|
||||
return self.parse_while_expr();
|
||||
} else if self.token_is_lifetime(&*self.token) {
|
||||
let lifetime = self.get_lifetime(&*self.token);
|
||||
} 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) {
|
||||
@@ -1829,8 +1821,8 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
return self.parse_loop_expr(None);
|
||||
} else if self.eat_keyword(keywords::Continue) {
|
||||
let lo = self.span.lo;
|
||||
let ex = if self.token_is_lifetime(&*self.token) {
|
||||
let lifetime = self.get_lifetime(&*self.token);
|
||||
let ex = if Parser::token_is_lifetime(&self.token) {
|
||||
let lifetime = self.get_lifetime();
|
||||
self.bump();
|
||||
ExprAgain(Some(lifetime.name))
|
||||
} else {
|
||||
@@ -1842,18 +1834,18 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
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 {
|
||||
} else if self.token == token::LBRACKET {
|
||||
self.bump();
|
||||
let mutbl = MutImmutable;
|
||||
|
||||
if *self.token == token::RBRACKET {
|
||||
if self.token == token::RBRACKET {
|
||||
// Empty vector.
|
||||
self.bump();
|
||||
ex = ExprVec(~[], mutbl);
|
||||
} else {
|
||||
// Nonempty vector.
|
||||
let first_expr = self.parse_expr();
|
||||
if *self.token == token::COMMA &&
|
||||
if self.token == token::COMMA &&
|
||||
self.look_ahead(1, |t| *t == token::DOTDOT) {
|
||||
// Repeating vector syntax: [ 0, ..512 ]
|
||||
self.bump();
|
||||
@@ -1861,7 +1853,7 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
let count = self.parse_expr();
|
||||
self.expect(&token::RBRACKET);
|
||||
ex = ExprRepeat(first_expr, count, mutbl);
|
||||
} else if *self.token == token::COMMA {
|
||||
} else if self.token == token::COMMA {
|
||||
// Vector with two or more elements.
|
||||
self.bump();
|
||||
let remaining_exprs = self.parse_seq_to_end(
|
||||
@@ -1885,36 +1877,36 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
self.expect(&token::RPAREN);
|
||||
} else if self.eat_keyword(keywords::Return) {
|
||||
// RETURN expression
|
||||
if can_begin_expr(&*self.token) {
|
||||
if can_begin_expr(&self.token) {
|
||||
let e = self.parse_expr();
|
||||
hi = e.span.hi;
|
||||
ex = ExprRet(Some(e));
|
||||
} else { ex = ExprRet(None); }
|
||||
} else if self.eat_keyword(keywords::Break) {
|
||||
// BREAK expression
|
||||
if self.token_is_lifetime(&*self.token) {
|
||||
let lifetime = self.get_lifetime(&*self.token);
|
||||
if Parser::token_is_lifetime(&self.token) {
|
||||
let lifetime = self.get_lifetime();
|
||||
self.bump();
|
||||
ex = ExprBreak(Some(lifetime.name));
|
||||
} else {
|
||||
ex = ExprBreak(None);
|
||||
}
|
||||
hi = self.span.hi;
|
||||
} else if *self.token == token::MOD_SEP ||
|
||||
is_ident(&*self.token) && !self.is_keyword(keywords::True) &&
|
||||
} 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 {
|
||||
if self.token == token::NOT {
|
||||
// MACRO INVOCATION expression
|
||||
self.bump();
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::LPAREN | token::LBRACE => {}
|
||||
_ => self.fatal("expected open delimiter")
|
||||
};
|
||||
|
||||
let ket = token::flip_delimiter(&*self.token);
|
||||
let ket = token::flip_delimiter(&self.token);
|
||||
self.bump();
|
||||
|
||||
let tts = self.parse_seq_to_end(&ket,
|
||||
@@ -1923,7 +1915,7 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
let hi = self.span.hi;
|
||||
|
||||
return self.mk_mac_expr(lo, hi, mac_invoc_tt(pth, tts, EMPTY_CTXT));
|
||||
} else if *self.token == token::LBRACE {
|
||||
} else if self.token == token::LBRACE {
|
||||
// This might be a struct literal.
|
||||
if self.looking_at_struct_literal() {
|
||||
// It's a struct literal.
|
||||
@@ -1932,7 +1924,7 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
let mut base = None;
|
||||
|
||||
fields.push(self.parse_field());
|
||||
while *self.token != token::RBRACE {
|
||||
while self.token != token::RBRACE {
|
||||
self.commit_expr(fields.last().expr, &[token::COMMA], &[token::RBRACE]);
|
||||
|
||||
if self.eat(&token::DOTDOT) {
|
||||
@@ -1940,7 +1932,7 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
break;
|
||||
}
|
||||
|
||||
if *self.token == token::RBRACE {
|
||||
if self.token == token::RBRACE {
|
||||
// Accept an optional trailing comma.
|
||||
break;
|
||||
}
|
||||
@@ -1967,7 +1959,7 @@ pub fn parse_bottom_expr(&self) -> @Expr {
|
||||
}
|
||||
|
||||
// parse a block or unsafe block
|
||||
pub fn parse_block_expr(&self, lo: BytePos, blk_mode: BlockCheckMode)
|
||||
pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode)
|
||||
-> @Expr {
|
||||
self.expect(&token::LBRACE);
|
||||
let blk = self.parse_block_tail(lo, blk_mode);
|
||||
@@ -1975,19 +1967,19 @@ pub fn parse_block_expr(&self, lo: BytePos, blk_mode: BlockCheckMode)
|
||||
}
|
||||
|
||||
// parse a.b or a(13) or a[4] or just a
|
||||
pub fn parse_dot_or_call_expr(&self) -> @Expr {
|
||||
pub fn parse_dot_or_call_expr(&mut self) -> @Expr {
|
||||
let b = self.parse_bottom_expr();
|
||||
self.parse_dot_or_call_expr_with(b)
|
||||
}
|
||||
|
||||
pub fn parse_dot_or_call_expr_with(&self, e0: @Expr) -> @Expr {
|
||||
pub fn parse_dot_or_call_expr_with(&mut self, e0: @Expr) -> @Expr {
|
||||
let mut e = e0;
|
||||
let lo = e.span.lo;
|
||||
let mut hi;
|
||||
loop {
|
||||
// expr.f
|
||||
if self.eat(&token::DOT) {
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::IDENT(i, _) => {
|
||||
hi = self.span.hi;
|
||||
self.bump();
|
||||
@@ -1999,7 +1991,7 @@ pub fn parse_dot_or_call_expr_with(&self, e0: @Expr) -> @Expr {
|
||||
};
|
||||
|
||||
// expr.f() method call
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::LPAREN => {
|
||||
let es = self.parse_unspanned_seq(
|
||||
&token::LPAREN,
|
||||
@@ -2013,7 +2005,8 @@ pub fn parse_dot_or_call_expr_with(&self, e0: @Expr) -> @Expr {
|
||||
e = self.mk_expr(lo, hi, nd);
|
||||
}
|
||||
_ => {
|
||||
e = self.mk_expr(lo, hi, self.mk_field(e, i, tys));
|
||||
let field = self.mk_field(e, i, tys);
|
||||
e = self.mk_expr(lo, hi, field)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2022,7 +2015,7 @@ pub fn parse_dot_or_call_expr_with(&self, e0: @Expr) -> @Expr {
|
||||
continue;
|
||||
}
|
||||
if self.expr_is_complete(e) { break; }
|
||||
match *self.token {
|
||||
match self.token {
|
||||
// expr(...)
|
||||
token::LPAREN => {
|
||||
let es = self.parse_unspanned_seq(
|
||||
@@ -2043,7 +2036,8 @@ pub fn parse_dot_or_call_expr_with(&self, e0: @Expr) -> @Expr {
|
||||
let ix = self.parse_expr();
|
||||
hi = ix.span.hi;
|
||||
self.commit_expr_expecting(ix, token::RBRACKET);
|
||||
e = self.mk_expr(lo, hi, self.mk_index(e, ix));
|
||||
let index = self.mk_index(e, ix);
|
||||
e = self.mk_expr(lo, hi, index)
|
||||
}
|
||||
|
||||
_ => return e
|
||||
@@ -2054,11 +2048,11 @@ pub fn parse_dot_or_call_expr_with(&self, e0: @Expr) -> @Expr {
|
||||
|
||||
// parse an optional separator followed by a kleene-style
|
||||
// repetition token (+ or *).
|
||||
pub fn parse_sep_and_zerok(&self) -> (Option<token::Token>, bool) {
|
||||
fn parse_zerok(parser: &Parser) -> Option<bool> {
|
||||
match *parser.token {
|
||||
pub fn parse_sep_and_zerok(&mut self) -> (Option<token::Token>, bool) {
|
||||
fn parse_zerok(parser: &mut Parser) -> Option<bool> {
|
||||
match parser.token {
|
||||
token::BINOP(token::STAR) | token::BINOP(token::PLUS) => {
|
||||
let zerok = *parser.token == token::BINOP(token::STAR);
|
||||
let zerok = parser.token == token::BINOP(token::STAR);
|
||||
parser.bump();
|
||||
Some(zerok)
|
||||
},
|
||||
@@ -2079,7 +2073,7 @@ fn parse_zerok(parser: &Parser) -> Option<bool> {
|
||||
}
|
||||
|
||||
// parse a single token tree from the input.
|
||||
pub fn parse_token_tree(&self) -> token_tree {
|
||||
pub fn parse_token_tree(&mut self) -> token_tree {
|
||||
// FIXME #6994: currently, this is too eager. It
|
||||
// parses token trees but also identifies tt_seq's
|
||||
// and tt_nonterminals; it's too early to know yet
|
||||
@@ -2092,22 +2086,27 @@ pub fn parse_token_tree(&self) -> token_tree {
|
||||
// not an EOF, and not the desired right-delimiter (if
|
||||
// it were, parse_seq_to_before_end would have prevented
|
||||
// reaching this point.
|
||||
fn parse_non_delim_tt_tok(p: &Parser) -> token_tree {
|
||||
fn parse_non_delim_tt_tok(p: &mut Parser) -> token_tree {
|
||||
maybe_whole!(deref p, nt_tt);
|
||||
match *p.token {
|
||||
match p.token {
|
||||
token::RPAREN | token::RBRACE | token::RBRACKET => {
|
||||
// This is a conservative error: only report the last unclosed delimiter. The
|
||||
// previous unclosed delimiters could actually be closed! The parser just hasn't
|
||||
// gotten to them yet.
|
||||
p.open_braces.last_opt().map(|sp| p.span_note(*sp, "unclosed delimiter"));
|
||||
p.fatal(format!("incorrect close delimiter: `{}`", p.this_token_to_str()));
|
||||
match p.open_braces.last_opt() {
|
||||
None => {}
|
||||
Some(&sp) => p.span_note(sp, "unclosed delimiter"),
|
||||
};
|
||||
let token_str = p.this_token_to_str();
|
||||
p.fatal(format!("incorrect close delimiter: `{}`",
|
||||
token_str))
|
||||
},
|
||||
/* we ought to allow different depths of unquotation */
|
||||
token::DOLLAR if *p.quote_depth > 0u => {
|
||||
token::DOLLAR if p.quote_depth > 0u => {
|
||||
p.bump();
|
||||
let sp = *p.span;
|
||||
let sp = p.span;
|
||||
|
||||
if *p.token == token::LPAREN {
|
||||
if p.token == token::LPAREN {
|
||||
let seq = p.parse_seq(
|
||||
&token::LPAREN,
|
||||
&token::RPAREN,
|
||||
@@ -2135,13 +2134,14 @@ fn parse_non_delim_tt_tok(p: &Parser) -> token_tree {
|
||||
}
|
||||
|
||||
// turn the next token into a tt_tok:
|
||||
fn parse_any_tt_tok(p: &Parser) -> token_tree{
|
||||
tt_tok(*p.span, p.bump_and_get())
|
||||
fn parse_any_tt_tok(p: &mut Parser) -> token_tree{
|
||||
tt_tok(p.span, p.bump_and_get())
|
||||
}
|
||||
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::EOF => {
|
||||
for sp in self.open_braces.iter() {
|
||||
let open_braces = self.open_braces.clone();
|
||||
for sp in open_braces.iter() {
|
||||
self.span_note(*sp, "Did you mean to close this delimiter?");
|
||||
}
|
||||
// There shouldn't really be a span, but it's easier for the test runner
|
||||
@@ -2149,10 +2149,10 @@ fn parse_any_tt_tok(p: &Parser) -> token_tree{
|
||||
self.fatal("This file contains an un-closed delimiter ");
|
||||
}
|
||||
token::LPAREN | token::LBRACE | token::LBRACKET => {
|
||||
let close_delim = token::flip_delimiter(&*self.token);
|
||||
let close_delim = token::flip_delimiter(&self.token);
|
||||
|
||||
// Parse the open delimiter.
|
||||
(*self.open_braces).push(*self.span);
|
||||
self.open_braces.push(self.span);
|
||||
let mut result = ~[parse_any_tt_tok(self)];
|
||||
|
||||
let trees =
|
||||
@@ -2173,22 +2173,22 @@ fn parse_any_tt_tok(p: &Parser) -> token_tree{
|
||||
|
||||
// parse a stream of tokens into a list of token_trees,
|
||||
// up to EOF.
|
||||
pub fn parse_all_token_trees(&self) -> ~[token_tree] {
|
||||
pub fn parse_all_token_trees(&mut self) -> ~[token_tree] {
|
||||
let mut tts = ~[];
|
||||
while *self.token != token::EOF {
|
||||
while self.token != token::EOF {
|
||||
tts.push(self.parse_token_tree());
|
||||
}
|
||||
tts
|
||||
}
|
||||
|
||||
pub fn parse_matchers(&self) -> ~[matcher] {
|
||||
pub fn parse_matchers(&mut self) -> ~[matcher] {
|
||||
// unification of matchers and token_trees would vastly improve
|
||||
// the interpolation of matchers
|
||||
maybe_whole!(self, nt_matchers);
|
||||
let name_idx = @mut 0u;
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::LBRACE | token::LPAREN | token::LBRACKET => {
|
||||
let other_delimiter = token::flip_delimiter(self.token);
|
||||
let other_delimiter = token::flip_delimiter(&self.token);
|
||||
self.bump();
|
||||
self.parse_matcher_subseq_upto(name_idx, &other_delimiter)
|
||||
}
|
||||
@@ -2199,16 +2199,16 @@ pub fn parse_matchers(&self) -> ~[matcher] {
|
||||
// This goofy function is necessary to correctly match parens in matchers.
|
||||
// Otherwise, `$( ( )` would be a valid matcher, and `$( () )` would be
|
||||
// invalid. It's similar to common::parse_seq.
|
||||
pub fn parse_matcher_subseq_upto(&self,
|
||||
pub fn parse_matcher_subseq_upto(&mut self,
|
||||
name_idx: @mut uint,
|
||||
ket: &token::Token)
|
||||
-> ~[matcher] {
|
||||
let mut ret_val = ~[];
|
||||
let mut lparens = 0u;
|
||||
|
||||
while *self.token != *ket || lparens > 0u {
|
||||
if *self.token == token::LPAREN { lparens += 1u; }
|
||||
if *self.token == token::RPAREN { lparens -= 1u; }
|
||||
while self.token != *ket || lparens > 0u {
|
||||
if self.token == token::LPAREN { lparens += 1u; }
|
||||
if self.token == token::RPAREN { lparens -= 1u; }
|
||||
ret_val.push(self.parse_matcher(name_idx));
|
||||
}
|
||||
|
||||
@@ -2217,12 +2217,12 @@ pub fn parse_matcher_subseq_upto(&self,
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
pub fn parse_matcher(&self, name_idx: @mut uint) -> matcher {
|
||||
pub fn parse_matcher(&mut self, name_idx: @mut uint) -> matcher {
|
||||
let lo = self.span.lo;
|
||||
|
||||
let m = if *self.token == token::DOLLAR {
|
||||
let m = if self.token == token::DOLLAR {
|
||||
self.bump();
|
||||
if *self.token == token::LPAREN {
|
||||
if self.token == token::LPAREN {
|
||||
let name_idx_lo = *name_idx;
|
||||
self.bump();
|
||||
let ms = self.parse_matcher_subseq_upto(name_idx,
|
||||
@@ -2248,12 +2248,12 @@ pub fn parse_matcher(&self, name_idx: @mut uint) -> matcher {
|
||||
}
|
||||
|
||||
// parse a prefix-operator expr
|
||||
pub fn parse_prefix_expr(&self) -> @Expr {
|
||||
pub fn parse_prefix_expr(&mut self) -> @Expr {
|
||||
let lo = self.span.lo;
|
||||
let hi;
|
||||
|
||||
let ex;
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::NOT => {
|
||||
self.bump();
|
||||
let e = self.parse_prefix_expr();
|
||||
@@ -2347,19 +2347,20 @@ pub fn parse_prefix_expr(&self) -> @Expr {
|
||||
}
|
||||
|
||||
// parse an expression of binops
|
||||
pub fn parse_binops(&self) -> @Expr {
|
||||
self.parse_more_binops(self.parse_prefix_expr(), 0)
|
||||
pub fn parse_binops(&mut self) -> @Expr {
|
||||
let prefix_expr = self.parse_prefix_expr();
|
||||
self.parse_more_binops(prefix_expr, 0)
|
||||
}
|
||||
|
||||
// parse an expression of binops of at least min_prec precedence
|
||||
pub fn parse_more_binops(&self, lhs: @Expr, min_prec: uint) -> @Expr {
|
||||
pub fn parse_more_binops(&mut self, lhs: @Expr, min_prec: uint) -> @Expr {
|
||||
if self.expr_is_complete(lhs) { return lhs; }
|
||||
|
||||
// Prevent dynamic borrow errors later on by limiting the
|
||||
// scope of the borrows.
|
||||
{
|
||||
let token: &token::Token = self.token;
|
||||
let restriction: &restriction = self.restriction;
|
||||
let token: &token::Token = &self.token;
|
||||
let restriction: &restriction = &self.restriction;
|
||||
match (token, restriction) {
|
||||
(&token::BINOP(token::OR), &RESTRICT_NO_BAR_OP) => return lhs,
|
||||
(&token::BINOP(token::OR),
|
||||
@@ -2369,7 +2370,7 @@ pub fn parse_more_binops(&self, lhs: @Expr, min_prec: uint) -> @Expr {
|
||||
}
|
||||
}
|
||||
|
||||
let cur_opt = token_to_binop(self.token);
|
||||
let cur_opt = token_to_binop(&self.token);
|
||||
match cur_opt {
|
||||
Some(cur_op) => {
|
||||
let cur_prec = operator_prec(cur_op);
|
||||
@@ -2377,8 +2378,8 @@ pub fn parse_more_binops(&self, lhs: @Expr, min_prec: uint) -> @Expr {
|
||||
self.bump();
|
||||
let expr = self.parse_prefix_expr();
|
||||
let rhs = self.parse_more_binops(expr, cur_prec);
|
||||
let bin = self.mk_expr(lhs.span.lo, rhs.span.hi,
|
||||
self.mk_binary(cur_op, lhs, rhs));
|
||||
let binary = self.mk_binary(cur_op, lhs, rhs);
|
||||
let bin = self.mk_expr(lhs.span.lo, rhs.span.hi, binary);
|
||||
self.parse_more_binops(bin, min_prec)
|
||||
} else {
|
||||
lhs
|
||||
@@ -2401,10 +2402,10 @@ pub fn parse_more_binops(&self, lhs: @Expr, min_prec: uint) -> @Expr {
|
||||
// parse an assignment expression....
|
||||
// actually, this seems to be the main entry point for
|
||||
// parsing an arbitrary expression.
|
||||
pub fn parse_assign_expr(&self) -> @Expr {
|
||||
pub fn parse_assign_expr(&mut self) -> @Expr {
|
||||
let lo = self.span.lo;
|
||||
let lhs = self.parse_binops();
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::EQ => {
|
||||
self.bump();
|
||||
let rhs = self.parse_expr();
|
||||
@@ -2425,11 +2426,11 @@ pub fn parse_assign_expr(&self) -> @Expr {
|
||||
token::SHL => BiShl,
|
||||
token::SHR => BiShr
|
||||
};
|
||||
self.mk_expr(lo, rhs.span.hi,
|
||||
self.mk_assign_op(aop, lhs, rhs))
|
||||
let assign_op = self.mk_assign_op(aop, lhs, rhs);
|
||||
self.mk_expr(lo, rhs.span.hi, assign_op)
|
||||
}
|
||||
token::DARROW => {
|
||||
self.obsolete(*self.span, ObsoleteSwap);
|
||||
self.obsolete(self.span, ObsoleteSwap);
|
||||
self.bump();
|
||||
// Ignore what we get, this is an error anyway
|
||||
self.parse_expr();
|
||||
@@ -2442,7 +2443,7 @@ pub fn parse_assign_expr(&self) -> @Expr {
|
||||
}
|
||||
|
||||
// parse an 'if' expression ('if' token already eaten)
|
||||
pub fn parse_if_expr(&self) -> @Expr {
|
||||
pub fn parse_if_expr(&mut self) -> @Expr {
|
||||
let lo = self.last_span.lo;
|
||||
let cond = self.parse_expr();
|
||||
let thn = self.parse_block();
|
||||
@@ -2457,12 +2458,12 @@ pub fn parse_if_expr(&self) -> @Expr {
|
||||
}
|
||||
|
||||
// `|args| { ... }` or `{ ...}` like in `do` expressions
|
||||
pub fn parse_lambda_block_expr(&self) -> @Expr {
|
||||
pub fn parse_lambda_block_expr(&mut self) -> @Expr {
|
||||
self.parse_lambda_expr_(
|
||||
|| {
|
||||
match *self.token {
|
||||
|p| {
|
||||
match p.token {
|
||||
token::BINOP(token::OR) | token::OROR => {
|
||||
self.parse_fn_block_decl()
|
||||
p.parse_fn_block_decl()
|
||||
}
|
||||
_ => {
|
||||
// No argument list - `do foo {`
|
||||
@@ -2471,7 +2472,7 @@ pub fn parse_lambda_block_expr(&self) -> @Expr {
|
||||
output: P(Ty {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ty_infer,
|
||||
span: *self.span
|
||||
span: p.span
|
||||
}),
|
||||
cf: return_val,
|
||||
variadic: false
|
||||
@@ -2479,28 +2480,28 @@ pub fn parse_lambda_block_expr(&self) -> @Expr {
|
||||
}
|
||||
}
|
||||
},
|
||||
|| {
|
||||
let blk = self.parse_block();
|
||||
self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk))
|
||||
|p| {
|
||||
let blk = p.parse_block();
|
||||
p.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk))
|
||||
})
|
||||
}
|
||||
|
||||
// `|args| expr`
|
||||
pub fn parse_lambda_expr(&self) -> @Expr {
|
||||
self.parse_lambda_expr_(|| self.parse_fn_block_decl(),
|
||||
|| self.parse_expr())
|
||||
pub fn parse_lambda_expr(&mut self) -> @Expr {
|
||||
self.parse_lambda_expr_(|p| p.parse_fn_block_decl(),
|
||||
|p| p.parse_expr())
|
||||
}
|
||||
|
||||
// parse something of the form |args| expr
|
||||
// this is used both in parsing a lambda expr
|
||||
// and in parsing a block expr as e.g. in for...
|
||||
pub fn parse_lambda_expr_(&self,
|
||||
parse_decl: || -> P<fn_decl>,
|
||||
parse_body: || -> @Expr)
|
||||
pub fn parse_lambda_expr_(&mut self,
|
||||
parse_decl: |&mut Parser| -> P<fn_decl>,
|
||||
parse_body: |&mut Parser| -> @Expr)
|
||||
-> @Expr {
|
||||
let lo = self.last_span.lo;
|
||||
let decl = parse_decl();
|
||||
let body = parse_body();
|
||||
let decl = parse_decl(self);
|
||||
let body = parse_body(self);
|
||||
let fakeblock = P(ast::Block {
|
||||
view_items: ~[],
|
||||
stmts: ~[],
|
||||
@@ -2510,11 +2511,10 @@ pub fn parse_lambda_expr_(&self,
|
||||
span: body.span,
|
||||
});
|
||||
|
||||
return self.mk_expr(lo, body.span.hi,
|
||||
ExprFnBlock(decl, fakeblock));
|
||||
return self.mk_expr(lo, body.span.hi, ExprFnBlock(decl, fakeblock));
|
||||
}
|
||||
|
||||
pub fn parse_else_expr(&self) -> @Expr {
|
||||
pub fn parse_else_expr(&mut self) -> @Expr {
|
||||
if self.eat_keyword(keywords::If) {
|
||||
return self.parse_if_expr();
|
||||
} else {
|
||||
@@ -2524,7 +2524,7 @@ pub fn parse_else_expr(&self) -> @Expr {
|
||||
}
|
||||
|
||||
// parse a 'for' .. 'in' expression ('for' token already eaten)
|
||||
pub fn parse_for_expr(&self, opt_ident: Option<ast::Ident>) -> @Expr {
|
||||
pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> @Expr {
|
||||
// Parse: `for <src_pat> in <src_expr> <src_loop_block>`
|
||||
|
||||
let lo = self.last_span.lo;
|
||||
@@ -2541,7 +2541,7 @@ pub fn parse_for_expr(&self, opt_ident: Option<ast::Ident>) -> @Expr {
|
||||
// parse a 'do'.
|
||||
// the 'do' expression parses as a call, but looks like
|
||||
// a function call followed by a closure expression.
|
||||
pub fn parse_sugary_call_expr(&self,
|
||||
pub fn parse_sugary_call_expr(&mut self,
|
||||
lo: BytePos,
|
||||
keyword: ~str,
|
||||
sugar: CallSugar,
|
||||
@@ -2570,33 +2570,31 @@ pub fn parse_sugary_call_expr(&self,
|
||||
let last_arg = self.mk_expr(block.span.lo, block.span.hi,
|
||||
ctor(block));
|
||||
let args = vec::append((*args).clone(), [last_arg]);
|
||||
self.mk_expr(lo, block.span.hi,
|
||||
self.mk_method_call(f,
|
||||
i,
|
||||
(*tps).clone(),
|
||||
args,
|
||||
sugar))
|
||||
let method_call = self.mk_method_call(f,
|
||||
i,
|
||||
(*tps).clone(),
|
||||
args,
|
||||
sugar);
|
||||
self.mk_expr(lo, block.span.hi, method_call)
|
||||
}
|
||||
ExprField(f, i, ref tps) => {
|
||||
let block = self.parse_lambda_block_expr();
|
||||
let last_arg = self.mk_expr(block.span.lo, block.span.hi,
|
||||
ctor(block));
|
||||
self.mk_expr(lo, block.span.hi,
|
||||
self.mk_method_call(f,
|
||||
i,
|
||||
(*tps).clone(),
|
||||
~[last_arg],
|
||||
sugar))
|
||||
let method_call = self.mk_method_call(f,
|
||||
i,
|
||||
(*tps).clone(),
|
||||
~[last_arg],
|
||||
sugar);
|
||||
self.mk_expr(lo, block.span.hi, method_call)
|
||||
}
|
||||
ExprPath(..) | ExprCall(..) | ExprMethodCall(..) |
|
||||
ExprParen(..) => {
|
||||
let block = self.parse_lambda_block_expr();
|
||||
let last_arg = self.mk_expr(block.span.lo, block.span.hi,
|
||||
ctor(block));
|
||||
self.mk_expr(
|
||||
lo,
|
||||
last_arg.span.hi,
|
||||
self.mk_call(e, ~[last_arg], sugar))
|
||||
let call = self.mk_call(e, ~[last_arg], sugar);
|
||||
self.mk_expr(lo, last_arg.span.hi, call)
|
||||
}
|
||||
_ => {
|
||||
// There may be other types of expressions that can
|
||||
@@ -2610,7 +2608,7 @@ pub fn parse_sugary_call_expr(&self,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_while_expr(&self) -> @Expr {
|
||||
pub fn parse_while_expr(&mut self) -> @Expr {
|
||||
let lo = self.last_span.lo;
|
||||
let cond = self.parse_expr();
|
||||
let body = self.parse_block();
|
||||
@@ -2618,11 +2616,11 @@ pub fn parse_while_expr(&self) -> @Expr {
|
||||
return self.mk_expr(lo, hi, ExprWhile(cond, body));
|
||||
}
|
||||
|
||||
pub fn parse_loop_expr(&self, opt_ident: Option<ast::Ident>) -> @Expr {
|
||||
pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> @Expr {
|
||||
// loop headers look like 'loop {' or 'loop unsafe {'
|
||||
let is_loop_header =
|
||||
*self.token == token::LBRACE
|
||||
|| (is_ident(&*self.token)
|
||||
self.token == token::LBRACE
|
||||
|| (is_ident(&self.token)
|
||||
&& self.look_ahead(1, |t| *t == token::LBRACE));
|
||||
|
||||
if is_loop_header {
|
||||
@@ -2634,14 +2632,14 @@ pub fn parse_loop_expr(&self, opt_ident: Option<ast::Ident>) -> @Expr {
|
||||
} else {
|
||||
// This is an obsolete 'continue' expression
|
||||
if opt_ident.is_some() {
|
||||
self.span_err(*self.last_span,
|
||||
self.span_err(self.last_span,
|
||||
"a label may not be used with a `loop` expression");
|
||||
}
|
||||
|
||||
self.obsolete(*self.last_span, ObsoleteLoopAsContinue);
|
||||
self.obsolete(self.last_span, ObsoleteLoopAsContinue);
|
||||
let lo = self.span.lo;
|
||||
let ex = if self.token_is_lifetime(&*self.token) {
|
||||
let lifetime = self.get_lifetime(&*self.token);
|
||||
let ex = if Parser::token_is_lifetime(&self.token) {
|
||||
let lifetime = self.get_lifetime();
|
||||
self.bump();
|
||||
ExprAgain(Some(lifetime.name))
|
||||
} else {
|
||||
@@ -2653,18 +2651,18 @@ pub fn parse_loop_expr(&self, opt_ident: Option<ast::Ident>) -> @Expr {
|
||||
}
|
||||
|
||||
// For distingishing between struct literals and blocks
|
||||
fn looking_at_struct_literal(&self) -> bool {
|
||||
*self.token == token::LBRACE &&
|
||||
fn looking_at_struct_literal(&mut self) -> bool {
|
||||
self.token == token::LBRACE &&
|
||||
(self.look_ahead(1, |t| token::is_plain_ident(t)) &&
|
||||
self.look_ahead(2, |t| *t == token::COLON))
|
||||
}
|
||||
|
||||
fn parse_match_expr(&self) -> @Expr {
|
||||
fn parse_match_expr(&mut self) -> @Expr {
|
||||
let lo = self.last_span.lo;
|
||||
let discriminant = self.parse_expr();
|
||||
self.commit_expr_expecting(discriminant, token::LBRACE);
|
||||
let mut arms: ~[Arm] = ~[];
|
||||
while *self.token != token::RBRACE {
|
||||
while self.token != token::RBRACE {
|
||||
let pats = self.parse_pats();
|
||||
let mut guard = None;
|
||||
if self.eat_keyword(keywords::If) {
|
||||
@@ -2675,7 +2673,7 @@ fn parse_match_expr(&self) -> @Expr {
|
||||
|
||||
let require_comma =
|
||||
!classify::expr_is_simple_block(expr)
|
||||
&& *self.token != token::RBRACE;
|
||||
&& self.token != token::RBRACE;
|
||||
|
||||
if require_comma {
|
||||
self.commit_expr(expr, &[token::COMMA], &[token::RBRACE]);
|
||||
@@ -2700,22 +2698,22 @@ fn parse_match_expr(&self) -> @Expr {
|
||||
}
|
||||
|
||||
// parse an expression
|
||||
pub fn parse_expr(&self) -> @Expr {
|
||||
pub fn parse_expr(&mut self) -> @Expr {
|
||||
return self.parse_expr_res(UNRESTRICTED);
|
||||
}
|
||||
|
||||
// parse an expression, subject to the given restriction
|
||||
fn parse_expr_res(&self, r: restriction) -> @Expr {
|
||||
let old = *self.restriction;
|
||||
*self.restriction = r;
|
||||
fn parse_expr_res(&mut self, r: restriction) -> @Expr {
|
||||
let old = self.restriction;
|
||||
self.restriction = r;
|
||||
let e = self.parse_assign_expr();
|
||||
*self.restriction = old;
|
||||
self.restriction = old;
|
||||
return e;
|
||||
}
|
||||
|
||||
// parse the RHS of a local variable declaration (e.g. '= 14;')
|
||||
fn parse_initializer(&self) -> Option<@Expr> {
|
||||
if *self.token == token::EQ {
|
||||
fn parse_initializer(&mut self) -> Option<@Expr> {
|
||||
if self.token == token::EQ {
|
||||
self.bump();
|
||||
Some(self.parse_expr())
|
||||
} else {
|
||||
@@ -2724,17 +2722,17 @@ fn parse_initializer(&self) -> Option<@Expr> {
|
||||
}
|
||||
|
||||
// parse patterns, separated by '|' s
|
||||
fn parse_pats(&self) -> ~[@Pat] {
|
||||
fn parse_pats(&mut self) -> ~[@Pat] {
|
||||
let mut pats = ~[];
|
||||
loop {
|
||||
pats.push(self.parse_pat());
|
||||
if *self.token == token::BINOP(token::OR) { self.bump(); }
|
||||
if self.token == token::BINOP(token::OR) { self.bump(); }
|
||||
else { return pats; }
|
||||
};
|
||||
}
|
||||
|
||||
fn parse_pat_vec_elements(
|
||||
&self,
|
||||
&mut self,
|
||||
) -> (~[@Pat], Option<@Pat>, ~[@Pat]) {
|
||||
let mut before = ~[];
|
||||
let mut slice = None;
|
||||
@@ -2742,13 +2740,13 @@ fn parse_pat_vec_elements(
|
||||
let mut first = true;
|
||||
let mut before_slice = true;
|
||||
|
||||
while *self.token != token::RBRACKET {
|
||||
while self.token != token::RBRACKET {
|
||||
if first { first = false; }
|
||||
else { self.expect(&token::COMMA); }
|
||||
|
||||
let mut is_slice = false;
|
||||
if before_slice {
|
||||
if *self.token == token::DOTDOT {
|
||||
if self.token == token::DOTDOT {
|
||||
self.bump();
|
||||
is_slice = true;
|
||||
before_slice = false;
|
||||
@@ -2756,17 +2754,17 @@ fn parse_pat_vec_elements(
|
||||
}
|
||||
|
||||
if is_slice {
|
||||
if *self.token == token::COMMA || *self.token == token::RBRACKET {
|
||||
if self.token == token::COMMA || self.token == token::RBRACKET {
|
||||
slice = Some(@ast::Pat {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: PatWildMulti,
|
||||
span: *self.span,
|
||||
span: self.span,
|
||||
})
|
||||
} else {
|
||||
let subpat = self.parse_pat();
|
||||
match subpat {
|
||||
@ast::Pat { id, node: PatWild, span } => {
|
||||
self.obsolete(*self.span, ObsoleteVecDotDotWildcard);
|
||||
self.obsolete(self.span, ObsoleteVecDotDotWildcard);
|
||||
slice = Some(@ast::Pat {
|
||||
id: id,
|
||||
node: PatWildMulti,
|
||||
@@ -2795,32 +2793,29 @@ fn parse_pat_vec_elements(
|
||||
}
|
||||
|
||||
// parse the fields of a struct-like pattern
|
||||
fn parse_pat_fields(&self) -> (~[ast::FieldPat], bool) {
|
||||
fn parse_pat_fields(&mut self) -> (~[ast::FieldPat], bool) {
|
||||
let mut fields = ~[];
|
||||
let mut etc = false;
|
||||
let mut first = true;
|
||||
while *self.token != token::RBRACE {
|
||||
while self.token != token::RBRACE {
|
||||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
self.expect(&token::COMMA);
|
||||
// accept trailing commas
|
||||
if *self.token == token::RBRACE { break }
|
||||
if self.token == token::RBRACE { break }
|
||||
}
|
||||
|
||||
etc = *self.token == token::UNDERSCORE || *self.token == token::DOTDOT;
|
||||
if *self.token == token::UNDERSCORE {
|
||||
self.obsolete(*self.span, ObsoleteStructWildcard);
|
||||
etc = self.token == token::UNDERSCORE || self.token == token::DOTDOT;
|
||||
if self.token == token::UNDERSCORE {
|
||||
self.obsolete(self.span, ObsoleteStructWildcard);
|
||||
}
|
||||
if etc {
|
||||
self.bump();
|
||||
if *self.token != token::RBRACE {
|
||||
self.fatal(
|
||||
format!(
|
||||
"expected `\\}`, found `{}`",
|
||||
self.this_token_to_str()
|
||||
)
|
||||
);
|
||||
if self.token != token::RBRACE {
|
||||
let token_str = self.this_token_to_str();
|
||||
self.fatal(format!("expected `\\}`, found `{}`",
|
||||
token_str))
|
||||
}
|
||||
etc = true;
|
||||
break;
|
||||
@@ -2840,11 +2835,12 @@ fn parse_pat_fields(&self) -> (~[ast::FieldPat], bool) {
|
||||
let fieldpath = ast_util::ident_to_path(mk_sp(lo1, hi1),
|
||||
fieldname);
|
||||
let subpat;
|
||||
if *self.token == token::COLON {
|
||||
if self.token == token::COLON {
|
||||
match bind_type {
|
||||
BindByRef(..) | BindByValue(MutMutable) =>
|
||||
self.fatal(format!("unexpected `{}`",
|
||||
self.this_token_to_str())),
|
||||
BindByRef(..) | BindByValue(MutMutable) => {
|
||||
let token_str = self.this_token_to_str();
|
||||
self.fatal(format!("unexpected `{}`", token_str))
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -2854,7 +2850,7 @@ fn parse_pat_fields(&self) -> (~[ast::FieldPat], bool) {
|
||||
subpat = @ast::Pat {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: PatIdent(bind_type, fieldpath, None),
|
||||
span: *self.last_span
|
||||
span: self.last_span
|
||||
};
|
||||
}
|
||||
fields.push(ast::FieldPat { ident: fieldname, pat: subpat });
|
||||
@@ -2863,13 +2859,13 @@ fn parse_pat_fields(&self) -> (~[ast::FieldPat], bool) {
|
||||
}
|
||||
|
||||
// parse a pattern.
|
||||
pub fn parse_pat(&self) -> @Pat {
|
||||
pub fn parse_pat(&mut self) -> @Pat {
|
||||
maybe_whole!(self, nt_pat);
|
||||
|
||||
let lo = self.span.lo;
|
||||
let mut hi;
|
||||
let pat;
|
||||
match *self.token {
|
||||
match self.token {
|
||||
// parse _
|
||||
token::UNDERSCORE => {
|
||||
self.bump();
|
||||
@@ -2968,7 +2964,7 @@ pub fn parse_pat(&self) -> @Pat {
|
||||
token::LPAREN => {
|
||||
// parse (pat,pat,pat,...) as tuple
|
||||
self.bump();
|
||||
if *self.token == token::RPAREN {
|
||||
if self.token == token::RPAREN {
|
||||
hi = self.span.hi;
|
||||
self.bump();
|
||||
let lit = @codemap::Spanned {
|
||||
@@ -2979,7 +2975,7 @@ pub fn parse_pat(&self) -> @Pat {
|
||||
} else {
|
||||
let mut fields = ~[self.parse_pat()];
|
||||
if self.look_ahead(1, |t| *t != token::RPAREN) {
|
||||
while *self.token == token::COMMA {
|
||||
while self.token == token::COMMA {
|
||||
self.bump();
|
||||
fields.push(self.parse_pat());
|
||||
}
|
||||
@@ -3013,8 +3009,7 @@ pub fn parse_pat(&self) -> @Pat {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let tok = self.token;
|
||||
if !is_ident_or_path(tok)
|
||||
if !is_ident_or_path(&self.token)
|
||||
|| self.is_keyword(keywords::True)
|
||||
|| self.is_keyword(keywords::False) {
|
||||
// Parse an expression pattern or exp .. exp.
|
||||
@@ -3023,7 +3018,7 @@ pub fn parse_pat(&self) -> @Pat {
|
||||
// preceded by unary-minus) or identifiers.
|
||||
let val = self.parse_literal_maybe_minus();
|
||||
if self.eat(&token::DOTDOT) {
|
||||
let end = if is_ident_or_path(tok) {
|
||||
let end = if is_ident_or_path(&self.token) {
|
||||
let path = self.parse_path(LifetimeAndTypesWithColons)
|
||||
.path;
|
||||
let hi = self.span.hi;
|
||||
@@ -3055,7 +3050,7 @@ pub fn parse_pat(&self) -> @Pat {
|
||||
self.eat(&token::DOTDOT);
|
||||
let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
|
||||
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 name = self.parse_path(NoTypesAllowed).path;
|
||||
let sub;
|
||||
if self.eat(&token::AT) {
|
||||
@@ -3070,7 +3065,7 @@ pub fn parse_pat(&self) -> @Pat {
|
||||
// parse an enum pat
|
||||
let enum_path = self.parse_path(LifetimeAndTypesWithColons)
|
||||
.path;
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::LBRACE => {
|
||||
self.bump();
|
||||
let (fields, etc) =
|
||||
@@ -3080,7 +3075,7 @@ pub fn parse_pat(&self) -> @Pat {
|
||||
}
|
||||
_ => {
|
||||
let mut args: ~[@Pat] = ~[];
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::LPAREN => {
|
||||
let is_star = self.look_ahead(1, |t| {
|
||||
match *t {
|
||||
@@ -3098,7 +3093,7 @@ pub fn parse_pat(&self) -> @Pat {
|
||||
// This is a "top constructor only" pat
|
||||
self.bump();
|
||||
if is_star {
|
||||
self.obsolete(*self.span, ObsoleteEnumWildcard);
|
||||
self.obsolete(self.span, ObsoleteEnumWildcard);
|
||||
}
|
||||
self.bump();
|
||||
self.expect(&token::RPAREN);
|
||||
@@ -3141,11 +3136,11 @@ pub fn parse_pat(&self) -> @Pat {
|
||||
// parse ident or ident @ pat
|
||||
// used by the copy foo and ref foo patterns to give a good
|
||||
// error message when parsing mistakes like ref foo(a,b)
|
||||
fn parse_pat_ident(&self,
|
||||
fn parse_pat_ident(&mut self,
|
||||
binding_mode: ast::BindingMode)
|
||||
-> ast::Pat_ {
|
||||
if !is_plain_ident(&*self.token) {
|
||||
self.span_fatal(*self.last_span,
|
||||
if !is_plain_ident(&self.token) {
|
||||
self.span_fatal(self.last_span,
|
||||
"expected identifier, found path");
|
||||
}
|
||||
// why a path here, and not just an identifier?
|
||||
@@ -3162,9 +3157,9 @@ fn parse_pat_ident(&self,
|
||||
// leads to a parse error. Note that if there is no explicit
|
||||
// binding mode then we do not end up here, because the lookahead
|
||||
// will direct us over to parse_enum_variant()
|
||||
if *self.token == token::LPAREN {
|
||||
if self.token == token::LPAREN {
|
||||
self.span_fatal(
|
||||
*self.last_span,
|
||||
self.last_span,
|
||||
"expected identifier, found enum pattern");
|
||||
}
|
||||
|
||||
@@ -3172,7 +3167,7 @@ fn parse_pat_ident(&self,
|
||||
}
|
||||
|
||||
// parse a local variable declaration
|
||||
fn parse_local(&self) -> @Local {
|
||||
fn parse_local(&mut self) -> @Local {
|
||||
let lo = self.span.lo;
|
||||
let pat = self.parse_pat();
|
||||
|
||||
@@ -3193,22 +3188,22 @@ fn parse_local(&self) -> @Local {
|
||||
}
|
||||
|
||||
// parse a "let" stmt
|
||||
fn parse_let(&self) -> @Decl {
|
||||
fn parse_let(&mut self) -> @Decl {
|
||||
let lo = self.span.lo;
|
||||
let local = self.parse_local();
|
||||
while self.eat(&token::COMMA) {
|
||||
let _ = self.parse_local();
|
||||
self.obsolete(*self.span, ObsoleteMultipleLocalDecl);
|
||||
self.obsolete(self.span, ObsoleteMultipleLocalDecl);
|
||||
}
|
||||
return @spanned(lo, self.last_span.hi, DeclLocal(local));
|
||||
}
|
||||
|
||||
// parse a structure field
|
||||
fn parse_name_and_ty(&self,
|
||||
fn parse_name_and_ty(&mut self,
|
||||
pr: visibility,
|
||||
attrs: ~[Attribute]) -> struct_field {
|
||||
let lo = self.span.lo;
|
||||
if !is_plain_ident(&*self.token) {
|
||||
if !is_plain_ident(&self.token) {
|
||||
self.fatal("expected ident");
|
||||
}
|
||||
let name = self.parse_ident();
|
||||
@@ -3224,13 +3219,13 @@ fn parse_name_and_ty(&self,
|
||||
|
||||
// parse a statement. may include decl.
|
||||
// precondition: any attributes are parsed already
|
||||
pub fn parse_stmt(&self, item_attrs: ~[Attribute]) -> @Stmt {
|
||||
pub fn parse_stmt(&mut self, item_attrs: ~[Attribute]) -> @Stmt {
|
||||
maybe_whole!(self, nt_stmt);
|
||||
|
||||
fn check_expected_item(p: &Parser, found_attrs: bool) {
|
||||
fn check_expected_item(p: &mut Parser, found_attrs: bool) {
|
||||
// If we have attributes then we should have an item
|
||||
if found_attrs {
|
||||
p.span_err(*p.last_span, "expected item after attributes");
|
||||
p.span_err(p.last_span, "expected item after attributes");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3240,8 +3235,8 @@ fn check_expected_item(p: &Parser, found_attrs: bool) {
|
||||
self.expect_keyword(keywords::Let);
|
||||
let decl = self.parse_let();
|
||||
return @spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID));
|
||||
} else if is_ident(&*self.token)
|
||||
&& !token::is_any_keyword(self.token)
|
||||
} else if is_ident(&self.token)
|
||||
&& !token::is_any_keyword(&self.token)
|
||||
&& self.look_ahead(1, |t| *t == token::NOT) {
|
||||
// parse a macro invocation. Looks like there's serious
|
||||
// overlap here; if this clause doesn't catch it (and it
|
||||
@@ -3263,7 +3258,7 @@ fn check_expected_item(p: &Parser, found_attrs: bool) {
|
||||
let pth = self.parse_path(NoTypesAllowed).path;
|
||||
self.bump();
|
||||
|
||||
let id = if *self.token == token::LPAREN {
|
||||
let id = if self.token == token::LPAREN {
|
||||
token::special_idents::invalid // no special identifier
|
||||
} else {
|
||||
self.parse_ident()
|
||||
@@ -3318,18 +3313,18 @@ fn check_expected_item(p: &Parser, found_attrs: bool) {
|
||||
}
|
||||
|
||||
// is this expression a successfully-parsed statement?
|
||||
fn expr_is_complete(&self, e: @Expr) -> bool {
|
||||
return *self.restriction == RESTRICT_STMT_EXPR &&
|
||||
fn expr_is_complete(&mut self, e: @Expr) -> bool {
|
||||
return self.restriction == RESTRICT_STMT_EXPR &&
|
||||
!classify::expr_requires_semi_to_be_stmt(e);
|
||||
}
|
||||
|
||||
// parse a block. No inner attrs are allowed.
|
||||
pub fn parse_block(&self) -> P<Block> {
|
||||
pub fn parse_block(&mut self) -> P<Block> {
|
||||
maybe_whole!(no_clone self, nt_block);
|
||||
|
||||
let lo = self.span.lo;
|
||||
if self.eat_keyword(keywords::Unsafe) {
|
||||
self.obsolete(*self.span, ObsoleteUnsafeBlock);
|
||||
self.obsolete(self.span, ObsoleteUnsafeBlock);
|
||||
}
|
||||
self.expect(&token::LBRACE);
|
||||
|
||||
@@ -3337,14 +3332,14 @@ pub fn parse_block(&self) -> P<Block> {
|
||||
}
|
||||
|
||||
// parse a block. Inner attrs are allowed.
|
||||
fn parse_inner_attrs_and_block(&self)
|
||||
fn parse_inner_attrs_and_block(&mut self)
|
||||
-> (~[Attribute], P<Block>) {
|
||||
|
||||
maybe_whole!(pair_empty self, nt_block);
|
||||
|
||||
let lo = self.span.lo;
|
||||
if self.eat_keyword(keywords::Unsafe) {
|
||||
self.obsolete(*self.span, ObsoleteUnsafeBlock);
|
||||
self.obsolete(self.span, ObsoleteUnsafeBlock);
|
||||
}
|
||||
self.expect(&token::LBRACE);
|
||||
let (inner, next) = self.parse_inner_attrs_and_next();
|
||||
@@ -3356,12 +3351,12 @@ fn parse_inner_attrs_and_block(&self)
|
||||
// I guess that also means "already parsed the 'impure'" if
|
||||
// necessary, and this should take a qualifier.
|
||||
// some blocks start with "#{"...
|
||||
fn parse_block_tail(&self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
|
||||
fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
|
||||
self.parse_block_tail_(lo, s, ~[])
|
||||
}
|
||||
|
||||
// parse the rest of a block expression or function body
|
||||
fn parse_block_tail_(&self, lo: BytePos, s: BlockCheckMode,
|
||||
fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
|
||||
first_item_attrs: ~[Attribute]) -> P<Block> {
|
||||
let mut stmts = ~[];
|
||||
let mut expr = None;
|
||||
@@ -3383,14 +3378,14 @@ fn parse_block_tail_(&self, lo: BytePos, s: BlockCheckMode,
|
||||
|
||||
let mut attributes_box = attrs_remaining;
|
||||
|
||||
while (*self.token != token::RBRACE) {
|
||||
while (self.token != token::RBRACE) {
|
||||
// parsing items even when they're not allowed lets us give
|
||||
// better error messages and recover more gracefully.
|
||||
attributes_box.push_all(self.parse_outer_attributes());
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::SEMI => {
|
||||
if !attributes_box.is_empty() {
|
||||
self.span_err(*self.last_span, "expected item after attributes");
|
||||
self.span_err(self.last_span, "expected item after attributes");
|
||||
attributes_box = ~[];
|
||||
}
|
||||
self.bump(); // empty
|
||||
@@ -3409,7 +3404,7 @@ fn parse_block_tail_(&self, lo: BytePos, s: BlockCheckMode,
|
||||
self.commit_stmt(stmt, &[], &[token::SEMI, token::RBRACE]);
|
||||
}
|
||||
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::SEMI => {
|
||||
self.bump();
|
||||
stmts.push(@codemap::Spanned {
|
||||
@@ -3428,7 +3423,7 @@ fn parse_block_tail_(&self, lo: BytePos, s: BlockCheckMode,
|
||||
StmtMac(ref m, _) => {
|
||||
// statement macro; might be an expr
|
||||
let has_semi;
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::SEMI => {
|
||||
has_semi = true;
|
||||
}
|
||||
@@ -3468,7 +3463,7 @@ fn parse_block_tail_(&self, lo: BytePos, s: BlockCheckMode,
|
||||
}
|
||||
|
||||
if !attributes_box.is_empty() {
|
||||
self.span_err(*self.last_span, "expected item after attributes");
|
||||
self.span_err(self.last_span, "expected item after attributes");
|
||||
}
|
||||
|
||||
let hi = self.span.hi;
|
||||
@@ -3490,19 +3485,19 @@ fn parse_block_tail_(&self, lo: BytePos, s: BlockCheckMode,
|
||||
// Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:")
|
||||
// Returns "Some(stuff)" otherwise (e.g. "T:stuff").
|
||||
// NB: The None/Some distinction is important for issue #7264.
|
||||
fn parse_optional_ty_param_bounds(&self) -> Option<OptVec<TyParamBound>> {
|
||||
fn parse_optional_ty_param_bounds(&mut self) -> Option<OptVec<TyParamBound>> {
|
||||
if !self.eat(&token::COLON) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut result = opt_vec::Empty;
|
||||
loop {
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::LIFETIME(lifetime) => {
|
||||
if "static" == self.id_to_str(lifetime) {
|
||||
result.push(RegionTyParamBound);
|
||||
} else {
|
||||
self.span_err(*self.span,
|
||||
self.span_err(self.span,
|
||||
"`'static` is the only permissible region bound here");
|
||||
}
|
||||
self.bump();
|
||||
@@ -3523,7 +3518,7 @@ fn parse_optional_ty_param_bounds(&self) -> Option<OptVec<TyParamBound>> {
|
||||
}
|
||||
|
||||
// matches typaram = IDENT optbounds
|
||||
fn parse_ty_param(&self) -> TyParam {
|
||||
fn parse_ty_param(&mut self) -> TyParam {
|
||||
let ident = self.parse_ident();
|
||||
let opt_bounds = self.parse_optional_ty_param_bounds();
|
||||
// For typarams we don't care about the difference b/w "<T>" and "<T:>".
|
||||
@@ -3535,7 +3530,7 @@ fn parse_ty_param(&self) -> TyParam {
|
||||
// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
|
||||
// | ( < lifetimes , typaramseq ( , )? > )
|
||||
// where typaramseq = ( typaram ) | ( typaram , typaramseq )
|
||||
pub fn parse_generics(&self) -> ast::Generics {
|
||||
pub fn parse_generics(&mut self) -> ast::Generics {
|
||||
if self.eat(&token::LT) {
|
||||
let lifetimes = self.parse_lifetimes();
|
||||
let ty_params = self.parse_seq_to_gt(
|
||||
@@ -3547,7 +3542,7 @@ pub fn parse_generics(&self) -> ast::Generics {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_generic_values_after_lt(&self) -> (OptVec<ast::Lifetime>, ~[P<Ty>]) {
|
||||
fn parse_generic_values_after_lt(&mut self) -> (OptVec<ast::Lifetime>, ~[P<Ty>]) {
|
||||
let lifetimes = self.parse_lifetimes();
|
||||
let result = self.parse_seq_to_gt(
|
||||
Some(token::COMMA),
|
||||
@@ -3555,23 +3550,24 @@ fn parse_generic_values_after_lt(&self) -> (OptVec<ast::Lifetime>, ~[P<Ty>]) {
|
||||
(lifetimes, opt_vec::take_vec(result))
|
||||
}
|
||||
|
||||
fn parse_fn_args(&self, named_args: bool, allow_variadic: bool) -> (~[arg], bool) {
|
||||
let sp = *self.span;
|
||||
fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
|
||||
-> (~[arg], bool) {
|
||||
let sp = self.span;
|
||||
let mut args: ~[Option<arg>] =
|
||||
self.parse_unspanned_seq(
|
||||
&token::LPAREN,
|
||||
&token::RPAREN,
|
||||
seq_sep_trailing_disallowed(token::COMMA),
|
||||
|p| {
|
||||
if *p.token == token::DOTDOTDOT {
|
||||
if p.token == token::DOTDOTDOT {
|
||||
p.bump();
|
||||
if allow_variadic {
|
||||
if *p.token != token::RPAREN {
|
||||
p.span_fatal(*p.span,
|
||||
if p.token != token::RPAREN {
|
||||
p.span_fatal(p.span,
|
||||
"`...` must be last in argument list for variadic function");
|
||||
}
|
||||
} else {
|
||||
p.span_fatal(*p.span,
|
||||
p.span_fatal(p.span,
|
||||
"only foreign functions are allowed to be variadic");
|
||||
}
|
||||
None
|
||||
@@ -3602,7 +3598,7 @@ fn parse_fn_args(&self, named_args: bool, allow_variadic: bool) -> (~[arg], bool
|
||||
}
|
||||
|
||||
// parse the argument list and result type of a function declaration
|
||||
pub fn parse_fn_decl(&self, allow_variadic: bool) -> P<fn_decl> {
|
||||
pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P<fn_decl> {
|
||||
|
||||
let (args, variadic) = self.parse_fn_args(true, allow_variadic);
|
||||
let (ret_style, ret_ty) = self.parse_ret_ty();
|
||||
@@ -3615,32 +3611,28 @@ pub fn parse_fn_decl(&self, allow_variadic: bool) -> P<fn_decl> {
|
||||
})
|
||||
}
|
||||
|
||||
fn is_self_ident(&self) -> bool {
|
||||
match *self.token {
|
||||
fn is_self_ident(&mut self) -> bool {
|
||||
match self.token {
|
||||
token::IDENT(id, false) => id.name == special_idents::self_.name,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn expect_self_ident(&self) {
|
||||
fn expect_self_ident(&mut self) {
|
||||
if !self.is_self_ident() {
|
||||
self.fatal(
|
||||
format!(
|
||||
"expected `self` but found `{}`",
|
||||
self.this_token_to_str()
|
||||
)
|
||||
);
|
||||
let token_str = self.this_token_to_str();
|
||||
self.fatal(format!("expected `self` but found `{}`", token_str))
|
||||
}
|
||||
self.bump();
|
||||
}
|
||||
|
||||
// parse the argument list and result type of a function
|
||||
// that may have a self type.
|
||||
fn parse_fn_decl_with_self(&self, parse_arg_fn: |&Parser| -> arg)
|
||||
fn parse_fn_decl_with_self(&mut self, parse_arg_fn: |&mut Parser| -> arg)
|
||||
-> (explicit_self, P<fn_decl>) {
|
||||
fn maybe_parse_explicit_self(cnstr: |v: Mutability| ->
|
||||
ast::explicit_self_,
|
||||
p: &Parser)
|
||||
p: &mut Parser)
|
||||
-> ast::explicit_self_ {
|
||||
// We need to make sure it isn't a type
|
||||
if p.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) ||
|
||||
@@ -3657,10 +3649,11 @@ fn maybe_parse_explicit_self(cnstr: |v: Mutability| ->
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
|
||||
fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
|
||||
-> ast::explicit_self_ {
|
||||
// The following things are possible to see here:
|
||||
//
|
||||
// fn(&self)
|
||||
// fn(&mut self)
|
||||
// fn(&mut self)
|
||||
// fn(&'lt self)
|
||||
// fn(&'lt mut self)
|
||||
@@ -3671,7 +3664,7 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
|
||||
this.bump();
|
||||
this.expect_self_ident();
|
||||
sty_region(None, MutImmutable)
|
||||
} else if this.look_ahead(1, |t| this.token_is_mutability(t)) &&
|
||||
} else if this.look_ahead(1, |t| Parser::token_is_mutability(t)) &&
|
||||
this.look_ahead(2,
|
||||
|t| token::is_keyword(keywords::Self,
|
||||
t)) {
|
||||
@@ -3679,7 +3672,7 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
|
||||
let mutability = this.parse_mutability();
|
||||
this.expect_self_ident();
|
||||
sty_region(None, mutability)
|
||||
} else if this.look_ahead(1, |t| this.token_is_lifetime(t)) &&
|
||||
} else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
|
||||
this.look_ahead(2,
|
||||
|t| token::is_keyword(keywords::Self,
|
||||
t)) {
|
||||
@@ -3687,8 +3680,10 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
|
||||
let lifetime = this.parse_lifetime();
|
||||
this.expect_self_ident();
|
||||
sty_region(Some(lifetime), MutImmutable)
|
||||
} else if this.look_ahead(1, |t| this.token_is_lifetime(t)) &&
|
||||
this.look_ahead(2, |t| this.token_is_mutability(t)) &&
|
||||
} else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
|
||||
this.look_ahead(2, |t| {
|
||||
Parser::token_is_mutability(t)
|
||||
}) &&
|
||||
this.look_ahead(3, |t| token::is_keyword(keywords::Self,
|
||||
t)) {
|
||||
this.bump();
|
||||
@@ -3706,7 +3701,7 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
|
||||
// A bit of complexity and lookahead is needed here in order to be
|
||||
// backwards compatible.
|
||||
let lo = self.span.lo;
|
||||
let explicit_self = match *self.token {
|
||||
let explicit_self = match self.token {
|
||||
token::BINOP(token::AND) => {
|
||||
maybe_parse_borrowed_explicit_self(self)
|
||||
}
|
||||
@@ -3716,7 +3711,7 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
|
||||
token::TILDE => {
|
||||
maybe_parse_explicit_self(|mutability| {
|
||||
if mutability != MutImmutable {
|
||||
self.span_err(*self.last_span,
|
||||
self.span_err(self.last_span,
|
||||
"mutability declaration not allowed here");
|
||||
}
|
||||
sty_uniq(MutImmutable)
|
||||
@@ -3730,22 +3725,22 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
|
||||
// Possibly "*self" or "*mut self" -- not supported. Try to avoid
|
||||
// emitting cryptic "unexpected token" errors.
|
||||
self.bump();
|
||||
let mutability = if self.token_is_mutability(self.token) {
|
||||
let mutability = if Parser::token_is_mutability(&self.token) {
|
||||
self.parse_mutability()
|
||||
} else { MutImmutable };
|
||||
if self.is_self_ident() {
|
||||
self.span_err(*self.span, "cannot pass self by unsafe pointer");
|
||||
self.span_err(self.span, "cannot pass self by unsafe pointer");
|
||||
self.bump();
|
||||
}
|
||||
sty_value(mutability)
|
||||
}
|
||||
_ if self.token_is_mutability(self.token) &&
|
||||
_ if Parser::token_is_mutability(&self.token) &&
|
||||
self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
|
||||
let mutability = self.parse_mutability();
|
||||
self.expect_self_ident();
|
||||
sty_value(mutability)
|
||||
}
|
||||
_ if self.token_is_mutability(self.token) &&
|
||||
_ if Parser::token_is_mutability(&self.token) &&
|
||||
self.look_ahead(1, |t| *t == token::TILDE) &&
|
||||
self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => {
|
||||
let mutability = self.parse_mutability();
|
||||
@@ -3761,7 +3756,7 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
|
||||
// If we parsed a self type, expect a comma before the argument list.
|
||||
let fn_inputs;
|
||||
if explicit_self != sty_static {
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::COMMA => {
|
||||
self.bump();
|
||||
let sep = seq_sep_trailing_disallowed(token::COMMA);
|
||||
@@ -3775,21 +3770,16 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
|
||||
fn_inputs = ~[];
|
||||
}
|
||||
_ => {
|
||||
self.fatal(
|
||||
format!(
|
||||
"expected `,` or `)`, found `{}`",
|
||||
self.this_token_to_str()
|
||||
)
|
||||
);
|
||||
let token_str = self.this_token_to_str();
|
||||
self.fatal(format!("expected `,` or `)`, found `{}`",
|
||||
token_str))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let sep = seq_sep_trailing_disallowed(token::COMMA);
|
||||
fn_inputs = self.parse_seq_to_before_end(
|
||||
&token::RPAREN,
|
||||
sep,
|
||||
parse_arg_fn
|
||||
);
|
||||
fn_inputs = self.parse_seq_to_before_end(&token::RPAREN,
|
||||
sep,
|
||||
parse_arg_fn);
|
||||
}
|
||||
|
||||
self.expect(&token::RPAREN);
|
||||
@@ -3809,7 +3799,7 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
|
||||
}
|
||||
|
||||
// parse the |arg, arg| header on a lambda
|
||||
fn parse_fn_block_decl(&self) -> P<fn_decl> {
|
||||
fn parse_fn_block_decl(&mut self) -> P<fn_decl> {
|
||||
let inputs_captures = {
|
||||
if self.eat(&token::OROR) {
|
||||
~[]
|
||||
@@ -3825,7 +3815,11 @@ fn parse_fn_block_decl(&self) -> P<fn_decl> {
|
||||
let output = if self.eat(&token::RARROW) {
|
||||
self.parse_ty(false)
|
||||
} else {
|
||||
P(Ty { id: ast::DUMMY_NODE_ID, node: ty_infer, span: *self.span })
|
||||
P(Ty {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ty_infer,
|
||||
span: self.span,
|
||||
})
|
||||
};
|
||||
|
||||
P(ast::fn_decl {
|
||||
@@ -3837,7 +3831,7 @@ fn parse_fn_block_decl(&self) -> P<fn_decl> {
|
||||
}
|
||||
|
||||
// Parses the `(arg, arg) -> return_type` header on a procedure.
|
||||
fn parse_proc_decl(&self) -> P<fn_decl> {
|
||||
fn parse_proc_decl(&mut self) -> P<fn_decl> {
|
||||
let inputs =
|
||||
self.parse_unspanned_seq(&token::LPAREN,
|
||||
&token::RPAREN,
|
||||
@@ -3850,7 +3844,7 @@ fn parse_proc_decl(&self) -> P<fn_decl> {
|
||||
P(Ty {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ty_infer,
|
||||
span: *self.span,
|
||||
span: self.span,
|
||||
})
|
||||
};
|
||||
|
||||
@@ -3863,13 +3857,13 @@ fn parse_proc_decl(&self) -> P<fn_decl> {
|
||||
}
|
||||
|
||||
// parse the name and optional generic types of a function header.
|
||||
fn parse_fn_header(&self) -> (Ident, ast::Generics) {
|
||||
fn parse_fn_header(&mut self) -> (Ident, ast::Generics) {
|
||||
let id = self.parse_ident();
|
||||
let generics = self.parse_generics();
|
||||
(id, generics)
|
||||
}
|
||||
|
||||
fn mk_item(&self, lo: BytePos, hi: BytePos, ident: Ident,
|
||||
fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident,
|
||||
node: item_, vis: visibility,
|
||||
attrs: ~[Attribute]) -> @item {
|
||||
@ast::item { ident: ident,
|
||||
@@ -3881,7 +3875,7 @@ fn mk_item(&self, lo: BytePos, hi: BytePos, ident: Ident,
|
||||
}
|
||||
|
||||
// parse an item-position function declaration.
|
||||
fn parse_item_fn(&self, purity: purity, abis: AbiSet) -> item_info {
|
||||
fn parse_item_fn(&mut self, purity: purity, abis: AbiSet) -> item_info {
|
||||
let (ident, generics) = self.parse_fn_header();
|
||||
let decl = self.parse_fn_decl(false);
|
||||
let (inner_attrs, body) = self.parse_inner_attrs_and_block();
|
||||
@@ -3891,7 +3885,7 @@ fn parse_item_fn(&self, purity: purity, abis: AbiSet) -> item_info {
|
||||
}
|
||||
|
||||
// parse a method in a trait impl, starting with `attrs` attributes.
|
||||
fn parse_method(&self, already_parsed_attrs: Option<~[Attribute]>) -> @method {
|
||||
fn parse_method(&mut self, already_parsed_attrs: Option<~[Attribute]>) -> @method {
|
||||
let next_attrs = self.parse_outer_attributes();
|
||||
let attrs = match already_parsed_attrs {
|
||||
Some(mut a) => { a.push_all_move(next_attrs); a }
|
||||
@@ -3927,13 +3921,13 @@ fn parse_method(&self, already_parsed_attrs: Option<~[Attribute]>) -> @method {
|
||||
}
|
||||
|
||||
// parse trait Foo { ... }
|
||||
fn parse_item_trait(&self) -> item_info {
|
||||
fn parse_item_trait(&mut self) -> item_info {
|
||||
let ident = self.parse_ident();
|
||||
let tps = self.parse_generics();
|
||||
|
||||
// Parse traits, if necessary.
|
||||
let traits;
|
||||
if *self.token == token::COLON {
|
||||
if self.token == token::COLON {
|
||||
self.bump();
|
||||
traits = self.parse_trait_ref_list(&token::LBRACE);
|
||||
} else {
|
||||
@@ -3947,7 +3941,7 @@ fn parse_item_trait(&self) -> item_info {
|
||||
// Parses two variants (with the region/type params always optional):
|
||||
// impl<T> Foo { ... }
|
||||
// impl<T> ToStr for ~[T] { ... }
|
||||
fn parse_item_impl(&self) -> item_info {
|
||||
fn parse_item_impl(&mut self) -> item_info {
|
||||
// First, parse type parameters if necessary.
|
||||
let generics = self.parse_generics();
|
||||
|
||||
@@ -3957,7 +3951,7 @@ fn parse_item_impl(&self) -> item_info {
|
||||
|
||||
// Special case: if the next identifier that follows is '(', don't
|
||||
// allow this to be parsed as a trait.
|
||||
let could_be_trait = *self.token != token::LPAREN;
|
||||
let could_be_trait = self.token != token::LPAREN;
|
||||
|
||||
// Parse the trait.
|
||||
let mut ty = self.parse_ty(false);
|
||||
@@ -3991,7 +3985,7 @@ fn parse_item_impl(&self) -> item_info {
|
||||
|
||||
let mut meths = ~[];
|
||||
let inner_attrs = if self.eat(&token::SEMI) {
|
||||
self.obsolete(*self.last_span, ObsoleteEmptyImpl);
|
||||
self.obsolete(self.last_span, ObsoleteEmptyImpl);
|
||||
None
|
||||
} else {
|
||||
self.expect(&token::LBRACE);
|
||||
@@ -4008,7 +4002,7 @@ fn parse_item_impl(&self) -> item_info {
|
||||
}
|
||||
|
||||
// parse a::B<~str,int>
|
||||
fn parse_trait_ref(&self) -> trait_ref {
|
||||
fn parse_trait_ref(&mut self) -> trait_ref {
|
||||
ast::trait_ref {
|
||||
path: self.parse_path(LifetimeAndTypesWithoutColons).path,
|
||||
ref_id: ast::DUMMY_NODE_ID,
|
||||
@@ -4016,7 +4010,7 @@ fn parse_trait_ref(&self) -> trait_ref {
|
||||
}
|
||||
|
||||
// parse B + C<~str,int> + D
|
||||
fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[trait_ref] {
|
||||
fn parse_trait_ref_list(&mut self, ket: &token::Token) -> ~[trait_ref] {
|
||||
self.parse_seq_to_before_end(
|
||||
ket,
|
||||
seq_sep_trailing_disallowed(token::BINOP(token::PLUS)),
|
||||
@@ -4025,7 +4019,7 @@ fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[trait_ref] {
|
||||
}
|
||||
|
||||
// parse struct Foo { ... }
|
||||
fn parse_item_struct(&self) -> item_info {
|
||||
fn parse_item_struct(&mut self) -> item_info {
|
||||
let class_name = self.parse_ident();
|
||||
let generics = self.parse_generics();
|
||||
|
||||
@@ -4036,7 +4030,7 @@ fn parse_item_struct(&self) -> item_info {
|
||||
// It's a record-like struct.
|
||||
is_tuple_like = false;
|
||||
fields = ~[];
|
||||
while *self.token != token::RBRACE {
|
||||
while self.token != token::RBRACE {
|
||||
fields.push(self.parse_struct_decl_field());
|
||||
}
|
||||
if fields.len() == 0 {
|
||||
@@ -4044,7 +4038,7 @@ fn parse_item_struct(&self) -> item_info {
|
||||
get_ident_interner().get(class_name.name)));
|
||||
}
|
||||
self.bump();
|
||||
} else if *self.token == token::LPAREN {
|
||||
} else if self.token == token::LPAREN {
|
||||
// It's a tuple-like struct.
|
||||
is_tuple_like = true;
|
||||
fields = self.parse_unspanned_seq(
|
||||
@@ -4052,7 +4046,7 @@ fn parse_item_struct(&self) -> item_info {
|
||||
&token::RPAREN,
|
||||
seq_sep_trailing_allowed(token::COMMA),
|
||||
|p| {
|
||||
let attrs = self.parse_outer_attributes();
|
||||
let attrs = p.parse_outer_attributes();
|
||||
let lo = p.span.lo;
|
||||
let struct_field_ = ast::struct_field_ {
|
||||
kind: unnamed_field,
|
||||
@@ -4068,13 +4062,10 @@ fn parse_item_struct(&self) -> item_info {
|
||||
is_tuple_like = true;
|
||||
fields = ~[];
|
||||
} else {
|
||||
self.fatal(
|
||||
format!(
|
||||
"expected `\\{`, `(`, or `;` after struct name \
|
||||
but found `{}`",
|
||||
self.this_token_to_str()
|
||||
)
|
||||
);
|
||||
let token_str = self.this_token_to_str();
|
||||
self.fatal(format!("expected `\\{`, `(`, or `;` after struct \
|
||||
name but found `{}`",
|
||||
token_str))
|
||||
}
|
||||
|
||||
let _ = ast::DUMMY_NODE_ID; // XXX: Workaround for crazy bug.
|
||||
@@ -4088,27 +4079,28 @@ fn parse_item_struct(&self) -> item_info {
|
||||
}
|
||||
|
||||
// parse a structure field declaration
|
||||
pub fn parse_single_struct_field(&self,
|
||||
pub fn parse_single_struct_field(&mut self,
|
||||
vis: visibility,
|
||||
attrs: ~[Attribute])
|
||||
-> struct_field {
|
||||
let a_var = self.parse_name_and_ty(vis, attrs);
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::COMMA => {
|
||||
self.bump();
|
||||
}
|
||||
token::RBRACE => {}
|
||||
_ => {
|
||||
self.span_fatal(*self.span,
|
||||
let token_str = self.this_token_to_str();
|
||||
self.span_fatal(self.span,
|
||||
format!("expected `,`, or `\\}` but found `{}`",
|
||||
self.this_token_to_str()));
|
||||
token_str))
|
||||
}
|
||||
}
|
||||
a_var
|
||||
}
|
||||
|
||||
// parse an element of a struct definition
|
||||
fn parse_struct_decl_field(&self) -> struct_field {
|
||||
fn parse_struct_decl_field(&mut self) -> struct_field {
|
||||
|
||||
let attrs = self.parse_outer_attributes();
|
||||
|
||||
@@ -4124,7 +4116,7 @@ fn parse_struct_decl_field(&self) -> struct_field {
|
||||
}
|
||||
|
||||
// parse visiility: PUB, PRIV, or nothing
|
||||
fn parse_visibility(&self) -> visibility {
|
||||
fn parse_visibility(&mut self) -> visibility {
|
||||
if self.eat_keyword(keywords::Pub) { public }
|
||||
else if self.eat_keyword(keywords::Priv) { private }
|
||||
else { inherited }
|
||||
@@ -4132,7 +4124,7 @@ fn parse_visibility(&self) -> visibility {
|
||||
|
||||
// given a termination token and a vector of already-parsed
|
||||
// attributes (of length 0 or 1), parse all of the items in a module
|
||||
fn parse_mod_items(&self,
|
||||
fn parse_mod_items(&mut self,
|
||||
term: token::Token,
|
||||
first_item_attrs: ~[Attribute])
|
||||
-> _mod {
|
||||
@@ -4150,7 +4142,7 @@ fn parse_mod_items(&self,
|
||||
// don't think this other loop is even necessary....
|
||||
|
||||
let mut first = true;
|
||||
while *self.token != term {
|
||||
while self.token != term {
|
||||
let mut attrs = self.parse_outer_attributes();
|
||||
if first {
|
||||
attrs = attrs_remaining + attrs;
|
||||
@@ -4167,21 +4159,22 @@ fn parse_mod_items(&self,
|
||||
the module");
|
||||
}
|
||||
_ => {
|
||||
self.fatal(format!("expected item but found `{}`",
|
||||
self.this_token_to_str()));
|
||||
let token_str = self.this_token_to_str();
|
||||
self.fatal(format!("expected item but found `{}`",
|
||||
token_str))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if first && attrs_remaining_len > 0u {
|
||||
// We parsed attributes for the first item but didn't find it
|
||||
self.span_err(*self.last_span, "expected item after attributes");
|
||||
self.span_err(self.last_span, "expected item after attributes");
|
||||
}
|
||||
|
||||
ast::_mod { view_items: view_items, items: items }
|
||||
}
|
||||
|
||||
fn parse_item_const(&self) -> item_info {
|
||||
fn parse_item_const(&mut self) -> item_info {
|
||||
let m = if self.eat_keyword(keywords::Mut) {MutMutable} else {MutImmutable};
|
||||
let id = self.parse_ident();
|
||||
self.expect(&token::COLON);
|
||||
@@ -4193,10 +4186,10 @@ fn parse_item_const(&self) -> item_info {
|
||||
}
|
||||
|
||||
// parse a `mod <foo> { ... }` or `mod <foo>;` item
|
||||
fn parse_item_mod(&self, outer_attrs: &[Attribute]) -> item_info {
|
||||
let id_span = *self.span;
|
||||
fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> item_info {
|
||||
let id_span = self.span;
|
||||
let id = self.parse_ident();
|
||||
if *self.token == token::SEMI {
|
||||
if self.token == token::SEMI {
|
||||
self.bump();
|
||||
// This mod is in an external file. Let's go get it!
|
||||
let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span);
|
||||
@@ -4212,7 +4205,7 @@ fn parse_item_mod(&self, outer_attrs: &[Attribute]) -> item_info {
|
||||
}
|
||||
}
|
||||
|
||||
fn push_mod_path(&self, id: Ident, attrs: &[Attribute]) {
|
||||
fn push_mod_path(&mut self, id: Ident, attrs: &[Attribute]) {
|
||||
let default_path = token::interner_get(id.name);
|
||||
let file_path = match ::attr::first_attr_value_str_by_name(attrs,
|
||||
"path") {
|
||||
@@ -4222,20 +4215,19 @@ fn push_mod_path(&self, id: Ident, attrs: &[Attribute]) {
|
||||
self.mod_path_stack.push(file_path)
|
||||
}
|
||||
|
||||
fn pop_mod_path(&self) {
|
||||
fn pop_mod_path(&mut self) {
|
||||
self.mod_path_stack.pop();
|
||||
}
|
||||
|
||||
// read a module from a source file.
|
||||
fn eval_src_mod(&self,
|
||||
fn eval_src_mod(&mut self,
|
||||
id: ast::Ident,
|
||||
outer_attrs: &[ast::Attribute],
|
||||
id_sp: Span)
|
||||
-> (ast::item_, ~[ast::Attribute]) {
|
||||
let mut prefix = Path::new(self.sess.cm.span_to_filename(*self.span));
|
||||
let mut prefix = Path::new(self.sess.cm.span_to_filename(self.span));
|
||||
prefix.pop();
|
||||
let mod_path_stack = &*self.mod_path_stack;
|
||||
let mod_path = Path::new(".").join_many(*mod_path_stack);
|
||||
let mod_path = Path::new(".").join_many(self.mod_path_stack);
|
||||
let dir_path = prefix.join(&mod_path);
|
||||
let file_path = match ::attr::first_attr_value_str_by_name(
|
||||
outer_attrs, "path") {
|
||||
@@ -4268,7 +4260,7 @@ fn eval_src_mod(&self,
|
||||
id_sp)
|
||||
}
|
||||
|
||||
fn eval_src_mod_from_path(&self,
|
||||
fn eval_src_mod_from_path(&mut self,
|
||||
path: Path,
|
||||
outer_attrs: ~[ast::Attribute],
|
||||
id_sp: Span) -> (ast::item_, ~[ast::Attribute]) {
|
||||
@@ -4288,7 +4280,7 @@ fn eval_src_mod_from_path(&self,
|
||||
}
|
||||
self.sess.included_mod_stack.push(path.clone());
|
||||
|
||||
let p0 =
|
||||
let mut p0 =
|
||||
new_sub_parser_from_file(self.sess,
|
||||
self.cfg.clone(),
|
||||
&path,
|
||||
@@ -4302,14 +4294,14 @@ fn eval_src_mod_from_path(&self,
|
||||
}
|
||||
|
||||
// parse a function declaration from a foreign module
|
||||
fn parse_item_foreign_fn(&self, vis: ast::visibility,
|
||||
fn parse_item_foreign_fn(&mut self, vis: ast::visibility,
|
||||
attrs: ~[Attribute]) -> @foreign_item {
|
||||
let lo = self.span.lo;
|
||||
|
||||
// Parse obsolete purity.
|
||||
let purity = self.parse_fn_purity();
|
||||
if purity != impure_fn {
|
||||
self.obsolete(*self.last_span, ObsoleteUnsafeExternFn);
|
||||
self.obsolete(self.last_span, ObsoleteUnsafeExternFn);
|
||||
}
|
||||
|
||||
let (ident, generics) = self.parse_fn_header();
|
||||
@@ -4325,7 +4317,7 @@ fn parse_item_foreign_fn(&self, vis: ast::visibility,
|
||||
}
|
||||
|
||||
// parse a static item from a foreign module
|
||||
fn parse_item_foreign_static(&self, vis: ast::visibility,
|
||||
fn parse_item_foreign_static(&mut self, vis: ast::visibility,
|
||||
attrs: ~[Attribute]) -> @foreign_item {
|
||||
let lo = self.span.lo;
|
||||
|
||||
@@ -4346,7 +4338,7 @@ fn parse_item_foreign_static(&self, vis: ast::visibility,
|
||||
}
|
||||
|
||||
// parse safe/unsafe and fn
|
||||
fn parse_fn_purity(&self) -> purity {
|
||||
fn parse_fn_purity(&mut self) -> purity {
|
||||
if self.eat_keyword(keywords::Fn) { impure_fn }
|
||||
else if self.eat_keyword(keywords::Unsafe) {
|
||||
self.expect_keyword(keywords::Fn);
|
||||
@@ -4358,7 +4350,7 @@ fn parse_fn_purity(&self) -> purity {
|
||||
|
||||
// at this point, this is essentially a wrapper for
|
||||
// parse_foreign_items.
|
||||
fn parse_foreign_mod_items(&self,
|
||||
fn parse_foreign_mod_items(&mut self,
|
||||
abis: AbiSet,
|
||||
first_item_attrs: ~[Attribute])
|
||||
-> foreign_mod {
|
||||
@@ -4369,10 +4361,10 @@ fn parse_foreign_mod_items(&self,
|
||||
foreign_items: foreign_items
|
||||
} = self.parse_foreign_items(first_item_attrs, true);
|
||||
if (! attrs_remaining.is_empty()) {
|
||||
self.span_err(*self.last_span,
|
||||
self.span_err(self.last_span,
|
||||
"expected item after attributes");
|
||||
}
|
||||
assert!(*self.token == token::RBRACE);
|
||||
assert!(self.token == token::RBRACE);
|
||||
ast::foreign_mod {
|
||||
abis: abis,
|
||||
view_items: view_items,
|
||||
@@ -4381,7 +4373,7 @@ fn parse_foreign_mod_items(&self,
|
||||
}
|
||||
|
||||
// parse extern foo; or extern mod foo { ... } or extern { ... }
|
||||
fn parse_item_foreign_mod(&self,
|
||||
fn parse_item_foreign_mod(&mut self,
|
||||
lo: BytePos,
|
||||
opt_abis: Option<AbiSet>,
|
||||
visibility: visibility,
|
||||
@@ -4392,16 +4384,17 @@ fn parse_item_foreign_mod(&self,
|
||||
if self.is_keyword(keywords::Mod) {
|
||||
must_be_named_mod = true;
|
||||
self.expect_keyword(keywords::Mod);
|
||||
} else if *self.token != token::LBRACE {
|
||||
self.span_fatal(*self.span,
|
||||
} else if self.token != token::LBRACE {
|
||||
let token_str = self.this_token_to_str();
|
||||
self.span_fatal(self.span,
|
||||
format!("expected `\\{` or `mod` but found `{}`",
|
||||
self.this_token_to_str()));
|
||||
token_str))
|
||||
}
|
||||
|
||||
let (named, maybe_path, ident) = match *self.token {
|
||||
let (named, maybe_path, ident) = match self.token {
|
||||
token::IDENT(..) => {
|
||||
let the_ident = self.parse_ident();
|
||||
let path = if *self.token == token::EQ {
|
||||
let path = if self.token == token::EQ {
|
||||
self.bump();
|
||||
Some(self.parse_str())
|
||||
}
|
||||
@@ -4410,10 +4403,11 @@ fn parse_item_foreign_mod(&self,
|
||||
}
|
||||
_ => {
|
||||
if must_be_named_mod {
|
||||
self.span_fatal(*self.span,
|
||||
let token_str = self.this_token_to_str();
|
||||
self.span_fatal(self.span,
|
||||
format!("expected foreign module name but \
|
||||
found `{}`",
|
||||
self.this_token_to_str()));
|
||||
found `{}`",
|
||||
token_str))
|
||||
}
|
||||
|
||||
(false, None,
|
||||
@@ -4425,7 +4419,7 @@ fn parse_item_foreign_mod(&self,
|
||||
if items_allowed && self.eat(&token::LBRACE) {
|
||||
// `extern mod foo { ... }` is obsolete.
|
||||
if named {
|
||||
self.obsolete(*self.last_span, ObsoleteNamedExternModule);
|
||||
self.obsolete(self.last_span, ObsoleteNamedExternModule);
|
||||
}
|
||||
|
||||
let abis = opt_abis.unwrap_or(AbiSet::C());
|
||||
@@ -4434,25 +4428,26 @@ fn parse_item_foreign_mod(&self,
|
||||
let m = self.parse_foreign_mod_items(abis, next);
|
||||
self.expect(&token::RBRACE);
|
||||
|
||||
return iovi_item(self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_foreign_mod(m),
|
||||
visibility,
|
||||
maybe_append(attrs, Some(inner))));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_foreign_mod(m),
|
||||
visibility,
|
||||
maybe_append(attrs, Some(inner)));
|
||||
return iovi_item(item);
|
||||
}
|
||||
|
||||
if opt_abis.is_some() {
|
||||
self.span_err(*self.span, "an ABI may not be specified here");
|
||||
self.span_err(self.span, "an ABI may not be specified here");
|
||||
}
|
||||
|
||||
|
||||
if *self.token == token::LPAREN {
|
||||
if self.token == token::LPAREN {
|
||||
// `extern mod foo (name = "bar"[,vers = "version"]) is obsolete,
|
||||
// `extern mod foo = "bar#[version]";` should be used.
|
||||
// Parse obsolete options to avoid wired parser errors
|
||||
self.parse_optional_meta();
|
||||
self.obsolete(*self.span, ObsoleteExternModAttributesInParens);
|
||||
self.obsolete(self.span, ObsoleteExternModAttributesInParens);
|
||||
}
|
||||
// extern mod foo;
|
||||
self.expect(&token::SEMI);
|
||||
@@ -4465,7 +4460,7 @@ fn parse_item_foreign_mod(&self,
|
||||
}
|
||||
|
||||
// parse type Foo = Bar;
|
||||
fn parse_item_type(&self) -> item_info {
|
||||
fn parse_item_type(&mut self) -> item_info {
|
||||
let ident = self.parse_ident();
|
||||
let tps = self.parse_generics();
|
||||
self.expect(&token::EQ);
|
||||
@@ -4476,9 +4471,9 @@ fn parse_item_type(&self) -> item_info {
|
||||
|
||||
// parse a structure-like enum variant definition
|
||||
// this should probably be renamed or refactored...
|
||||
fn parse_struct_def(&self) -> @struct_def {
|
||||
fn parse_struct_def(&mut self) -> @struct_def {
|
||||
let mut fields: ~[struct_field] = ~[];
|
||||
while *self.token != token::RBRACE {
|
||||
while self.token != token::RBRACE {
|
||||
fields.push(self.parse_struct_decl_field());
|
||||
}
|
||||
self.bump();
|
||||
@@ -4490,11 +4485,11 @@ fn parse_struct_def(&self) -> @struct_def {
|
||||
}
|
||||
|
||||
// parse the part of an "enum" decl following the '{'
|
||||
fn parse_enum_def(&self, _generics: &ast::Generics) -> enum_def {
|
||||
fn parse_enum_def(&mut self, _generics: &ast::Generics) -> enum_def {
|
||||
let mut variants = ~[];
|
||||
let mut all_nullary = true;
|
||||
let mut have_disr = false;
|
||||
while *self.token != token::RBRACE {
|
||||
while self.token != token::RBRACE {
|
||||
let variant_attrs = self.parse_outer_attributes();
|
||||
let vlo = self.span.lo;
|
||||
|
||||
@@ -4509,7 +4504,7 @@ fn parse_enum_def(&self, _generics: &ast::Generics) -> enum_def {
|
||||
// Parse a struct variant.
|
||||
all_nullary = false;
|
||||
kind = struct_variant_kind(self.parse_struct_def());
|
||||
} else if *self.token == token::LPAREN {
|
||||
} else if self.token == token::LPAREN {
|
||||
all_nullary = false;
|
||||
let arg_tys = self.parse_unspanned_seq(
|
||||
&token::LPAREN,
|
||||
@@ -4554,7 +4549,7 @@ fn parse_enum_def(&self, _generics: &ast::Generics) -> enum_def {
|
||||
}
|
||||
|
||||
// parse an "enum" declaration
|
||||
fn parse_item_enum(&self) -> item_info {
|
||||
fn parse_item_enum(&mut self) -> item_info {
|
||||
let id = self.parse_ident();
|
||||
let generics = self.parse_generics();
|
||||
self.expect(&token::LBRACE);
|
||||
@@ -4563,7 +4558,7 @@ fn parse_item_enum(&self) -> item_info {
|
||||
(id, item_enum(enum_definition, generics), None)
|
||||
}
|
||||
|
||||
fn fn_expr_lookahead(&self, tok: &token::Token) -> bool {
|
||||
fn fn_expr_lookahead(tok: &token::Token) -> bool {
|
||||
match *tok {
|
||||
token::LPAREN | token::AT | token::TILDE | token::BINOP(_) => true,
|
||||
_ => false
|
||||
@@ -4572,12 +4567,12 @@ fn fn_expr_lookahead(&self, tok: &token::Token) -> bool {
|
||||
|
||||
// Parses a string as an ABI spec on an extern type or module. Consumes
|
||||
// the `extern` keyword, if one is found.
|
||||
fn parse_opt_abis(&self) -> Option<AbiSet> {
|
||||
fn parse_opt_abis(&mut self) -> Option<AbiSet> {
|
||||
if !self.eat_keyword(keywords::Extern) {
|
||||
return None
|
||||
}
|
||||
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::LIT_STR(s)
|
||||
| token::LIT_STR_RAW(s, _) => {
|
||||
self.bump();
|
||||
@@ -4588,7 +4583,7 @@ fn parse_opt_abis(&self) -> Option<AbiSet> {
|
||||
Some(abi) => {
|
||||
if abis.contains(abi) {
|
||||
self.span_err(
|
||||
*self.span,
|
||||
self.span,
|
||||
format!("ABI `{}` appears twice",
|
||||
word));
|
||||
} else {
|
||||
@@ -4598,7 +4593,7 @@ fn parse_opt_abis(&self) -> Option<AbiSet> {
|
||||
|
||||
None => {
|
||||
self.span_err(
|
||||
*self.span,
|
||||
self.span,
|
||||
format!("illegal ABI: \
|
||||
expected one of [{}], \
|
||||
found `{}`",
|
||||
@@ -4620,11 +4615,11 @@ fn parse_opt_abis(&self) -> Option<AbiSet> {
|
||||
// flags; on failure, return iovi_none.
|
||||
// NB: this function no longer parses the items inside an
|
||||
// extern mod.
|
||||
fn parse_item_or_view_item(&self,
|
||||
fn parse_item_or_view_item(&mut self,
|
||||
attrs: ~[Attribute],
|
||||
macros_allowed: bool)
|
||||
-> item_or_view_item {
|
||||
match *self.token {
|
||||
match self.token {
|
||||
INTERPOLATED(token::nt_item(item)) => {
|
||||
self.bump();
|
||||
let new_attrs = vec::append(attrs, item.attrs);
|
||||
@@ -4660,10 +4655,13 @@ fn parse_item_or_view_item(&self,
|
||||
let abis = opt_abis.unwrap_or(AbiSet::C());
|
||||
let (ident, item_, extra_attrs) =
|
||||
self.parse_item_fn(extern_fn, abis);
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident,
|
||||
item_, visibility,
|
||||
maybe_append(attrs,
|
||||
extra_attrs)));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return iovi_item(item);
|
||||
} else {
|
||||
// EXTERN MODULE ITEM (iovi_view_item)
|
||||
return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs,
|
||||
@@ -4675,19 +4673,27 @@ fn parse_item_or_view_item(&self,
|
||||
// STATIC ITEM
|
||||
self.bump();
|
||||
let (ident, item_, extra_attrs) = self.parse_item_const();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return iovi_item(item);
|
||||
}
|
||||
if self.is_keyword(keywords::Fn) &&
|
||||
self.look_ahead(1, |f| !self.fn_expr_lookahead(f)) {
|
||||
self.look_ahead(1, |f| !Parser::fn_expr_lookahead(f)) {
|
||||
// FUNCTION ITEM
|
||||
self.bump();
|
||||
let (ident, item_, extra_attrs) =
|
||||
self.parse_item_fn(impure_fn, AbiSet::Rust());
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return iovi_item(item);
|
||||
}
|
||||
if self.is_keyword(keywords::Unsafe)
|
||||
&& self.look_ahead(1u, |t| *t != token::LBRACE) {
|
||||
@@ -4696,57 +4702,85 @@ fn parse_item_or_view_item(&self,
|
||||
self.expect_keyword(keywords::Fn);
|
||||
let (ident, item_, extra_attrs) =
|
||||
self.parse_item_fn(unsafe_fn, AbiSet::Rust());
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return iovi_item(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Mod) {
|
||||
// MODULE ITEM
|
||||
let (ident, item_, extra_attrs) = self.parse_item_mod(attrs);
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return iovi_item(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Type) {
|
||||
// TYPE ITEM
|
||||
let (ident, item_, extra_attrs) = self.parse_item_type();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return iovi_item(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Enum) {
|
||||
// ENUM ITEM
|
||||
let (ident, item_, extra_attrs) = self.parse_item_enum();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return iovi_item(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Trait) {
|
||||
// TRAIT ITEM
|
||||
let (ident, item_, extra_attrs) = self.parse_item_trait();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return iovi_item(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Impl) {
|
||||
// IMPL ITEM
|
||||
let (ident, item_, extra_attrs) = self.parse_item_impl();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return iovi_item(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Struct) {
|
||||
// STRUCT ITEM
|
||||
let (ident, item_, extra_attrs) = self.parse_item_struct();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
ident,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return iovi_item(item);
|
||||
}
|
||||
self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
|
||||
}
|
||||
|
||||
// parse a foreign item; on failure, return iovi_none.
|
||||
fn parse_foreign_item(&self,
|
||||
fn parse_foreign_item(&mut self,
|
||||
attrs: ~[Attribute],
|
||||
macros_allowed: bool)
|
||||
-> item_or_view_item {
|
||||
@@ -4770,13 +4804,13 @@ fn parse_foreign_item(&self,
|
||||
|
||||
// this is the fall-through for parsing items.
|
||||
fn parse_macro_use_or_failure(
|
||||
&self,
|
||||
&mut self,
|
||||
attrs: ~[Attribute],
|
||||
macros_allowed: bool,
|
||||
lo : BytePos,
|
||||
visibility : visibility
|
||||
) -> item_or_view_item {
|
||||
if macros_allowed && !token::is_any_keyword(self.token)
|
||||
if macros_allowed && !token::is_any_keyword(&self.token)
|
||||
&& self.look_ahead(1, |t| *t == token::NOT)
|
||||
&& (self.look_ahead(2, |t| is_plain_ident(t))
|
||||
|| self.look_ahead(2, |t| *t == token::LPAREN)
|
||||
@@ -4790,15 +4824,15 @@ fn parse_macro_use_or_failure(
|
||||
// a 'special' identifier (like what `macro_rules!` uses)
|
||||
// is optional. We should eventually unify invoc syntax
|
||||
// and remove this.
|
||||
let id = if is_plain_ident(&*self.token) {
|
||||
let id = if is_plain_ident(&self.token) {
|
||||
self.parse_ident()
|
||||
} else {
|
||||
token::special_idents::invalid // no special identifier
|
||||
};
|
||||
// eat a matched-delimiter token tree:
|
||||
let tts = match *self.token {
|
||||
let tts = match self.token {
|
||||
token::LPAREN | token::LBRACE => {
|
||||
let ket = token::flip_delimiter(&*self.token);
|
||||
let ket = token::flip_delimiter(&self.token);
|
||||
self.bump();
|
||||
self.parse_seq_to_end(&ket,
|
||||
seq_sep_none(),
|
||||
@@ -4812,8 +4846,13 @@ fn parse_macro_use_or_failure(
|
||||
span: mk_sp(self.span.lo,
|
||||
self.span.hi) };
|
||||
let item_ = item_mac(m);
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, id, item_,
|
||||
visibility, attrs));
|
||||
let item = self.mk_item(lo,
|
||||
self.last_span.hi,
|
||||
id,
|
||||
item_,
|
||||
visibility,
|
||||
attrs);
|
||||
return iovi_item(item);
|
||||
}
|
||||
|
||||
// FAILURE TO PARSE ITEM
|
||||
@@ -4825,12 +4864,12 @@ fn parse_macro_use_or_failure(
|
||||
s.push_str("priv")
|
||||
}
|
||||
s.push_char('`');
|
||||
self.span_fatal(*self.last_span, s);
|
||||
self.span_fatal(self.last_span, s);
|
||||
}
|
||||
return iovi_none(attrs);
|
||||
}
|
||||
|
||||
pub fn parse_item(&self, attrs: ~[Attribute]) -> Option<@ast::item> {
|
||||
pub fn parse_item(&mut self, attrs: ~[Attribute]) -> Option<@ast::item> {
|
||||
match self.parse_item_or_view_item(attrs, true) {
|
||||
iovi_none(_) => None,
|
||||
iovi_view_item(_) =>
|
||||
@@ -4842,7 +4881,7 @@ pub fn parse_item(&self, attrs: ~[Attribute]) -> Option<@ast::item> {
|
||||
}
|
||||
|
||||
// parse, e.g., "use a::b::{z,y}"
|
||||
fn parse_use(&self) -> view_item_ {
|
||||
fn parse_use(&mut self) -> view_item_ {
|
||||
return view_item_use(self.parse_view_paths());
|
||||
}
|
||||
|
||||
@@ -4852,10 +4891,10 @@ fn parse_use(&self) -> view_item_ {
|
||||
// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
|
||||
// | MOD? non_global_path MOD_SEP STAR
|
||||
// | MOD? non_global_path
|
||||
fn parse_view_path(&self) -> @view_path {
|
||||
fn parse_view_path(&mut self) -> @view_path {
|
||||
let lo = self.span.lo;
|
||||
|
||||
if *self.token == token::LBRACE {
|
||||
if self.token == token::LBRACE {
|
||||
// use {foo,bar}
|
||||
let idents = self.parse_unspanned_seq(
|
||||
&token::LBRACE, &token::RBRACE,
|
||||
@@ -4873,12 +4912,12 @@ fn parse_view_path(&self) -> @view_path {
|
||||
let first_ident = self.parse_ident();
|
||||
let mut path = ~[first_ident];
|
||||
debug!("parsed view_path: {}", self.id_to_str(first_ident));
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::EQ => {
|
||||
// x = foo::bar
|
||||
self.bump();
|
||||
path = ~[self.parse_ident()];
|
||||
while *self.token == token::MOD_SEP {
|
||||
while self.token == token::MOD_SEP {
|
||||
self.bump();
|
||||
let id = self.parse_ident();
|
||||
path.push(id);
|
||||
@@ -4902,10 +4941,10 @@ fn parse_view_path(&self) -> @view_path {
|
||||
|
||||
token::MOD_SEP => {
|
||||
// foo::bar or foo::{a,b,c} or foo::*
|
||||
while *self.token == token::MOD_SEP {
|
||||
while self.token == token::MOD_SEP {
|
||||
self.bump();
|
||||
|
||||
match *self.token {
|
||||
match self.token {
|
||||
token::IDENT(i, _) => {
|
||||
self.bump();
|
||||
path.push(i);
|
||||
@@ -4976,11 +5015,11 @@ fn parse_view_path(&self) -> @view_path {
|
||||
}
|
||||
|
||||
// matches view_paths = view_path | view_path , view_paths
|
||||
fn parse_view_paths(&self) -> ~[@view_path] {
|
||||
fn parse_view_paths(&mut self) -> ~[@view_path] {
|
||||
let mut vp = ~[self.parse_view_path()];
|
||||
while *self.token == token::COMMA {
|
||||
while self.token == token::COMMA {
|
||||
self.bump();
|
||||
self.obsolete(*self.last_span, ObsoleteMultipleImport);
|
||||
self.obsolete(self.last_span, ObsoleteMultipleImport);
|
||||
vp.push(self.parse_view_path());
|
||||
}
|
||||
return vp;
|
||||
@@ -4990,7 +5029,7 @@ fn parse_view_paths(&self) -> ~[@view_path] {
|
||||
// text that can't be parsed as an item
|
||||
// - mod_items uses extern_mod_allowed = true
|
||||
// - block_tail_ uses extern_mod_allowed = false
|
||||
fn parse_items_and_view_items(&self,
|
||||
fn parse_items_and_view_items(&mut self,
|
||||
first_item_attrs: ~[Attribute],
|
||||
mut extern_mod_allowed: bool,
|
||||
macros_allowed: bool)
|
||||
@@ -5074,7 +5113,7 @@ fn parse_items_and_view_items(&self,
|
||||
|
||||
// Parses a sequence of foreign items. Stops when it finds program
|
||||
// text that can't be parsed as an item
|
||||
fn parse_foreign_items(&self, first_item_attrs: ~[Attribute],
|
||||
fn parse_foreign_items(&mut self, first_item_attrs: ~[Attribute],
|
||||
macros_allowed: bool)
|
||||
-> ParsedItemsAndViewItems {
|
||||
let mut attrs = vec::append(first_item_attrs,
|
||||
@@ -5083,7 +5122,7 @@ fn parse_foreign_items(&self, first_item_attrs: ~[Attribute],
|
||||
loop {
|
||||
match self.parse_foreign_item(attrs, macros_allowed) {
|
||||
iovi_none(returned_attrs) => {
|
||||
if *self.token == token::RBRACE {
|
||||
if self.token == token::RBRACE {
|
||||
attrs = returned_attrs;
|
||||
break
|
||||
}
|
||||
@@ -5115,7 +5154,7 @@ fn parse_foreign_items(&self, first_item_attrs: ~[Attribute],
|
||||
|
||||
// Parses a source module as a crate. This is the main
|
||||
// entry point for the parser.
|
||||
pub fn parse_crate_mod(&self) -> Crate {
|
||||
pub fn parse_crate_mod(&mut self) -> Crate {
|
||||
let lo = self.span.lo;
|
||||
// parse the crate's inner attrs, maybe (oops) one
|
||||
// of the attrs of an item:
|
||||
@@ -5132,8 +5171,8 @@ pub fn parse_crate_mod(&self) -> Crate {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_optional_str(&self) -> Option<(@str, ast::StrStyle)> {
|
||||
let (s, style) = match *self.token {
|
||||
pub fn parse_optional_str(&mut self) -> Option<(@str, ast::StrStyle)> {
|
||||
let (s, style) = match self.token {
|
||||
token::LIT_STR(s) => (s, ast::CookedStr),
|
||||
token::LIT_STR_RAW(s, n) => (s, ast::RawStr(n)),
|
||||
_ => return None
|
||||
@@ -5142,7 +5181,7 @@ pub fn parse_optional_str(&self) -> Option<(@str, ast::StrStyle)> {
|
||||
Some((ident_to_str(&s), style))
|
||||
}
|
||||
|
||||
pub fn parse_str(&self) -> (@str, StrStyle) {
|
||||
pub fn parse_str(&mut self) -> (@str, StrStyle) {
|
||||
match self.parse_optional_str() {
|
||||
Some(s) => { s }
|
||||
_ => self.fatal("expected string literal")
|
||||
|
||||
@@ -55,7 +55,7 @@ pub fn string_to_crate (source_str : @str) -> ast::Crate {
|
||||
|
||||
// parse a string, return a crate and the ParseSess
|
||||
pub fn string_to_crate_and_sess (source_str : @str) -> (ast::Crate,@mut ParseSess) {
|
||||
let (p,ps) = string_to_parser_and_sess(source_str);
|
||||
let (mut p,ps) = string_to_parser_and_sess(source_str);
|
||||
(p.parse_crate_mod(),ps)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user