Skip to content

Commit 38ce6d9

Browse files
committed
Use TokenTrees in lhs of macros
1 parent 5c1fd5f commit 38ce6d9

File tree

10 files changed

+387
-249
lines changed

10 files changed

+387
-249
lines changed

src/librustdoc/html/highlight.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
163163

164164
token::Lifetime(..) => "lifetime",
165165
token::DocComment(..) => "doccomment",
166-
token::Underscore | token::Eof | token::Interpolated(..) => "",
166+
token::Underscore | token::Eof | token::Interpolated(..) |
167+
token::MatchNt(..) | token::SubstNt(..) => "",
167168
};
168169

169170
// as mentioned above, use the original source code instead of

src/libsyntax/ast.rs

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
// The Rust abstract syntax tree.
1212

13-
use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
13+
use codemap::{Span, Spanned, DUMMY_SP, ExpnId, respan};
1414
use abi::Abi;
1515
use ast_util;
1616
use owned_slice::OwnedSlice;
@@ -657,23 +657,55 @@ pub enum TokenTree {
657657
/// A delimited sequence of token trees
658658
TtDelimited(Span, Rc<Delimited>),
659659

660-
// These only make sense for right-hand-sides of MBE macros:
660+
// This only makes sense for right-hand-sides of MBE macros:
661661

662662
/// A Kleene-style repetition sequence with an optional separator.
663663
// FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
664-
TtSequence(Span, Rc<Vec<TokenTree>>, Option<token::Token>, KleeneOp),
665-
/// A syntactic variable that will be filled in by macro expansion.
666-
TtNonterminal(Span, Ident)
664+
TtSequence(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, KleeneOp, uint),
667665
}
668666

669667
impl TokenTree {
668+
pub fn expand_into_tts(self) -> Rc<Vec<TokenTree>> {
669+
match self {
670+
TtToken(sp, token::DocComment(name)) => {
671+
let doc = MetaNameValue(token::intern_and_get_ident("doc"),
672+
respan(sp, LitStr(token::get_name(name), CookedStr)));
673+
let doc = token::NtMeta(P(respan(sp, doc)));
674+
let delimed = Delimited {
675+
delim: token::Bracket,
676+
open_span: sp,
677+
tts: vec![TtToken(sp, token::Interpolated(doc))],
678+
close_span: sp,
679+
};
680+
Rc::new(vec![TtToken(sp, token::Pound),
681+
TtDelimited(sp, Rc::new(delimed))])
682+
}
683+
TtDelimited(_, ref delimed) => {
684+
let mut tts = Vec::with_capacity(1 + delimed.tts.len() + 1);
685+
tts.push(delimed.open_tt());
686+
tts.extend(delimed.tts.iter().map(|tt| tt.clone()));
687+
tts.push(delimed.close_tt());
688+
Rc::new(tts)
689+
}
690+
TtToken(sp, token::SubstNt(name, namep)) => {
691+
Rc::new(vec![TtToken(sp, token::Dollar),
692+
TtToken(sp, token::Ident(name, namep))])
693+
}
694+
TtToken(sp, token::MatchNt(name, kind, namep, kindp)) => {
695+
Rc::new(vec![TtToken(sp, token::SubstNt(name, namep)),
696+
TtToken(sp, token::Colon),
697+
TtToken(sp, token::Ident(kind, kindp))])
698+
}
699+
_ => panic!("Cannot expand a token")
700+
}
701+
}
702+
670703
/// Returns the `Span` corresponding to this token tree.
671704
pub fn get_span(&self) -> Span {
672705
match *self {
673-
TtToken(span, _) => span,
674-
TtDelimited(span, _) => span,
675-
TtSequence(span, _, _, _) => span,
676-
TtNonterminal(span, _) => span,
706+
TtToken(span, _) => span,
707+
TtDelimited(span, _) => span,
708+
TtSequence(span, _, _, _, _) => span,
677709
}
678710
}
679711
}

src/libsyntax/ext/quote.rs

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,20 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
616616
vec!(mk_name(cx, sp, ident.ident())));
617617
}
618618

619+
token::MatchNt(name, kind, name_style, kind_style) => {
620+
return cx.expr_call(sp,
621+
mk_token_path(cx, sp, "MatchNt"),
622+
vec![mk_ident(cx, sp, name),
623+
mk_ident(cx, sp, kind),
624+
match name_style {
625+
ModName => mk_token_path(cx, sp, "ModName"),
626+
Plain => mk_token_path(cx, sp, "Plain"),
627+
},
628+
match kind_style {
629+
ModName => mk_token_path(cx, sp, "ModName"),
630+
Plain => mk_token_path(cx, sp, "Plain"),
631+
}]);
632+
}
619633
token::Interpolated(_) => panic!("quote! with interpolated token"),
620634

621635
_ => ()
@@ -654,6 +668,25 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
654668

655669
fn mk_tt(cx: &ExtCtxt, _: Span, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
656670
match *tt {
671+
ast::TtToken(sp, SubstNt(ident, _)) => {
672+
// tt.extend($ident.to_tokens(ext_cx).into_iter())
673+
674+
let e_to_toks =
675+
cx.expr_method_call(sp,
676+
cx.expr_ident(sp, ident),
677+
id_ext("to_tokens"),
678+
vec!(cx.expr_ident(sp, id_ext("ext_cx"))));
679+
let e_to_toks =
680+
cx.expr_method_call(sp, e_to_toks, id_ext("into_iter"), vec![]);
681+
682+
let e_push =
683+
cx.expr_method_call(sp,
684+
cx.expr_ident(sp, id_ext("tt")),
685+
id_ext("extend"),
686+
vec!(e_to_toks));
687+
688+
vec!(cx.stmt_expr(e_push))
689+
}
657690
ast::TtToken(sp, ref tok) => {
658691
let e_sp = cx.expr_ident(sp, id_ext("_sp"));
659692
let e_tok = cx.expr_call(sp,
@@ -673,25 +706,6 @@ fn mk_tt(cx: &ExtCtxt, _: Span, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
673706
.collect()
674707
},
675708
ast::TtSequence(..) => panic!("TtSequence in quote!"),
676-
ast::TtNonterminal(sp, ident) => {
677-
// tt.extend($ident.to_tokens(ext_cx).into_iter())
678-
679-
let e_to_toks =
680-
cx.expr_method_call(sp,
681-
cx.expr_ident(sp, ident),
682-
id_ext("to_tokens"),
683-
vec!(cx.expr_ident(sp, id_ext("ext_cx"))));
684-
let e_to_toks =
685-
cx.expr_method_call(sp, e_to_toks, id_ext("into_iter"), vec![]);
686-
687-
let e_push =
688-
cx.expr_method_call(sp,
689-
cx.expr_ident(sp, id_ext("tt")),
690-
id_ext("extend"),
691-
vec!(e_to_toks));
692-
693-
vec!(cx.stmt_expr(e_push))
694-
},
695709
}
696710
}
697711

0 commit comments

Comments
 (0)