1313//! A library for procedural macro writers.
1414//!
1515//! ## Usage
16- //! This crate provides the `qquote !` macro for syntax creation.
16+ //! This crate provides the `quote !` macro for syntax creation.
1717//!
18- //! The `qquote !` macro uses the crate `syntax`, so users must declare `extern crate syntax;`
18+ //! The `quote !` macro uses the crate `syntax`, so users must declare `extern crate syntax;`
1919//! at the crate root. This is a temporary solution until we have better hygiene.
2020//!
2121//! ## Quasiquotation
2222//!
2323//! The quasiquoter creates output that, when run, constructs the tokenstream specified as
24- //! input. For example, `qquote !(5 + 5)` will produce a program, that, when run, will
24+ //! input. For example, `quote !(5 + 5)` will produce a program, that, when run, will
2525//! construct the TokenStream `5 | + | 5`.
2626//!
2727//! ### Unquoting
2828//!
29- //! Unquoting is currently done as `unquote`, and works by taking the single next
30- //! TokenTree in the TokenStream as the unquoted term. Ergonomically, `unquote(foo)` works
31- //! fine, but `unquote foo` is also supported.
29+ //! Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
30+ //! To quote `$` itself, use `$$`.
3231//!
33- //! A simple example might be :
32+ //! A simple example is :
3433//!
3534//!```
3635//!fn double(tmp: TokenStream) -> TokenStream {
37- //! qquote!(unquote( tmp) * 2)
36+ //! quote!($ tmp * 2)
3837//!}
3938//!```
4039//!
41- //! ### Large Example: Implementing Scheme's `cond`
40+ //! ### Large example: Scheme's `cond`
4241//!
43- //! Below is the full implementation of Scheme's `cond` operator .
42+ //! Below is an example implementation of Scheme's `cond`.
4443//!
4544//! ```
46- //! fn cond_rec(input: TokenStream) -> TokenStream {
47- //! if input.is_empty() { return quote!(); }
48- //!
49- //! let next = input.slice(0..1);
50- //! let rest = input.slice_from(1..);
51- //!
52- //! let clause : TokenStream = match next.maybe_delimited() {
53- //! Some(ts) => ts,
54- //! _ => panic!("Invalid input"),
55- //! };
56- //!
57- //! // clause is ([test]) [rhs]
58- //! if clause.len() < 2 { panic!("Invalid macro usage in cond: {:?}", clause) }
59- //!
60- //! let test: TokenStream = clause.slice(0..1);
61- //! let rhs: TokenStream = clause.slice_from(1..);
62- //!
63- //! if ident_eq(&test[0], str_to_ident("else")) || rest.is_empty() {
64- //! quote!({unquote(rhs)})
65- //! } else {
66- //! quote!({if unquote(test) { unquote(rhs) } else { cond!(unquote(rest)) } })
67- //! }
45+ //! fn cond(input: TokenStream) -> TokenStream {
46+ //! let mut conds = Vec::new();
47+ //! let mut input = input.trees().peekable();
48+ //! while let Some(tree) = input.next() {
49+ //! let mut cond = match tree {
50+ //! TokenTree::Delimited(_, ref delimited) => delimited.stream(),
51+ //! _ => panic!("Invalid input"),
52+ //! };
53+ //! let mut trees = cond.trees();
54+ //! let test = trees.next();
55+ //! let rhs = trees.collect::<TokenStream>();
56+ //! if rhs.is_empty() {
57+ //! panic!("Invalid macro usage in cond: {}", cond);
58+ //! }
59+ //! let is_else = match test {
60+ //! Some(TokenTree::Token(_, Token::Ident(ident))) if ident.name == "else" => true,
61+ //! _ => false,
62+ //! };
63+ //! conds.push(if is_else || input.peek().is_none() {
64+ //! quote!({ $rhs })
65+ //! } else {
66+ //! let test = test.unwrap();
67+ //! quote!(if $test { $rhs } else)
68+ //! });
69+ //! }
70+ //!
71+ //! conds.into_iter().collect()
6872//! }
6973//! ```
70- //!
71-
7274#![ crate_name = "proc_macro_plugin" ]
7375#![ unstable( feature = "rustc_private" , issue = "27812" ) ]
7476#![ feature( plugin_registrar) ]
@@ -87,8 +89,8 @@ extern crate rustc_plugin;
8789extern crate syntax;
8890extern crate syntax_pos;
8991
90- mod qquote ;
91- use qquote :: qquote ;
92+ mod quote ;
93+ use quote :: quote ;
9294
9395use rustc_plugin:: Registry ;
9496use syntax:: ext:: base:: SyntaxExtension ;
@@ -99,6 +101,6 @@ use syntax::symbol::Symbol;
99101
100102#[ plugin_registrar]
101103pub fn plugin_registrar ( reg : & mut Registry ) {
102- reg. register_syntax_extension ( Symbol :: intern ( "qquote " ) ,
103- SyntaxExtension :: ProcMacro ( Box :: new ( qquote ) ) ) ;
104+ reg. register_syntax_extension ( Symbol :: intern ( "quote " ) ,
105+ SyntaxExtension :: ProcMacro ( Box :: new ( quote ) ) ) ;
104106}
0 commit comments