]> git.proxmox.com Git - rustc.git/blob - src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs
New upstream version 1.14.0+dfsg1
[rustc.git] / src / test / run-pass-fulldeps / auxiliary / cond_noprelude_plugin.rs
1 // Copyright 2015 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 #![allow(unused_parens)]
12 #![feature(plugin)]
13 #![feature(plugin_registrar)]
14 #![feature(rustc_private)]
15 #![plugin(proc_macro_plugin)]
16
17 extern crate rustc_plugin;
18 extern crate proc_macro_tokens;
19 extern crate syntax;
20
21 use proc_macro_tokens::build::ident_eq;
22
23 use syntax::ext::base::{ExtCtxt, MacResult};
24 use syntax::ext::proc_macro_shim::build_block_emitter;
25 use syntax::tokenstream::{TokenTree, TokenStream};
26 use syntax::parse::token::str_to_ident;
27 use syntax::codemap::Span;
28
29 use rustc_plugin::Registry;
30
31 #[plugin_registrar]
32 pub fn plugin_registrar(reg: &mut Registry) {
33 reg.register_macro("cond", cond);
34 }
35
36 fn cond<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResult + 'cx> {
37 let output = cond_rec(TokenStream::from_tts(tts.clone().to_owned()));
38 build_block_emitter(cx, sp, output)
39 }
40
41 fn cond_rec(input: TokenStream) -> TokenStream {
42 if input.is_empty() {
43 return qquote!();
44 }
45
46 let next = input.slice(0..1);
47 let rest = input.slice_from(1..);
48
49 let clause : TokenStream = match next.maybe_delimited() {
50 Some(ts) => ts,
51 _ => panic!("Invalid input"),
52 };
53
54 // clause is ([test]) [rhs]
55 if clause.len() < 2 { panic!("Invalid macro usage in cond: {:?}", clause) }
56
57 let test: TokenStream = clause.slice(0..1);
58 let rhs: TokenStream = clause.slice_from(1..);
59
60 if ident_eq(&test[0], str_to_ident("else")) || rest.is_empty() {
61 qquote!({unquote(rhs)})
62 } else {
63 qquote!({if unquote(test) { unquote(rhs) } else { cond!(unquote(rest)) } })
64 }
65 }