]> git.proxmox.com Git - rustc.git/blob - src/test/auxiliary/roman_numerals.rs
Imported Upstream version 1.6.0+dfsg1
[rustc.git] / src / test / auxiliary / roman_numerals.rs
1 // Copyright 2014 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 // force-host
12
13 #![crate_type="dylib"]
14 #![feature(plugin_registrar, rustc_private)]
15 #![feature(slice_patterns)]
16
17 extern crate syntax;
18 extern crate rustc;
19 extern crate rustc_plugin;
20
21 use syntax::codemap::Span;
22 use syntax::ast::TokenTree;
23 use syntax::parse::token;
24 use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
25 use syntax::ext::build::AstBuilder; // trait for expr_usize
26 use rustc_plugin::Registry;
27
28 // WARNING WARNING WARNING WARNING WARNING
29 // =======================================
30 //
31 // This code also appears in src/doc/guide-plugin.md. Please keep
32 // the two copies in sync! FIXME: have rustdoc read this file
33
34 fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
35 -> Box<MacResult + 'static> {
36
37 static NUMERALS: &'static [(&'static str, usize)] = &[
38 ("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
39 ("C", 100), ("XC", 90), ("L", 50), ("XL", 40),
40 ("X", 10), ("IX", 9), ("V", 5), ("IV", 4),
41 ("I", 1)];
42
43 if args.len() != 1 {
44 cx.span_err(
45 sp,
46 &format!("argument should be a single identifier, but got {} arguments", args.len()));
47 return DummyResult::any(sp);
48 }
49
50 let text = match args[0] {
51 TokenTree::Token(_, token::Ident(s, _)) => s.to_string(),
52 _ => {
53 cx.span_err(sp, "argument should be a single identifier");
54 return DummyResult::any(sp);
55 }
56 };
57
58 let mut text = &*text;
59 let mut total = 0;
60 while !text.is_empty() {
61 match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
62 Some(&(rn, val)) => {
63 total += val;
64 text = &text[rn.len()..];
65 }
66 None => {
67 cx.span_err(sp, "invalid Roman numeral");
68 return DummyResult::any(sp);
69 }
70 }
71 }
72
73 MacEager::expr(cx.expr_usize(sp, total))
74 }
75
76 #[plugin_registrar]
77 pub fn plugin_registrar(reg: &mut Registry) {
78 reg.register_macro("rn", expand_rn);
79 }