Crate proc_macro_plugin [−] [src]
rustc_private
)Proc_Macro
A library for procedural macro writers.
## Usage
This crate provides the qquote!
macro for syntax creation.
The qquote!
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, qquote!(5 + 5)
will produce a program, that, when run, will
construct the TokenStream 5 | + | 5
.
### Unquoting
Unquoting is currently done as unquote
, and works by taking the single next
TokenTree in the TokenStream as the unquoted term. Ergonomically, unquote(foo)
works
fine, but unquote foo
is also supported.
A simple example might be:
fn double(tmp: TokenStream) -> TokenStream { qquote!(unquote(tmp) * 2) }
### Large Example: Implementing Scheme's cond
Below is the full implementation of Scheme's cond
operator.
fn cond_rec(input: TokenStream) -> TokenStream { if input.is_empty() { return quote!(); } let next = input.slice(0..1); let rest = input.slice_from(1..); let clause : TokenStream = match next.maybe_delimited() { Some(ts) => ts, _ => panic!("Invalid input"), }; // clause is ([test]) [rhs] if clause.len() < 2 { panic!("Invalid macro usage in cond: {:?}", clause) } let test: TokenStream = clause.slice(0..1); let rhs: TokenStream = clause.slice_from(1..); if ident_eq(&test[0], str_to_ident("else")) || rest.is_empty() { quote!({unquote(rhs)}) } else { quote!({if unquote(test) { unquote(rhs) } else { cond!(unquote(rest)) } }) } }
Functions
plugin_registrar |
[ Experimental ]
|