Skip to content

Commit 5889a8e

Browse files
committed
Fill out an unstable implementation
This is verified to compile and work against the current version of rust-lang/rust#40939.
1 parent 1d7628c commit 5889a8e

File tree

2 files changed

+334
-1
lines changed

2 files changed

+334
-1
lines changed

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![cfg_attr(feature = "unstable", feature(proc_macro))]
2+
13
extern crate proc_macro;
24

35
#[cfg(not(feature = "unstable"))]

src/unstable.rs

Lines changed: 332 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,332 @@
1-
pub use proc_macro::*;
1+
use std::ascii;
2+
use std::fmt;
3+
use std::iter;
4+
use std::ops;
5+
use std::str::FromStr;
6+
7+
use proc_macro;
8+
9+
use {TokenTree, TokenKind, Delimiter, OpKind};
10+
11+
#[derive(Clone)]
12+
pub struct TokenStream(proc_macro::TokenStream);
13+
14+
pub struct LexError(proc_macro::LexError);
15+
16+
impl TokenStream {
17+
pub fn empty() -> TokenStream {
18+
TokenStream(proc_macro::TokenStream::empty())
19+
}
20+
21+
pub fn is_empty(&self) -> bool {
22+
self.0.is_empty()
23+
}
24+
}
25+
26+
impl FromStr for TokenStream {
27+
type Err = LexError;
28+
29+
fn from_str(src: &str) -> Result<TokenStream, LexError> {
30+
Ok(TokenStream(src.parse().map_err(LexError)?))
31+
}
32+
}
33+
34+
impl fmt::Display for TokenStream {
35+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36+
self.0.fmt(f)
37+
}
38+
}
39+
40+
impl From<proc_macro::TokenStream> for TokenStream {
41+
fn from(inner: proc_macro::TokenStream) -> TokenStream {
42+
TokenStream(inner)
43+
}
44+
}
45+
46+
impl From<TokenStream> for proc_macro::TokenStream {
47+
fn from(inner: TokenStream) -> proc_macro::TokenStream {
48+
inner.0
49+
}
50+
}
51+
52+
53+
impl From<TokenTree> for TokenStream {
54+
fn from(tree: TokenTree) -> TokenStream {
55+
TokenStream(proc_macro::TokenTree {
56+
span: (tree.span.0).0,
57+
kind: match tree.kind {
58+
TokenKind::Sequence(delim, s) => {
59+
let delim = match delim {
60+
Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
61+
Delimiter::Bracket => proc_macro::Delimiter::Bracket,
62+
Delimiter::Brace => proc_macro::Delimiter::Brace,
63+
Delimiter::None => proc_macro::Delimiter::None,
64+
};
65+
proc_macro::TokenKind::Sequence(delim, (s.0).0)
66+
}
67+
TokenKind::Op(ch, kind) => {
68+
let kind = match kind {
69+
OpKind::Joint => proc_macro::OpKind::Joint,
70+
OpKind::Alone => proc_macro::OpKind::Alone,
71+
};
72+
proc_macro::TokenKind::Op(ch, kind)
73+
}
74+
TokenKind::Word(s) => {
75+
proc_macro::TokenKind::Word((s.0).0)
76+
}
77+
TokenKind::Literal(l) => {
78+
proc_macro::TokenKind::Literal((l.0).0)
79+
}
80+
},
81+
}.into())
82+
}
83+
}
84+
85+
impl iter::FromIterator<TokenStream> for TokenStream {
86+
fn from_iter<I: IntoIterator<Item=TokenStream>>(streams: I) -> Self {
87+
let streams = streams.into_iter().map(|s| s.0);
88+
TokenStream(streams.collect::<proc_macro::TokenStream>())
89+
}
90+
}
91+
92+
impl fmt::Debug for TokenStream {
93+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94+
f.debug_struct("TokenStream")
95+
.field("tts", &self.clone().into_iter().collect::<Vec<_>>())
96+
.finish()
97+
}
98+
}
99+
100+
impl fmt::Debug for LexError {
101+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102+
f.debug_struct("LexError").finish()
103+
}
104+
}
105+
106+
pub struct TokenIter(proc_macro::TokenIter);
107+
108+
impl IntoIterator for TokenStream {
109+
type Item = TokenTree;
110+
type IntoIter = TokenIter;
111+
112+
fn into_iter(self) -> TokenIter {
113+
TokenIter(self.0.into_iter())
114+
}
115+
}
116+
117+
impl Iterator for TokenIter {
118+
type Item = TokenTree;
119+
120+
fn next(&mut self) -> Option<TokenTree> {
121+
let token = match self.0.next() {
122+
Some(n) => n,
123+
None => return None,
124+
};
125+
Some(TokenTree {
126+
span: ::Span(Span(token.span)),
127+
kind: match token.kind {
128+
proc_macro::TokenKind::Sequence(delim, s) => {
129+
let delim = match delim {
130+
proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
131+
proc_macro::Delimiter::Bracket => Delimiter::Bracket,
132+
proc_macro::Delimiter::Brace => Delimiter::Brace,
133+
proc_macro::Delimiter::None => Delimiter::None,
134+
};
135+
TokenKind::Sequence(delim, ::TokenStream(TokenStream(s)))
136+
}
137+
proc_macro::TokenKind::Op(ch, kind) => {
138+
let kind = match kind {
139+
proc_macro::OpKind::Joint => OpKind::Joint,
140+
proc_macro::OpKind::Alone => OpKind::Alone,
141+
};
142+
TokenKind::Op(ch, kind)
143+
}
144+
proc_macro::TokenKind::Word(s) => {
145+
TokenKind::Word(::Symbol(Symbol(s)))
146+
}
147+
proc_macro::TokenKind::Literal(l) => {
148+
TokenKind::Literal(::Literal(Literal(l)))
149+
}
150+
},
151+
})
152+
}
153+
154+
fn size_hint(&self) -> (usize, Option<usize>) {
155+
self.0.size_hint()
156+
}
157+
}
158+
159+
impl fmt::Debug for TokenIter {
160+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161+
f.debug_struct("TokenIter").finish()
162+
}
163+
}
164+
165+
#[derive(Copy, Clone, Default)]
166+
pub struct Span(proc_macro::Span);
167+
168+
impl Span {
169+
pub fn call_site() -> Span {
170+
Span(proc_macro::Span::call_site())
171+
}
172+
}
173+
174+
impl fmt::Debug for Span {
175+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
176+
f.debug_struct("Span")
177+
.finish()
178+
}
179+
}
180+
181+
#[derive(Copy, Clone)]
182+
pub struct Symbol(proc_macro::Symbol);
183+
184+
impl<'a> From<&'a str> for Symbol {
185+
fn from(string: &'a str) -> Symbol {
186+
Symbol(string.into())
187+
}
188+
}
189+
190+
impl ops::Deref for Symbol {
191+
type Target = str;
192+
193+
fn deref(&self) -> &str {
194+
&self.0
195+
}
196+
}
197+
198+
impl fmt::Debug for Symbol {
199+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
200+
(**self).fmt(f)
201+
}
202+
}
203+
204+
#[derive(Clone)]
205+
pub struct Literal(proc_macro::Literal);
206+
207+
impl Literal {
208+
pub fn byte_char(byte: u8) -> Literal {
209+
match byte {
210+
0 => Literal(to_literal("b'\\0'")),
211+
b'\"' => Literal(to_literal("b'\"'")),
212+
n => {
213+
let mut escaped = "b'".to_string();
214+
escaped.extend(ascii::escape_default(n).map(|c| c as char));
215+
escaped.push('\'');
216+
Literal(to_literal(&escaped))
217+
}
218+
}
219+
}
220+
221+
pub fn byte_string(bytes: &[u8]) -> Literal {
222+
let mut escaped = "b\"".to_string();
223+
for b in bytes {
224+
match *b {
225+
b'\0' => escaped.push_str(r"\0"),
226+
b'\t' => escaped.push_str(r"\t"),
227+
b'\n' => escaped.push_str(r"\n"),
228+
b'\r' => escaped.push_str(r"\r"),
229+
b'"' => escaped.push_str("\\\""),
230+
b'\\' => escaped.push_str("\\\\"),
231+
b'\x20' ... b'\x7E' => escaped.push(*b as char),
232+
_ => escaped.push_str(&format!("\\x{:02X}", b)),
233+
}
234+
}
235+
escaped.push('"');
236+
Literal(to_literal(&escaped))
237+
}
238+
239+
pub fn doccomment(s: &str) -> Literal {
240+
Literal(to_literal(s))
241+
}
242+
243+
pub fn float(s: &str) -> Literal {
244+
Literal(to_literal(s))
245+
}
246+
247+
pub fn integer(s: &str) -> Literal {
248+
Literal(to_literal(s))
249+
}
250+
251+
pub fn raw_string(s: &str, pounds: usize) -> Literal {
252+
let mut ret = format!("r");
253+
ret.extend((0..pounds).map(|_| "#"));
254+
ret.push('"');
255+
ret.push_str(s);
256+
ret.push('"');
257+
ret.extend((0..pounds).map(|_| "#"));
258+
Literal(to_literal(&ret))
259+
}
260+
261+
pub fn raw_byte_string(s: &str, pounds: usize) -> Literal {
262+
let mut ret = format!("br");
263+
ret.extend((0..pounds).map(|_| "#"));
264+
ret.push('"');
265+
ret.push_str(s);
266+
ret.push('"');
267+
ret.extend((0..pounds).map(|_| "#"));
268+
Literal(to_literal(&ret))
269+
}
270+
}
271+
272+
impl fmt::Display for Literal {
273+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
274+
self.0.fmt(f)
275+
}
276+
}
277+
278+
impl fmt::Debug for Literal {
279+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
280+
fmt::Display::fmt(self, f)
281+
}
282+
}
283+
284+
fn to_literal(s: &str) -> proc_macro::Literal {
285+
let stream = s.parse::<proc_macro::TokenStream>().unwrap();
286+
match stream.into_iter().next().unwrap().kind {
287+
proc_macro::TokenKind::Literal(l) => l,
288+
_ => unreachable!(),
289+
}
290+
}
291+
292+
macro_rules! ints {
293+
($($t:ty,)*) => {$(
294+
impl From<$t> for Literal {
295+
fn from(t: $t) -> Literal {
296+
Literal(to_literal(&format!(concat!("{}", stringify!($t)), t)))
297+
}
298+
}
299+
)*}
300+
}
301+
302+
ints! {
303+
u8, u16, u32, u64, usize,
304+
i8, i16, i32, i64, isize,
305+
}
306+
307+
macro_rules! floats {
308+
($($t:ident,)*) => {$(
309+
impl From<$t> for Literal {
310+
fn from(t: $t) -> Literal {
311+
// TODO: remove this `as f32` when fixed upstream
312+
Literal(proc_macro::Literal::$t(t as f32))
313+
}
314+
}
315+
)*}
316+
}
317+
318+
floats! {
319+
f32, f64,
320+
}
321+
322+
impl<'a> From<&'a str> for Literal {
323+
fn from(t: &'a str) -> Literal {
324+
Literal(proc_macro::Literal::string(t))
325+
}
326+
}
327+
328+
impl From<char> for Literal {
329+
fn from(t: char) -> Literal {
330+
Literal(proc_macro::Literal::character(t))
331+
}
332+
}

0 commit comments

Comments
 (0)