diff options
Diffstat (limited to 'macros/src/lib.rs')
-rw-r--r-- | macros/src/lib.rs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/macros/src/lib.rs b/macros/src/lib.rs new file mode 100644 index 00000000..05210fbb --- /dev/null +++ b/macros/src/lib.rs @@ -0,0 +1,63 @@ +#![feature(plugin_registrar)] +#![feature(proc_macro_internals)] +#![feature(rustc_private)] +#![recursion_limit = "128"] + +extern crate proc_macro; +#[macro_use] +extern crate quote; +extern crate rustc_errors; +extern crate rustc_plugin; +extern crate syn; +extern crate syntax as rustc_syntax; + +use proc_macro::TokenStream; +use rustc_errors::Handler; +use rustc_errors::emitter::ColorConfig; +use rustc_plugin::Registry; +use rustc_syntax::codemap::{CodeMap, FilePathMapping}; +use rustc_syntax::ext::base::SyntaxExtension; +use rustc_syntax::parse::ParseSess; +use rustc_syntax::symbol::Symbol; +use rustc_syntax::tokenstream::TokenStream as TokenStream_; +use std::rc::Rc; +use std::str::FromStr; + +mod check; +mod syntax; +mod trans; +mod util; + +fn expand_rtfm(ts: TokenStream_) -> TokenStream_ { + let input = format!("{}", ts); + + let app = syntax::parse::app(&input); + let ceilings = util::compute_ceilings(&app); + check::resources(&app.resources, &ceilings); + + let output = format!("{}", trans::app(&app, &ceilings)); + + let mapping = FilePathMapping::empty(); + let codemap = Rc::new(CodeMap::new(mapping)); + + let tty_handler = Handler::with_tty_emitter( + ColorConfig::Auto, + true, + false, + Some(codemap.clone()), + ); + + let sess = ParseSess::with_span_handler(tty_handler, codemap.clone()); + proc_macro::__internal::set_parse_sess(&sess, || { + let ts = TokenStream::from_str(&output).unwrap(); + proc_macro::__internal::token_stream_inner(ts) + }) +} + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_syntax_extension( + Symbol::intern("rtfm"), + SyntaxExtension::ProcMacro(Box::new(expand_rtfm)), + ); +} |