]> git.proxmox.com Git - rustc.git/blame - src/libproc_macro_plugin/lib.rs
New upstream version 1.19.0+dfsg1
[rustc.git] / src / libproc_macro_plugin / lib.rs
CommitLineData
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
88extern crate rustc_plugin;
89extern crate syntax;
90extern crate syntax_pos;
c30ab7b3 91
cc61c64b
XL
92mod quote;
93use quote::quote;
c30ab7b3
SL
94
95use rustc_plugin::Registry;
32a655c1
SL
96use syntax::ext::base::SyntaxExtension;
97use syntax::symbol::Symbol;
c30ab7b3
SL
98
99// ____________________________________________________________________________________________
100// Main macro definition
101
102#[plugin_registrar]
103pub fn plugin_registrar(reg: &mut Registry) {
cc61c64b
XL
104 reg.register_syntax_extension(Symbol::intern("quote"),
105 SyntaxExtension::ProcMacro(Box::new(quote)));
c30ab7b3 106}