Skip to content

Instantly share code, notes, and snippets.

@cgswords
Last active July 28, 2016 23:50
Show Gist options
  • Save cgswords/582857c82c9bb390fd4e981bb0ca5a51 to your computer and use it in GitHub Desktop.
Save cgswords/582857c82c9bb390fd4e981bb0ca5a51 to your computer and use it in GitHub Desktop.
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_macro("cond", cond);
}
fn cond<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<base::MacResult + 'cx> {
let output = cond_rec(TokenStream::from_tts(tts.clone().to_owned()));
build_emitter(cx, sp, output)
}
fn cond_rec(input: TokenStream) -> TokenStream {
if input.is_empty() { return qquote!(); }
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"),
};
if clause.len() < 2 { panic!("Invalid macro usage in cond: {:?}", clause) } // clause is ([test]) [rhs]
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() {
qquote!({unquote(rhs)})
} else {
qquote!({if unquote(test) { unquote(rhs) } else { cond!(unquote(rest)) } })
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment