/src/test/auxiliary/procedural_mbe_matching.rs

https://gitlab.com/pranith/rust · Rust · 69 lines · 49 code · 10 blank · 10 comment · 5 complexity · af249c2fb1092b122ee3aa4478bcea66 MD5 · raw file

  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. // force-host
  11. #![crate_type="dylib"]
  12. #![feature(plugin_registrar, quote, rustc_private)]
  13. extern crate syntax;
  14. extern crate rustc;
  15. use syntax::codemap::Span;
  16. use syntax::parse::token::{self, str_to_ident, NtExpr, NtPat};
  17. use syntax::ast::{TokenTree, TtToken, Pat};
  18. use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
  19. use syntax::ext::build::AstBuilder;
  20. use syntax::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
  21. use syntax::ext::tt::macro_parser::{Success, Failure, Error};
  22. use syntax::ptr::P;
  23. use rustc::plugin::Registry;
  24. fn expand_mbe_matches(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
  25. -> Box<MacResult + 'static> {
  26. let mbe_matcher = quote_matcher!(cx, $matched:expr, $($pat:pat)|+);
  27. let mac_expr = match TokenTree::parse(cx, &mbe_matcher[..], args) {
  28. Success(map) => {
  29. match (&*map[&str_to_ident("matched")], &*map[&str_to_ident("pat")]) {
  30. (&MatchedNonterminal(NtExpr(ref matched_expr)),
  31. &MatchedSeq(ref pats, seq_sp)) => {
  32. let pats: Vec<P<Pat>> = pats.iter().map(|pat_nt|
  33. if let &MatchedNonterminal(NtPat(ref pat)) = &**pat_nt {
  34. pat.clone()
  35. } else {
  36. unreachable!()
  37. }
  38. ).collect();
  39. let arm = cx.arm(seq_sp, pats, cx.expr_bool(seq_sp, true));
  40. quote_expr!(cx,
  41. match $matched_expr {
  42. $arm
  43. _ => false
  44. }
  45. )
  46. }
  47. _ => unreachable!()
  48. }
  49. }
  50. Failure(_, s) | Error(_, s) => {
  51. panic!("expected Success, but got Error/Failure: {}", s);
  52. }
  53. };
  54. MacEager::expr(mac_expr)
  55. }
  56. #[plugin_registrar]
  57. pub fn plugin_registrar(reg: &mut Registry) {
  58. reg.register_macro("matches", expand_mbe_matches);
  59. }