diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 7359c21eccca..d6874f60cde7 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -21,9 +21,9 @@ use ext::base::*; use feature_gate::{self, Features}; use fold; use fold::*; -use parse::{ParseSess, lexer}; +use parse::{ParseSess, PResult, lexer}; use parse::parser::Parser; -use parse::token::{intern, keywords}; +use parse::token::{self, intern, keywords}; use print::pprust; use ptr::P; use tokenstream::{TokenTree, TokenStream}; @@ -38,12 +38,12 @@ macro_rules! expansions { ($($kind:ident: $ty:ty [$($vec:ident, $ty_elt:ty)*], $kind_name:expr, .$make:ident, $(.$fold:ident)* $(lift .$fold_elt:ident)*, $(.$visit:ident)* $(lift .$visit_elt:ident)*;)*) => { - #[derive(Copy, Clone)] + #[derive(Copy, Clone, PartialEq, Eq)] pub enum ExpansionKind { OptExpr, $( $kind, )* } pub enum Expansion { OptExpr(Option
>), $( $kind($ty), )* }
impl ExpansionKind {
- fn name(self) -> &'static str {
+ pub fn name(self) -> &'static str {
match self {
ExpansionKind::OptExpr => "expression",
$( ExpansionKind::$kind => $kind_name, )*
@@ -106,6 +106,12 @@ macro_rules! expansions {
self.expand(Expansion::$kind(SmallVector::one(node))).$make()
})*)*
}
+
+ impl<'a> MacResult for ::ext::tt::macro_rules::ParserAnyMacro<'a> {
+ $(fn $make(self: Box<::ext::tt::macro_rules::ParserAnyMacro<'a>>) -> Option<$ty> {
+ Some(self.make(ExpansionKind::$kind).$make())
+ })*
+ }
}
}
@@ -450,6 +456,47 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
}
+impl<'a> Parser<'a> {
+ pub fn parse_expansion(&mut self, kind: ExpansionKind) -> PResult<'a, Expansion> {
+ Ok(match kind {
+ ExpansionKind::Items => {
+ let mut items = SmallVector::zero();
+ while let Some(item) = self.parse_item()? {
+ items.push(item);
+ }
+ Expansion::Items(items)
+ }
+ ExpansionKind::TraitItems => {
+ let mut items = SmallVector::zero();
+ while self.token != token::Eof {
+ items.push(self.parse_trait_item()?);
+ }
+ Expansion::TraitItems(items)
+ }
+ ExpansionKind::ImplItems => {
+ let mut items = SmallVector::zero();
+ while self.token != token::Eof {
+ items.push(self.parse_impl_item()?);
+ }
+ Expansion::ImplItems(items)
+ }
+ ExpansionKind::Stmts => {
+ let mut stmts = SmallVector::zero();
+ while self.token != token::Eof {
+ if let Some(stmt) = self.parse_full_stmt(true)? {
+ stmts.push(stmt);
+ }
+ }
+ Expansion::Stmts(stmts)
+ }
+ ExpansionKind::Expr => Expansion::Expr(self.parse_expr()?),
+ ExpansionKind::OptExpr => Expansion::OptExpr(Some(self.parse_expr()?)),
+ ExpansionKind::Ty => Expansion::Ty(self.parse_ty()?),
+ ExpansionKind::Pat => Expansion::Pat(self.parse_pat()?),
+ })
+ }
+}
+
struct InvocationCollector<'a, 'b: 'a> {
cx: &'a mut ExtCtxt<'b>,
cfg: StripUnconfigured<'a>,
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 0eed3e5898c0..8c95e7d31f79 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -12,6 +12,7 @@ use {ast, attr};
use syntax_pos::{Span, DUMMY_SP};
use ext::base::{DummyResult, ExtCtxt, MacEager, MacResult, SyntaxExtension};
use ext::base::{IdentMacroExpander, NormalTT, TTMacroExpander};
+use ext::expand::{Expansion, ExpansionKind};
use ext::placeholders;
use ext::tt::macro_parser::{Success, Error, Failure};
use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
@@ -22,18 +23,14 @@ use parse::parser::{Parser, Restrictions};
use parse::token::{self, gensym_ident, NtTT, Token};
use parse::token::Token::*;
use print;
-use ptr::P;
use tokenstream::{self, TokenTree};
-use util::small_vector::SmallVector;
-
-use std::cell::RefCell;
use std::collections::{HashMap};
use std::collections::hash_map::{Entry};
use std::rc::Rc;
-struct ParserAnyMacro<'a> {
- parser: RefCell > {
- let ret = panictry!(self.parser.borrow_mut().parse_expr());
- self.ensure_complete_parse(true, "expression");
- Some(ret)
- }
- fn make_pat(self: Box > {
- let ret = panictry!(self.parser.borrow_mut().parse_pat());
- self.ensure_complete_parse(false, "pattern");
- Some(ret)
- }
- fn make_items(self: Box > {
- let ret = panictry!(self.parser.borrow_mut().parse_ty());
- self.ensure_complete_parse(false, "type");
- Some(ret)
+ pub fn make(mut self: Box