/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs
https://gitlab.com/alx741/rust · Rust · 79 lines · 52 code · 12 blank · 15 comment · 5 complexity · 96741d6ebd3fffb0c9e3d452a15388fe MD5 · raw file
- // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
- // file at the top-level directory of this distribution and at
- // http://rust-lang.org/COPYRIGHT.
- //
- // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
- // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
- // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
- // option. This file may not be copied, modified, or distributed
- // except according to those terms.
- // force-host
- #![crate_type="dylib"]
- #![feature(plugin_registrar, rustc_private)]
- #![feature(slice_patterns)]
- extern crate syntax;
- extern crate rustc;
- extern crate rustc_plugin;
- use syntax::codemap::Span;
- use syntax::ast::TokenTree;
- use syntax::parse::token;
- use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
- use syntax::ext::build::AstBuilder; // trait for expr_usize
- use rustc_plugin::Registry;
- // WARNING WARNING WARNING WARNING WARNING
- // =======================================
- //
- // This code also appears in src/doc/guide-plugin.md. Please keep
- // the two copies in sync! FIXME: have rustdoc read this file
- fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
- -> Box<MacResult + 'static> {
- static NUMERALS: &'static [(&'static str, usize)] = &[
- ("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
- ("C", 100), ("XC", 90), ("L", 50), ("XL", 40),
- ("X", 10), ("IX", 9), ("V", 5), ("IV", 4),
- ("I", 1)];
- if args.len() != 1 {
- cx.span_err(
- sp,
- &format!("argument should be a single identifier, but got {} arguments", args.len()));
- return DummyResult::any(sp);
- }
- let text = match args[0] {
- TokenTree::Token(_, token::Ident(s)) => s.to_string(),
- _ => {
- cx.span_err(sp, "argument should be a single identifier");
- return DummyResult::any(sp);
- }
- };
- let mut text = &*text;
- let mut total = 0;
- while !text.is_empty() {
- match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
- Some(&(rn, val)) => {
- total += val;
- text = &text[rn.len()..];
- }
- None => {
- cx.span_err(sp, "invalid Roman numeral");
- return DummyResult::any(sp);
- }
- }
- }
- MacEager::expr(cx.expr_usize(sp, total))
- }
- #[plugin_registrar]
- pub fn plugin_registrar(reg: &mut Registry) {
- reg.register_macro("rn", expand_rn);
- }