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.
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.
13 #![crate_type="dylib"]
14 #![feature(plugin_registrar, quote, rustc_private)]
17 extern crate syntax_pos;
19 extern crate rustc_plugin;
21 use syntax::feature_gate::Features;
22 use syntax::parse::token::{NtExpr, NtPat};
23 use syntax::ast::{Ident, Pat};
24 use syntax::tokenstream::{TokenTree};
25 use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
26 use syntax::ext::build::AstBuilder;
27 use syntax::ext::tt::quoted;
28 use syntax::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
29 use syntax::ext::tt::macro_parser::{Success, Failure, Error};
30 use syntax::ext::tt::macro_parser::parse_failure_msg;
33 use rustc_plugin::Registry;
35 use std::cell::RefCell;
37 fn expand_mbe_matches(cx: &mut ExtCtxt, _: Span, args: &[TokenTree])
38 -> Box<MacResult + 'static> {
40 let mbe_matcher = quote_tokens!(cx, $$matched:expr, $$($$pat:pat)|+);
41 let mbe_matcher = quoted::parse(mbe_matcher.into_iter().collect(),
46 let map = match TokenTree::parse(cx, &mbe_matcher, args.iter().cloned().collect()) {
49 panic!("expected Success, but got Failure: {}", parse_failure_msg(tok));
52 panic!("expected Success, but got Error: {}", s);
56 let matched_nt = match *map[&Ident::from_str("matched")] {
57 MatchedNonterminal(ref nt) => nt.clone(),
61 let mac_expr = match (&*matched_nt, &*map[&Ident::from_str("pat")]) {
62 (&NtExpr(ref matched_expr), &MatchedSeq(ref pats, seq_sp)) => {
63 let pats: Vec<P<Pat>> = pats.iter().map(|pat_nt| {
65 MatchedNonterminal(ref nt) => match **nt {
66 NtPat(ref pat) => pat.clone(),
72 let arm = cx.arm(seq_sp, pats, cx.expr_bool(seq_sp, true));
84 MacEager::expr(mac_expr)
88 pub fn plugin_registrar(reg: &mut Registry) {
89 reg.register_macro("matches", expand_mbe_matches);