13
13
//! A library for procedural macro writers.
14
14
//!
15
15
//! ## Usage
16
- //! This crate provides the `qquote !` macro for syntax creation.
16
+ //! This crate provides the `quote !` macro for syntax creation.
17
17
//!
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;`
19
19
//! at the crate root. This is a temporary solution until we have better hygiene.
20
20
//!
21
21
//! ## Quasiquotation
22
22
//!
23
23
//! 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
25
25
//! construct the TokenStream `5 | + | 5`.
26
26
//!
27
27
//! ### Unquoting
28
28
//!
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 `$$`.
32
31
//!
33
- //! A simple example might be :
32
+ //! A simple example is :
34
33
//!
35
34
//!```
36
35
//!fn double(tmp: TokenStream) -> TokenStream {
37
- //! qquote!(unquote( tmp) * 2)
36
+ //! quote!($ tmp * 2)
38
37
//!}
39
38
//!```
40
39
//!
41
- //! ### Large Example: Implementing Scheme's `cond`
40
+ //! ### Large example: Scheme's `cond`
42
41
//!
43
- //! Below is the full implementation of Scheme's `cond` operator .
42
+ //! Below is an example implementation of Scheme's `cond`.
44
43
//!
45
44
//! ```
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()
68
72
//! }
69
73
//! ```
70
- //!
71
-
72
74
#![ crate_name = "proc_macro_plugin" ]
73
75
#![ unstable( feature = "rustc_private" , issue = "27812" ) ]
74
76
#![ feature( plugin_registrar) ]
@@ -87,8 +89,8 @@ extern crate rustc_plugin;
87
89
extern crate syntax;
88
90
extern crate syntax_pos;
89
91
90
- mod qquote ;
91
- use qquote :: qquote ;
92
+ mod quote ;
93
+ use quote :: quote ;
92
94
93
95
use rustc_plugin:: Registry ;
94
96
use syntax:: ext:: base:: SyntaxExtension ;
@@ -99,6 +101,6 @@ use syntax::symbol::Symbol;
99
101
100
102
#[ plugin_registrar]
101
103
pub 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 ) ) ) ;
104
106
}
0 commit comments