diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-01-06 15:38:10 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-01-06 15:38:10 -0800 |
| commit | 0631b466c23ffdb1edb2997a8da2702cfe6fcd4a (patch) | |
| tree | 3c9f6076565b544f450e98102825a85df1b55f3b /src/libsyntax/ext | |
| parent | 771fe9026a38cb673d0928fea1f6ebd4ba796e43 (diff) | |
| parent | d85c017f92156d0d6854292c976c13c3312bba8e (diff) | |
| download | rust-0631b466c23ffdb1edb2997a8da2702cfe6fcd4a.tar.gz rust-0631b466c23ffdb1edb2997a8da2702cfe6fcd4a.zip | |
rollup merge of #19430: pczarn/interp_tt-cleanup
Conflicts: src/libsyntax/parse/parser.rs
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/tt/macro_parser.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 19 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/transcribe.rs | 34 |
3 files changed, 44 insertions, 26 deletions
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 0f9d613cf13..d33d03bbfa9 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -507,6 +507,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), None => p.fatal("expected an item keyword") @@ -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)) } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 805af484e28..fdf749e1285 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -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 { diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index b3bb5cdd897..bc07c7f6cae 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -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 |
