diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 407715ab4dae0..9174bb65b248b 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -32,6 +32,7 @@ use std::gc::Gc; pub mod rt { use ast; + use codemap::Spanned; use ext::base::ExtCtxt; use parse::token; use parse; @@ -48,12 +49,25 @@ pub mod rt { fn to_tokens(&self, _cx: &ExtCtxt) -> Vec ; } + impl ToTokens for TokenTree { + fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { + vec!(self.clone()) + } + } + impl ToTokens for Vec { fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { (*self).clone() } } + impl ToTokens for Spanned { + fn to_tokens(&self, cx: &ExtCtxt) -> Vec { + // FIXME: use the span? + self.node.to_tokens(cx) + } + } + /* Should be (when bugs in default methods are fixed): trait ToSource : ToTokens { @@ -68,72 +82,62 @@ pub mod rt { */ + // FIXME: Move this trait to pprust and get rid of *_to_str? pub trait ToSource { // Takes a thing and generates a string containing rust code for it. fn to_source(&self) -> String; } - impl ToSource for ast::Ident { - fn to_source(&self) -> String { - token::get_ident(*self).get().to_string() - } - } - - impl ToSource for Gc { - fn to_source(&self) -> String { - pprust::item_to_str(&**self) - } - } - - impl<'a> ToSource for &'a [Gc] { - fn to_source(&self) -> String { - self.iter() - .map(|i| i.to_source()) - .collect::>() - .connect("\n\n") - .to_string() - } - } - - impl ToSource for ast::Ty { - fn to_source(&self) -> String { - pprust::ty_to_str(self) - } - } - - impl<'a> ToSource for &'a [ast::Ty] { - fn to_source(&self) -> String { - self.iter() - .map(|i| i.to_source()) - .collect::>() - .connect(", ") - .to_string() - } - } + macro_rules! impl_to_source( + (Gc<$t:ty>, $pp:ident) => ( + impl ToSource for Gc<$t> { + fn to_source(&self) -> String { + pprust::$pp(&**self) + } + } + ); + ($t:ty, $pp:ident) => ( + impl ToSource for $t { + fn to_source(&self) -> String { + pprust::$pp(self) + } + } + ); + ) - impl ToSource for Generics { - fn to_source(&self) -> String { - pprust::generics_to_str(self) - } + fn slice_to_source<'a, T: ToSource>(sep: &'static str, xs: &'a [T]) -> String { + xs.iter() + .map(|i| i.to_source()) + .collect::>() + .connect(sep) + .to_string() } - impl ToSource for Gc { - fn to_source(&self) -> String { - pprust::expr_to_str(&**self) - } - } + macro_rules! impl_to_source_slice( + ($t:ty, $sep:expr) => ( + impl<'a> ToSource for &'a [$t] { + fn to_source(&self) -> String { + slice_to_source($sep, *self) + } + } + ) + ) - impl ToSource for ast::Block { + impl ToSource for ast::Ident { fn to_source(&self) -> String { - pprust::block_to_str(self) + token::get_ident(*self).get().to_string() } } - impl ToSource for ast::Arg { - fn to_source(&self) -> String { - pprust::arg_to_str(self) - } - } + impl_to_source!(ast::Ty, ty_to_str) + impl_to_source!(ast::Block, block_to_str) + impl_to_source!(ast::Arg, arg_to_str) + impl_to_source!(Generics, generics_to_str) + impl_to_source!(Gc, item_to_str) + impl_to_source!(Gc, expr_to_str) + impl_to_source!(Gc, pat_to_str) + impl_to_source_slice!(ast::Ty, ", ") + impl_to_source_slice!(Gc, "\n\n") impl<'a> ToSource for &'a str { fn to_source(&self) -> String { @@ -163,76 +167,36 @@ pub mod rt { } } - impl ToSource for int { - fn to_source(&self) -> String { - let lit = dummy_spanned(ast::LitInt(*self as i64, ast::TyI)); - pprust::lit_to_str(&lit) - } - } - - impl ToSource for i8 { - fn to_source(&self) -> String { - let lit = dummy_spanned(ast::LitInt(*self as i64, ast::TyI8)); - pprust::lit_to_str(&lit) - } - } - - impl ToSource for i16 { - fn to_source(&self) -> String { - let lit = dummy_spanned(ast::LitInt(*self as i64, ast::TyI16)); - pprust::lit_to_str(&lit) - } - } - - - impl ToSource for i32 { - fn to_source(&self) -> String { - let lit = dummy_spanned(ast::LitInt(*self as i64, ast::TyI32)); - pprust::lit_to_str(&lit) - } - } - - impl ToSource for i64 { - fn to_source(&self) -> String { - let lit = dummy_spanned(ast::LitInt(*self as i64, ast::TyI64)); - pprust::lit_to_str(&lit) - } - } - - impl ToSource for uint { - fn to_source(&self) -> String { - let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU)); - pprust::lit_to_str(&lit) - } - } - - impl ToSource for u8 { - fn to_source(&self) -> String { - let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU8)); - pprust::lit_to_str(&lit) - } - } - - impl ToSource for u16 { - fn to_source(&self) -> String { - let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU16)); - pprust::lit_to_str(&lit) - } - } + macro_rules! impl_to_source_int( + (signed, $t:ty, $tag:ident) => ( + impl ToSource for $t { + fn to_source(&self) -> String { + let lit = dummy_spanned(ast::LitInt(*self as i64, ast::$tag)); + pprust::lit_to_str(&lit) + } + } + ); + (unsigned, $t:ty, $tag:ident) => ( + impl ToSource for $t { + fn to_source(&self) -> String { + let lit = dummy_spanned(ast::LitUint(*self as u64, ast::$tag)); + pprust::lit_to_str(&lit) + } + } + ); + ) - impl ToSource for u32 { - fn to_source(&self) -> String { - let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU32)); - pprust::lit_to_str(&lit) - } - } + impl_to_source_int!(signed, int, TyI) + impl_to_source_int!(signed, i8, TyI8) + impl_to_source_int!(signed, i16, TyI16) + impl_to_source_int!(signed, i32, TyI32) + impl_to_source_int!(signed, i64, TyI64) - impl ToSource for u64 { - fn to_source(&self) -> String { - let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU64)); - pprust::lit_to_str(&lit) - } - } + impl_to_source_int!(unsigned, uint, TyU) + impl_to_source_int!(unsigned, u8, TyU8) + impl_to_source_int!(unsigned, u16, TyU16) + impl_to_source_int!(unsigned, u32, TyU32) + impl_to_source_int!(unsigned, u64, TyU64) // Alas ... we write these out instead. All redundant. @@ -246,7 +210,7 @@ pub mod rt { ) ) - macro_rules! impl_to_tokens_self( + macro_rules! impl_to_tokens_lifetime( ($t:ty) => ( impl<'a> ToTokens for $t { fn to_tokens(&self, cx: &ExtCtxt) -> Vec { @@ -258,14 +222,15 @@ pub mod rt { impl_to_tokens!(ast::Ident) impl_to_tokens!(Gc) - impl_to_tokens_self!(&'a [Gc]) + impl_to_tokens!(Gc) + impl_to_tokens_lifetime!(&'a [Gc]) impl_to_tokens!(ast::Ty) - impl_to_tokens_self!(&'a [ast::Ty]) + impl_to_tokens_lifetime!(&'a [ast::Ty]) impl_to_tokens!(Generics) impl_to_tokens!(Gc) impl_to_tokens!(ast::Block) impl_to_tokens!(ast::Arg) - impl_to_tokens_self!(&'a str) + impl_to_tokens_lifetime!(&'a str) impl_to_tokens!(()) impl_to_tokens!(char) impl_to_tokens!(bool) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e1319304e04e9..1cb09bb8d890e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2721,7 +2721,7 @@ impl<'a> Parser<'a> { } // parse an expression, subject to the given restriction - fn parse_expr_res(&mut self, r: restriction) -> Gc { + pub fn parse_expr_res(&mut self, r: restriction) -> Gc { let old = self.restriction; self.restriction = r; let e = self.parse_assign_expr();