libsyntax: Make the parser mutable
This commit is contained in:
parent
0df9b850ac
commit
f499d365ad
13 changed files with 518 additions and 487 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -442,9 +442,9 @@ 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 {
|
||||
if es.len() != 0 && !p.eat(&token::COMMA) {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ use parse::token;
|
|||
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", ...)`
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -579,21 +579,17 @@ 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()
|
||||
);
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@ use parse::attr::parser_attr;
|
|||
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 @@ impl AnyMacro for ParserAnyMacro {
|
|||
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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue