rollup merge of #19430: pczarn/interp_tt-cleanup

Conflicts:
	src/libsyntax/parse/parser.rs
This commit is contained in:
Alex Crichton 2015-01-06 15:38:10 -08:00
commit 0631b466c2
12 changed files with 170 additions and 103 deletions

View file

@ -506,6 +506,17 @@ pub fn parse(sess: &ParseSess,
}
pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal {
match name {
"tt" => {
p.quote_depth += 1u; //but in theory, non-quoted tts might be useful
let res = token::NtTT(P(p.parse_token_tree()));
p.quote_depth -= 1u;
return res;
}
_ => {}
}
// check at the beginning and the parser checks after each bump
p.check_unknown_macro_variable();
match name {
"item" => match p.parse_item(Vec::new()) {
Some(i) => token::NtItem(i),
@ -529,12 +540,6 @@ pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal {
token::NtPath(box p.parse_path(LifetimeAndTypesWithoutColons))
}
"meta" => token::NtMeta(p.parse_meta_item()),
"tt" => {
p.quote_depth += 1u; //but in theory, non-quoted tts might be useful
let res = token::NtTT(P(p.parse_token_tree()));
p.quote_depth -= 1u;
res
}
_ => {
p.fatal(format!("unsupported builtin nonterminal parser: {}", name).index(&FullRange))
}

View file

@ -16,7 +16,7 @@ use ext::base::{NormalTT, TTMacroExpander};
use ext::tt::macro_parser::{Success, Error, Failure};
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
use ext::tt::macro_parser::{parse, parse_or_else};
use parse::lexer::new_tt_reader;
use parse::lexer::{new_tt_reader, new_tt_reader_with_doc_flag};
use parse::parser::Parser;
use parse::attr::ParserAttr;
use parse::token::{special_idents, gensym_ident};
@ -158,13 +158,13 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
_ => cx.span_fatal(sp, "malformed macro lhs")
};
// `None` is because we're not interpolating
let mut arg_rdr = new_tt_reader(&cx.parse_sess().span_diagnostic,
None,
None,
arg.iter()
.map(|x| (*x).clone())
.collect());
arg_rdr.desugar_doc_comments = true;
let arg_rdr = new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
None,
None,
arg.iter()
.map(|x| (*x).clone())
.collect(),
true);
match parse(cx.parse_sess(), cx.cfg(), arg_rdr, lhs_tt) {
Success(named_matches) => {
let rhs = match *rhses[i] {
@ -183,7 +183,8 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
Some(named_matches),
imported_from,
rhs);
let p = Parser::new(cx.parse_sess(), cx.cfg(), box trncbr);
let mut p = Parser::new(cx.parse_sess(), cx.cfg(), box trncbr);
p.check_unknown_macro_variable();
// Let the context choose how to interpret the result.
// Weird, but useful for X-macros.
return box ParserAnyMacro {

View file

@ -53,13 +53,28 @@ pub struct TtReader<'a> {
}
/// This can do Macro-By-Example transcription. On the other hand, if
/// `src` contains no `TtSequence`s and `TtNonterminal`s, `interp` can (and
/// should) be none.
/// `src` contains no `TtSequence`s, `MatchNt`s or `SubstNt`s, `interp` can
/// (and should) be None.
pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
interp: Option<HashMap<Ident, Rc<NamedMatch>>>,
imported_from: Option<Ident>,
src: Vec<ast::TokenTree> )
src: Vec<ast::TokenTree>)
-> TtReader<'a> {
new_tt_reader_with_doc_flag(sp_diag, interp, imported_from, src, false)
}
/// The extra `desugar_doc_comments` flag enables reading doc comments
/// like any other attribute which consists of `meta` and surrounding #[ ] tokens.
///
/// This can do Macro-By-Example transcription. On the other hand, if
/// `src` contains no `TtSequence`s, `MatchNt`s or `SubstNt`s, `interp` can
/// (and should) be None.
pub fn new_tt_reader_with_doc_flag<'a>(sp_diag: &'a SpanHandler,
interp: Option<HashMap<Ident, Rc<NamedMatch>>>,
imported_from: Option<Ident>,
src: Vec<ast::TokenTree>,
desugar_doc_comments: bool)
-> TtReader<'a> {
let mut r = TtReader {
sp_diag: sp_diag,
stack: vec!(TtFrame {
@ -80,7 +95,7 @@ pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
crate_name_next: None,
repeat_idx: Vec::new(),
repeat_len: Vec::new(),
desugar_doc_comments: false,
desugar_doc_comments: desugar_doc_comments,
/* dummy values, never read: */
cur_tok: token::Eof,
cur_span: DUMMY_SP,
@ -266,18 +281,15 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
}
// FIXME #2887: think about span stuff here
TtToken(sp, SubstNt(ident, namep)) => {
r.stack.last_mut().unwrap().idx += 1;
match lookup_cur_matched(r, ident) {
None => {
r.stack.push(TtFrame {
forest: TtToken(sp, SubstNt(ident, namep)),
idx: 0,
dotdotdoted: false,
sep: None
});
r.cur_span = sp;
r.cur_tok = SubstNt(ident, namep);
return ret_val;
// this can't be 0 length, just like TtDelimited
}
Some(cur_matched) => {
r.stack.last_mut().unwrap().idx += 1;
match *cur_matched {
// sidestep the interpolation tricks for ident because
// (a) idents can be in lots of places, so it'd be a pain