Crate proc_macro_plugin [] [src]

🔬 This is a nightly-only experimental API. (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
]