diff options
| author | bors <bors@rust-lang.org> | 2016-08-16 16:35:10 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-08-16 16:35:10 -0700 |
| commit | 1bf5fa3269ba32ae21e349ac675bdedcc7e99a66 (patch) | |
| tree | a7e9ecbddb7b1661c5455da1edc9e5c2d94c1140 /src/libsyntax | |
| parent | 514d4cef24a3a463d7423bd75d17335547c6a99c (diff) | |
| parent | 98c8e0a05dd7b1ecbbda28c1d01e05c1e41b1638 (diff) | |
| download | rust-1bf5fa3269ba32ae21e349ac675bdedcc7e99a66.tar.gz rust-1bf5fa3269ba32ae21e349ac675bdedcc7e99a66.zip | |
Auto merge of #35538 - cgswords:libproc_macro, r=nrc
Kicking off libproc_macro This PR introduces `libproc_macro`, which is currently quite bare-bones (just a few macro construction tools and an initial `quote!` macro). This PR also introduces a few test cases for it, and an additional `shim` file (at `src/libsyntax/ext/proc_macro_shim.rs` to allow a facsimile usage of Macros 2.0 *today*!
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/proc_macro_shim.rs | 69 | ||||
| -rw-r--r-- | src/libsyntax/lib.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/tokenstream.rs | 6 |
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 0171f24101a..7b1df6f0e97 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -589,6 +589,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 { |
