about summary refs log tree commit diff
path: root/src/libsyntax_ext/proc_macro_impl.rs
diff options
context:
space:
mode:
authorAustin Bonander <austin.bonander@gmail.com>2017-02-27 12:03:19 -0800
committerAustin Bonander <austin.bonander@gmail.com>2017-02-28 18:34:22 -0800
commit2fcbb48c727e82ea8751d6476d86fd3c6fe16b42 (patch)
tree0b738571ef71885d370f3cce871793593c591303 /src/libsyntax_ext/proc_macro_impl.rs
parent4be034e62270ca15c9fff173faef11939092f4e3 (diff)
downloadrust-2fcbb48c727e82ea8751d6476d86fd3c6fe16b42.tar.gz
rust-2fcbb48c727e82ea8751d6476d86fd3c6fe16b42.zip
Implement function-like procedural macros ( `#[proc_macro]`)
Diffstat (limited to 'src/libsyntax_ext/proc_macro_impl.rs')
-rw-r--r--src/libsyntax_ext/proc_macro_impl.rs35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs
index b454628acb1..f60e5824db9 100644
--- a/src/libsyntax_ext/proc_macro_impl.rs
+++ b/src/libsyntax_ext/proc_macro_impl.rs
@@ -56,3 +56,38 @@ impl base::AttrProcMacro for AttrProcMacro {
         }
     }
 }
+
+pub struct BangProcMacro {
+    pub inner: fn(TsShim) -> TsShim,
+}
+
+impl base::ProcMacro for BangProcMacro {
+    fn expand<'cx>(&self,
+                   ecx: &'cx mut ExtCtxt,
+                   span: Span,
+                   input: TokenStream)
+                   -> TokenStream {
+        let input = __internal::token_stream_wrap(input);
+
+        let res = __internal::set_parse_sess(&ecx.parse_sess, || {
+            panic::catch_unwind(panic::AssertUnwindSafe(|| (self.inner)(input)))
+        });
+
+        match res {
+            Ok(stream) => __internal::token_stream_inner(stream),
+            Err(e) => {
+                let msg = "proc macro panicked";
+                let mut err = ecx.struct_span_fatal(span, msg);
+                if let Some(s) = e.downcast_ref::<String>() {
+                    err.help(&format!("message: {}", s));
+                }
+                if let Some(s) = e.downcast_ref::<&'static str>() {
+                    err.help(&format!("message: {}", s));
+                }
+
+                err.emit();
+                panic!(FatalError);
+            }
+        }
+    }
+}