]> git.lizzy.rs Git - rust.git/blob - src/test/ui-fulldeps/auxiliary/roman-numerals.rs
Replace AstBuilder with inherent methods
[rust.git] / src / test / ui-fulldeps / auxiliary / roman-numerals.rs
1 // WARNING WARNING WARNING WARNING WARNING
2 // =======================================
3 //
4 // This code also appears in src/doc/unstable-book/src/language-features/plugin.md.
5 // Please keep the two copies in sync!  FIXME: have rustdoc read this file
6
7 // force-host
8
9 #![crate_type="dylib"]
10 #![feature(plugin_registrar, rustc_private)]
11
12 extern crate syntax;
13 extern crate syntax_pos;
14 extern crate rustc;
15 extern crate rustc_plugin;
16 extern crate rustc_driver;
17
18 use syntax::parse::token::{self, Token};
19 use syntax::tokenstream::TokenTree;
20 use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
21 use syntax_pos::Span;
22 use rustc_plugin::Registry;
23
24 fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
25         -> Box<dyn MacResult + 'static> {
26
27     static NUMERALS: &'static [(&'static str, usize)] = &[
28         ("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
29         ("C",  100), ("XC",  90), ("L",  50), ("XL",  40),
30         ("X",   10), ("IX",   9), ("V",   5), ("IV",   4),
31         ("I",    1)];
32
33     if args.len() != 1 {
34         cx.span_err(
35             sp,
36             &format!("argument should be a single identifier, but got {} arguments", args.len()));
37         return DummyResult::any(sp);
38     }
39
40     let text = match args[0] {
41         TokenTree::Token(Token { kind: token::Ident(s, _), .. }) => s.to_string(),
42         _ => {
43             cx.span_err(sp, "argument should be a single identifier");
44             return DummyResult::any(sp);
45         }
46     };
47
48     let mut text = &*text;
49     let mut total = 0;
50     while !text.is_empty() {
51         match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
52             Some(&(rn, val)) => {
53                 total += val;
54                 text = &text[rn.len()..];
55             }
56             None => {
57                 cx.span_err(sp, "invalid Roman numeral");
58                 return DummyResult::any(sp);
59             }
60         }
61     }
62
63     MacEager::expr(cx.expr_usize(sp, total))
64 }
65
66 #[plugin_registrar]
67 pub fn plugin_registrar(reg: &mut Registry) {
68     reg.register_macro("rn", expand_rn);
69 }