about summary refs log tree commit diff
path: root/src/libproc_macro_plugin
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2017-03-17 23:41:09 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2017-06-26 02:06:26 +0000
commite42836b2085233323339bacb636ecf9c28e8422e (patch)
treec43855deb6274dce6bbafb7efb75bd9ac8b95f97 /src/libproc_macro_plugin
parent7d41674b175cdb3452e042ef6f37141bc3788f8b (diff)
Implement `quote!` and other `proc_macro` API.
Diffstat (limited to 'src/libproc_macro_plugin')
-rw-r--r--src/libproc_macro_plugin/Cargo.toml13
-rw-r--r--src/libproc_macro_plugin/lib.rs103
-rw-r--r--src/libproc_macro_plugin/quote.rs230
3 files changed, 0 insertions, 346 deletions
diff --git a/src/libproc_macro_plugin/Cargo.toml b/src/libproc_macro_plugin/Cargo.toml
deleted file mode 100644
index 146a66cdf01..00000000000
--- a/src/libproc_macro_plugin/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "proc_macro_plugin"
-version = "0.0.0"
-
-[lib]
-path = "lib.rs"
-crate-type = ["dylib"]
-
-[dependencies]
-rustc_plugin = { path = "../librustc_plugin" }
-syntax = { path = "../libsyntax" }
-syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/libproc_macro_plugin/lib.rs b/src/libproc_macro_plugin/lib.rs
deleted file mode 100644
index d1bc0966eb5..00000000000
--- a/src/libproc_macro_plugin/lib.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! # Proc_Macro
-//!
-//! A library for procedural macro writers.
-//!
-//! ## Usage
-//! This crate provides the `quote!` macro for syntax creation.
-//!
-//! The `quote!` macro uses the crate `syntax`, so users must declare `extern crate syntax;`
-//! at the crate root. This is a temporary solution until we have better hygiene.
-//!
-//! ## Quasiquotation
-//!
-//! The quasiquoter creates output that, when run, constructs the tokenstream specified as
-//! input. For example, `quote!(5 + 5)` will produce a program, that, when run, will
-//! construct the TokenStream `5 | + | 5`.
-//!
-//! ### Unquoting
-//!
-//! Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
-//! To quote `$` itself, use `$$`.
-//!
-//! A simple example is:
-//!
-//!```
-//!fn double(tmp: TokenStream) -> TokenStream {
-//!    quote!($tmp * 2)
-//!}
-//!```
-//!
-//! ### Large example: Scheme's `cond`
-//!
-//! Below is an example implementation of Scheme's `cond`.
-//!
-//! ```
-//! fn cond(input: TokenStream) -> TokenStream {
-//!     let mut conds = Vec::new();
-//!     let mut input = input.trees().peekable();
-//!     while let Some(tree) = input.next() {
-//!         let mut cond = match tree {
-//!             TokenTree::Delimited(_, ref delimited) => delimited.stream(),
-//!             _ => panic!("Invalid input"),
-//!         };
-//!         let mut trees = cond.trees();
-//!         let test = trees.next();
-//!         let rhs = trees.collect::<TokenStream>();
-//!         if rhs.is_empty() {
-//!             panic!("Invalid macro usage in cond: {}", cond);
-//!         }
-//!         let is_else = match test {
-//!             Some(TokenTree::Token(_, Token::Ident(ident))) if ident.name == "else" => true,
-//!             _ => false,
-//!         };
-//!         conds.push(if is_else || input.peek().is_none() {
-//!             quote!({ $rhs })
-//!         } else {
-//!             let test = test.unwrap();
-//!             quote!(if $test { $rhs } else)
-//!         });
-//!     }
-//!
-//!     conds.into_iter().collect()
-//! }
-//! ```
-#![crate_name = "proc_macro_plugin"]
-#![feature(plugin_registrar)]
-#![crate_type = "dylib"]
-#![crate_type = "rlib"]
-#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
-       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
-
-#![feature(rustc_diagnostic_macros)]
-
-extern crate rustc_plugin;
-extern crate syntax;
-extern crate syntax_pos;
-
-mod quote;
-use quote::quote;
-
-use rustc_plugin::Registry;
-use syntax::ext::base::SyntaxExtension;
-use syntax::symbol::Symbol;
-
-// ____________________________________________________________________________________________
-// Main macro definition
-
-#[plugin_registrar]
-pub fn plugin_registrar(reg: &mut Registry) {
-    reg.register_syntax_extension(Symbol::intern("quote"),
-                                  SyntaxExtension::ProcMacro(Box::new(quote)));
-}
diff --git a/src/libproc_macro_plugin/quote.rs b/src/libproc_macro_plugin/quote.rs
deleted file mode 100644
index 09675564291..00000000000
--- a/src/libproc_macro_plugin/quote.rs
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! # Quasiquoter
-//! This file contains the implementation internals of the quasiquoter provided by `qquote!`.
-
-use syntax::ast::Ident;
-use syntax::parse::token::{self, Token, Lit};
-use syntax::symbol::Symbol;
-use syntax::tokenstream::{self, Delimited, TokenTree, TokenStream};
-use syntax_pos::DUMMY_SP;
-
-use std::iter;
-
-pub fn quote<'cx>(stream: TokenStream) -> TokenStream {
-    stream.quote()
-}
-
-trait Quote {
-    fn quote(&self) -> TokenStream;
-}
-
-macro_rules! quote_tok {
-    (,) => { Token::Comma };
-    (.) => { Token::Dot };
-    (:) => { Token::Colon };
-    (::) => { Token::ModSep };
-    (!) => { Token::Not };
-    (<) => { Token::Lt };
-    (>) => { Token::Gt };
-    (_) => { Token::Underscore };
-    ($i:ident) => { Token::Ident(Ident::from_str(stringify!($i))) };
-}
-
-macro_rules! quote_tree {
-    ((unquote $($t:tt)*)) => { $($t)* };
-    ((quote $($t:tt)*)) => { ($($t)*).quote() };
-    (($($t:tt)*)) => { delimit(token::Paren, quote!($($t)*)) };
-    ([$($t:tt)*]) => { delimit(token::Bracket, quote!($($t)*)) };
-    ({$($t:tt)*}) => { delimit(token::Brace, quote!($($t)*)) };
-    ($t:tt) => { TokenStream::from(TokenTree::Token(DUMMY_SP, quote_tok!($t))) };
-}
-
-fn delimit(delim: token::DelimToken, stream: TokenStream) -> TokenStream {
-    TokenTree::Delimited(DUMMY_SP, Delimited { delim: delim, tts: stream.into() }).into()
-}
-
-macro_rules! quote {
-    () => { TokenStream::empty() };
-    ($($t:tt)*) => { [ $( quote_tree!($t), )* ].iter().cloned().collect::<TokenStream>() };
-}
-
-impl<T: Quote> Quote for Option<T> {
-    fn quote(&self) -> TokenStream {
-        match *self {
-            Some(ref t) => quote!(::std::option::Option::Some((quote t))),
-            None => quote!(::std::option::Option::None),
-        }
-    }
-}
-
-impl Quote for TokenStream {
-    fn quote(&self) -> TokenStream {
-        if self.is_empty() {
-            return quote!(::syntax::tokenstream::TokenStream::empty());
-        }
-
-        struct Quoter(iter::Peekable<tokenstream::Cursor>);
-
-        impl Iterator for Quoter {
-            type Item = TokenStream;
-
-            fn next(&mut self) -> Option<TokenStream> {
-                let quoted_tree = if let Some(&TokenTree::Token(_, Token::Dollar)) = self.0.peek() {
-                    self.0.next();
-                    match self.0.next() {
-                        Some(tree @ TokenTree::Token(_, Token::Ident(..))) => Some(tree.into()),
-                        Some(tree @ TokenTree::Token(_, Token::Dollar)) => Some(tree.quote()),
-                        // FIXME(jseyfried): improve these diagnostics
-                        Some(..) => panic!("`$` must be followed by an ident or `$` in `quote!`"),
-                        None => panic!("unexpected trailing `$` in `quote!`"),
-                    }
-                } else {
-                    self.0.next().as_ref().map(Quote::quote)
-                };
-
-                quoted_tree.map(|quoted_tree| {
-                    quote!(::syntax::tokenstream::TokenStream::from((unquote quoted_tree)),)
-                })
-            }
-        }
-
-        let quoted = Quoter(self.trees().peekable()).collect::<TokenStream>();
-        quote!([(unquote quoted)].iter().cloned().collect::<::syntax::tokenstream::TokenStream>())
-    }
-}
-
-impl Quote for TokenTree {
-    fn quote(&self) -> TokenStream {
-        match *self {
-            TokenTree::Token(_, ref token) => quote! {
-                ::syntax::tokenstream::TokenTree::Token(::syntax::ext::quote::rt::DUMMY_SP,
-                                                        (quote token))
-            },
-            TokenTree::Delimited(_, ref delimited) => quote! {
-                ::syntax::tokenstream::TokenTree::Delimited(::syntax::ext::quote::rt::DUMMY_SP,
-                                                            (quote delimited))
-            },
-        }
-    }
-}
-
-impl Quote for Delimited {
-    fn quote(&self) -> TokenStream {
-        quote!(::syntax::tokenstream::Delimited {
-            delim: (quote self.delim),
-            tts: (quote self.stream()).into(),
-        })
-    }
-}
-
-impl<'a> Quote for &'a str {
-    fn quote(&self) -> TokenStream {
-        TokenTree::Token(DUMMY_SP, Token::Literal(token::Lit::Str_(Symbol::intern(self)), None))
-            .into()
-    }
-}
-
-impl Quote for usize {
-    fn quote(&self) -> TokenStream {
-        let integer_symbol = Symbol::intern(&self.to_string());
-        TokenTree::Token(DUMMY_SP, Token::Literal(token::Lit::Integer(integer_symbol), None))
-            .into()
-    }
-}
-
-impl Quote for Ident {
-    fn quote(&self) -> TokenStream {
-        // FIXME(jseyfried) quote hygiene
-        quote!(::syntax::ast::Ident::from_str((quote &*self.name.as_str())))
-    }
-}
-
-impl Quote for Symbol {
-    fn quote(&self) -> TokenStream {
-        quote!(::syntax::symbol::Symbol::intern((quote &*self.as_str())))
-    }
-}
-
-impl Quote for Token {
-    fn quote(&self) -> TokenStream {
-        macro_rules! gen_match {
-            ($($i:ident),*; $($t:tt)*) => {
-                match *self {
-                    $( Token::$i => quote!(::syntax::parse::token::$i), )*
-                    $( $t )*
-                }
-            }
-        }
-
-        gen_match! {
-            Eq, Lt, Le, EqEq, Ne, Ge, Gt, AndAnd, OrOr, Not, Tilde, At, Dot, DotDot, DotDotDot,
-            Comma, Semi, Colon, ModSep, RArrow, LArrow, FatArrow, Pound, Dollar, Question,
-            Underscore;
-
-            Token::OpenDelim(delim) => quote!(::syntax::parse::token::OpenDelim((quote delim))),
-            Token::CloseDelim(delim) => quote!(::syntax::parse::token::CloseDelim((quote delim))),
-            Token::BinOp(tok) => quote!(::syntax::parse::token::BinOp((quote tok))),
-            Token::BinOpEq(tok) => quote!(::syntax::parse::token::BinOpEq((quote tok))),
-            Token::Ident(ident) => quote!(::syntax::parse::token::Ident((quote ident))),
-            Token::Lifetime(ident) => quote!(::syntax::parse::token::Lifetime((quote ident))),
-            Token::Literal(lit, sfx) => quote! {
-                ::syntax::parse::token::Literal((quote lit), (quote sfx))
-            },
-            _ => panic!("Unhandled case!"),
-        }
-    }
-}
-
-impl Quote for token::BinOpToken {
-    fn quote(&self) -> TokenStream {
-        macro_rules! gen_match {
-            ($($i:ident),*) => {
-                match *self {
-                    $( token::BinOpToken::$i => quote!(::syntax::parse::token::BinOpToken::$i), )*
-                }
-            }
-        }
-
-        gen_match!(Plus, Minus, Star, Slash, Percent, Caret, And, Or, Shl, Shr)
-    }
-}
-
-impl Quote for Lit {
-    fn quote(&self) -> TokenStream {
-        macro_rules! gen_match {
-            ($($i:ident),*; $($raw:ident),*) => {
-                match *self {
-                    $( Lit::$i(lit) => quote!(::syntax::parse::token::Lit::$i((quote lit))), )*
-                    $( Lit::$raw(lit, n) => {
-                        quote!(::syntax::parse::token::Lit::$raw((quote lit), (quote n)))
-                    })*
-                }
-            }
-        }
-
-        gen_match!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw)
-    }
-}
-
-impl Quote for token::DelimToken {
-    fn quote(&self) -> TokenStream {
-        macro_rules! gen_match {
-            ($($i:ident),*) => {
-                match *self {
-                    $(token::DelimToken::$i => { quote!(::syntax::parse::token::DelimToken::$i) })*
-                }
-            }
-        }
-
-        gen_match!(Paren, Bracket, Brace, NoDelim)
-    }
-}