diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2017-03-18 01:55:51 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2017-05-25 05:51:06 +0000 |
| commit | 2a1d2edb821e123586049f349bb4aaee2d001cc6 (patch) | |
| tree | ea86b6b7403e222132be53f01949f393b31a41d7 /src/libsyntax/parse | |
| parent | 9c6430b3257a96d587349d85aa7596d3f4704c28 (diff) | |
| download | rust-2a1d2edb821e123586049f349bb4aaee2d001cc6.tar.gz rust-2a1d2edb821e123586049f349bb4aaee2d001cc6.zip | |
Declarative macros 2.0 without hygiene.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 68 |
1 files changed, 47 insertions, 21 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3c9ad8ca9c0..bc9be809ca4 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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, |
