]> git.lizzy.rs Git - rust.git/blob - src/libproc_macro_plugin/lib.rs
Fix regression on `include!(line!())`.
[rust.git] / src / libproc_macro_plugin / lib.rs
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
16 //! This crate provides the `quote!` macro for syntax creation.
17 //!
18 //! The `quote!` macro uses the crate `syntax`, so users must declare `extern crate syntax;`
19 //! at the crate root. This is a temporary solution until we have better hygiene.
20 //!
21 //! ## Quasiquotation
22 //!
23 //! The quasiquoter creates output that, when run, constructs the tokenstream specified as
24 //! input. For example, `quote!(5 + 5)` will produce a program, that, when run, will
25 //! construct the TokenStream `5 | + | 5`.
26 //!
27 //! ### Unquoting
28 //!
29 //! Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
30 //! To quote `$` itself, use `$$`.
31 //!
32 //! A simple example is:
33 //!
34 //!```
35 //!fn double(tmp: TokenStream) -> TokenStream {
36 //!    quote!($tmp * 2)
37 //!}
38 //!```
39 //!
40 //! ### Large example: Scheme's `cond`
41 //!
42 //! Below is an example implementation of Scheme's `cond`.
43 //!
44 //! ```
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()
72 //! }
73 //! ```
74 #![crate_name = "proc_macro_plugin"]
75 #![unstable(feature = "rustc_private", issue = "27812")]
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/")]
82 #![deny(warnings)]
83
84 #![feature(staged_api)]
85 #![feature(rustc_diagnostic_macros)]
86 #![feature(rustc_private)]
87
88 extern crate rustc_plugin;
89 extern crate syntax;
90 extern crate syntax_pos;
91
92 mod quote;
93 use quote::quote;
94
95 use rustc_plugin::Registry;
96 use syntax::ext::base::SyntaxExtension;
97 use syntax::symbol::Symbol;
98
99 // ____________________________________________________________________________________________
100 // Main macro definition
101
102 #[plugin_registrar]
103 pub fn plugin_registrar(reg: &mut Registry) {
104     reg.register_syntax_extension(Symbol::intern("quote"),
105                                   SyntaxExtension::ProcMacro(Box::new(quote)));
106 }