Declarative macros 2.0 without hygiene.
This commit is contained in:
parent
9c6430b325
commit
2a1d2edb82
14 changed files with 116 additions and 46 deletions
|
@ -3758,33 +3758,59 @@ impl<'a> Parser<'a> {
|
|||
fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility)
|
||||
-> PResult<'a, Option<P<Item>>> {
|
||||
let lo = self.span;
|
||||
match self.token {
|
||||
token::Ident(ident) if ident.name == "macro_rules" => {
|
||||
if self.look_ahead(1, |t| *t == token::Not) {
|
||||
let prev_span = self.prev_span;
|
||||
self.complain_if_pub_macro(vis, prev_span);
|
||||
self.bump();
|
||||
self.bump();
|
||||
let (ident, def) = match self.token {
|
||||
token::Ident(ident) if ident.name == keywords::Macro.name() => {
|
||||
self.bump();
|
||||
let ident = self.parse_ident()?;
|
||||
let tokens = if self.check(&token::OpenDelim(token::Brace)) {
|
||||
match self.parse_token_tree() {
|
||||
TokenTree::Delimited(_, ref delimited) => delimited.stream(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
} else if self.check(&token::OpenDelim(token::Paren)) {
|
||||
let args = self.parse_token_tree();
|
||||
let body = if self.check(&token::OpenDelim(token::Brace)) {
|
||||
self.parse_token_tree()
|
||||
} else {
|
||||
self.unexpected()?;
|
||||
unreachable!()
|
||||
};
|
||||
TokenStream::concat(vec![
|
||||
args.into(),
|
||||
TokenTree::Token(lo.to(self.prev_span), token::FatArrow).into(),
|
||||
body.into(),
|
||||
])
|
||||
} else {
|
||||
self.unexpected()?;
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
(ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
|
||||
}
|
||||
token::Ident(ident) if ident.name == "macro_rules" &&
|
||||
self.look_ahead(1, |t| *t == token::Not) => {
|
||||
let prev_span = self.prev_span;
|
||||
self.complain_if_pub_macro(vis, prev_span);
|
||||
self.bump();
|
||||
self.bump();
|
||||
|
||||
let ident = self.parse_ident()?;
|
||||
let (delim, tokens) = self.expect_delimited_token_tree()?;
|
||||
if delim != token::Brace {
|
||||
if !self.eat(&token::Semi) {
|
||||
let msg = "macros that expand to items must either \
|
||||
be surrounded with braces or followed by a semicolon";
|
||||
self.span_err(self.prev_span, msg);
|
||||
}
|
||||
}
|
||||
|
||||
(ident, ast::MacroDef { tokens: tokens, legacy: true })
|
||||
}
|
||||
_ => return Ok(None),
|
||||
};
|
||||
|
||||
let id = self.parse_ident()?;
|
||||
let (delim, tts) = self.expect_delimited_token_tree()?;
|
||||
if delim != token::Brace {
|
||||
if !self.eat(&token::Semi) {
|
||||
let msg = "macros that expand to items must either be surrounded with braces \
|
||||
or followed by a semicolon";
|
||||
self.span_err(self.prev_span, msg);
|
||||
}
|
||||
}
|
||||
|
||||
let span = lo.to(self.prev_span);
|
||||
let kind = ItemKind::MacroDef(ast::MacroDef {
|
||||
tokens: tts,
|
||||
});
|
||||
Ok(Some(self.mk_item(span, id, kind, Visibility::Inherited, attrs.to_owned())))
|
||||
Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
|
||||
}
|
||||
|
||||
fn parse_stmt_without_recovery(&mut self,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue