]>
Commit | Line | Data |
---|---|---|
c30ab7b3 SL |
1 | // Copyright 2016 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | //! # Proc_Macro | |
12 | //! | |
13 | //! A library for procedural macro writers. | |
14 | //! | |
15 | //! ## Usage | |
cc61c64b | 16 | //! This crate provides the `quote!` macro for syntax creation. |
c30ab7b3 | 17 | //! |
cc61c64b | 18 | //! The `quote!` macro uses the crate `syntax`, so users must declare `extern crate syntax;` |
32a655c1 | 19 | //! at the crate root. This is a temporary solution until we have better hygiene. |
c30ab7b3 SL |
20 | //! |
21 | //! ## Quasiquotation | |
22 | //! | |
23 | //! The quasiquoter creates output that, when run, constructs the tokenstream specified as | |
cc61c64b | 24 | //! input. For example, `quote!(5 + 5)` will produce a program, that, when run, will |
c30ab7b3 SL |
25 | //! construct the TokenStream `5 | + | 5`. |
26 | //! | |
27 | //! ### Unquoting | |
28 | //! | |
cc61c64b XL |
29 | //! Unquoting is done with `$`, and works by taking the single next ident as the unquoted term. |
30 | //! To quote `$` itself, use `$$`. | |
c30ab7b3 | 31 | //! |
cc61c64b | 32 | //! A simple example is: |
c30ab7b3 SL |
33 | //! |
34 | //!``` | |
35 | //!fn double(tmp: TokenStream) -> TokenStream { | |
cc61c64b | 36 | //! quote!($tmp * 2) |
c30ab7b3 SL |
37 | //!} |
38 | //!``` | |
39 | //! | |
cc61c64b | 40 | //! ### Large example: Scheme's `cond` |
c30ab7b3 | 41 | //! |
cc61c64b | 42 | //! Below is an example implementation of Scheme's `cond`. |
c30ab7b3 SL |
43 | //! |
44 | //! ``` | |
cc61c64b XL |
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() | |
c30ab7b3 SL |
72 | //! } |
73 | //! ``` | |
c30ab7b3 | 74 | #![crate_name = "proc_macro_plugin"] |
7cac9316 | 75 | #![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))] |
c30ab7b3 SL |
76 | #![feature(plugin_registrar)] |
77 | #![crate_type = "dylib"] | |
78 | #![crate_type = "rlib"] | |
79 | #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", | |
80 | html_favicon_url = "https://doc.rust-lang.org/favicon.ico", | |
81 | html_root_url = "https://doc.rust-lang.org/nightly/")] | |
32a655c1 | 82 | #![deny(warnings)] |
c30ab7b3 | 83 | |
7cac9316 | 84 | #![cfg_attr(stage0, feature(staged_api))] |
c30ab7b3 | 85 | #![feature(rustc_diagnostic_macros)] |
7cac9316 | 86 | #![cfg_attr(stage0, feature(rustc_private))] |
c30ab7b3 SL |
87 | |
88 | extern crate rustc_plugin; | |
89 | extern crate syntax; | |
90 | extern crate syntax_pos; | |
c30ab7b3 | 91 | |
cc61c64b XL |
92 | mod quote; |
93 | use quote::quote; | |
c30ab7b3 SL |
94 | |
95 | use rustc_plugin::Registry; | |
32a655c1 SL |
96 | use syntax::ext::base::SyntaxExtension; |
97 | use syntax::symbol::Symbol; | |
c30ab7b3 SL |
98 | |
99 | // ____________________________________________________________________________________________ | |
100 | // Main macro definition | |
101 | ||
102 | #[plugin_registrar] | |
103 | pub fn plugin_registrar(reg: &mut Registry) { | |
cc61c64b XL |
104 | reg.register_syntax_extension(Symbol::intern("quote"), |
105 | SyntaxExtension::ProcMacro(Box::new(quote))); | |
c30ab7b3 | 106 | } |