about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorcgswords <cameronswords@gmail.com>2016-08-04 12:20:01 -0700
committercgswords <cameronswords@gmail.com>2016-08-16 13:17:36 -0700
commit98c8e0a05dd7b1ecbbda28c1d01e05c1e41b1638 (patch)
tree829168f08c68bcb796a37ef886e81a32f5c4e236 /src/libsyntax
parent32e462ef99e2f61b75e2b0ef37048d50ad8ccf6c (diff)
downloadrust-98c8e0a05dd7b1ecbbda28c1d01e05c1e41b1638.tar.gz
rust-98c8e0a05dd7b1ecbbda28c1d01e05c1e41b1638.zip
Proc_macro is alive
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/proc_macro_shim.rs69
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/tokenstream.rs6
3 files changed, 76 insertions, 0 deletions
diff --git a/src/libsyntax/ext/proc_macro_shim.rs b/src/libsyntax/ext/proc_macro_shim.rs
new file mode 100644
index 00000000000..fa37e9b54e4
--- /dev/null
+++ b/src/libsyntax/ext/proc_macro_shim.rs
@@ -0,0 +1,69 @@
+// Copyright 2016 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.
+
+//! This is a shim file to ease the transition to the final procedural macro interface for
+//! Macros 2.0. It currently exposes the `libsyntax` operations that the quasiquoter's
+//! output needs to compile correctly, along with the following operators:
+//!
+//! - `build_block_emitter`, which produces a `block` output macro result from the
+//!   provided TokenStream.
+
+use ast;
+use codemap::Span;
+use parse::parser::Parser;
+use ptr::P;
+use tokenstream::TokenStream;
+use ext::base::*;
+
+/// Take a `ExtCtxt`, `Span`, and `TokenStream`, and produce a Macro Result that parses
+/// the TokenStream as a block and returns it as an `Expr`.
+pub fn build_block_emitter<'cx>(cx: &'cx mut ExtCtxt, sp: Span, output: TokenStream)
+                                -> Box<MacResult + 'cx> {
+    let parser = cx.new_parser_from_tts(&output.to_tts());
+
+    struct Result<'a> {
+        prsr: Parser<'a>,
+        span: Span,
+    }; //FIXME is this the right lifetime
+
+    impl<'a> Result<'a> {
+        fn block(&mut self) -> P<ast::Block> {
+            let res = self.prsr.parse_block().unwrap();
+            res
+        }
+    }
+
+    impl<'a> MacResult for Result<'a> {
+        fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
+            let mut me = *self;
+            Some(P(ast::Expr {
+                id: ast::DUMMY_NODE_ID,
+                node: ast::ExprKind::Block(me.block()),
+                span: me.span,
+                attrs: ast::ThinVec::new(),
+            }))
+
+        }
+    }
+
+    Box::new(Result {
+        prsr: parser,
+        span: sp,
+    })
+}
+
+pub mod prelude {
+    pub use ext::proc_macro_shim::build_block_emitter;
+    pub use ast::Ident;
+    pub use codemap::{DUMMY_SP, Span};
+    pub use ext::base::{ExtCtxt, MacResult};
+    pub use parse::token::{self, Token, DelimToken, keywords, str_to_ident};
+    pub use tokenstream::{TokenTree, TokenStream};
+}
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 5ad17444188..b4311fc007d 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -128,6 +128,7 @@ pub mod ext {
     pub mod build;
     pub mod expand;
     pub mod hygiene;
+    pub mod proc_macro_shim;
     pub mod quote;
     pub mod source_util;
 
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 89ead21cc10..aab6f3d682e 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -548,6 +548,12 @@ impl TokenStream {
         TokenStream::mk_leaf(Rc::new(trees), span)
     }
 
+    /// Convert a vector of Tokens into a TokenStream.
+    pub fn from_tokens(tokens: Vec<Token>) -> TokenStream {
+        // FIXME do something nicer with the spans
+        TokenStream::from_tts(tokens.into_iter().map(|t| TokenTree::Token(DUMMY_SP, t)).collect())
+    }
+
     /// Manually change a TokenStream's span.
     pub fn respan(self, span: Span) -> TokenStream {
         match self.ts {