blob: 269da93e0372e983eacc5b1934f66b21bf09ef16 [file] [log] [blame]
Alex Crichton954046c2017-05-30 21:49:42 -07001//! Discrete tokens that can be parsed out by synom.
2//!
3//! This module contains a number of useful tokens like `+=` and `/` along with
4//! keywords like `crate` and such. These structures are used to track the spans
5//! of these tokens and all implment the `ToTokens` and `Synom` traits when the
6//! corresponding feature is activated.
7
Alex Crichton7b9e02f2017-05-30 15:54:33 -07008use span::Span;
9
10macro_rules! tokens {
11 (
12 ops: {
13 $(($($op:tt)*),)*
14 }
15 delim: {
16 $(($($delim:tt)*),)*
17 }
18 syms: {
19 $(($($sym:tt)*),)*
20 }
21 ) => (
22 $(op! { $($op)* })*
23 $(delim! { $($delim)* })*
24 $(sym! { $($sym)* })*
25 )
26}
27
28macro_rules! op {
29 (pub struct $name:ident($($contents:tt)*) => $s:expr) => {
30 #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
Nika Layzelld73a3652017-10-24 08:57:05 -040031 #[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash))]
Alex Crichton7b9e02f2017-05-30 15:54:33 -070032 #[derive(Default)]
33 pub struct $name(pub $($contents)*);
34
Nika Layzelld73a3652017-10-24 08:57:05 -040035 #[cfg(feature = "extra-traits")]
36 impl ::std::fmt::Debug for $name {
37 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
38 let mut t = f.debug_tuple(stringify!($name));
39 for span in &self.0 {
40 t.field(span);
41 }
42 t.finish()
43 }
44 }
45
Alex Crichton7b9e02f2017-05-30 15:54:33 -070046 #[cfg(feature = "printing")]
47 impl ::quote::ToTokens for $name {
48 fn to_tokens(&self, tokens: &mut ::quote::Tokens) {
49 printing::op($s, &self.0, tokens);
50 }
51 }
52
53 #[cfg(feature = "parsing")]
54 impl ::Synom for $name {
Michael Layzell760fd662017-05-31 22:46:05 -040055 fn parse(tokens: $crate::Cursor) -> $crate::PResult<$name> {
Alex Crichton7b9e02f2017-05-30 15:54:33 -070056 parsing::op($s, tokens, $name)
57 }
58 }
59 }
60}
61
62macro_rules! sym {
63 (pub struct $name:ident => $s:expr) => {
64 #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
65 #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
66 #[derive(Default)]
67 pub struct $name(pub Span);
68
69 #[cfg(feature = "printing")]
70 impl ::quote::ToTokens for $name {
71 fn to_tokens(&self, tokens: &mut ::quote::Tokens) {
72 printing::sym($s, &self.0, tokens);
73 }
74 }
75
76 #[cfg(feature = "parsing")]
77 impl ::Synom for $name {
Michael Layzell760fd662017-05-31 22:46:05 -040078 fn parse(tokens: $crate::Cursor) -> $crate::PResult<$name> {
Alex Crichton7b9e02f2017-05-30 15:54:33 -070079 parsing::sym($s, tokens, $name)
80 }
81 }
82 }
83}
84
85macro_rules! delim {
86 (pub struct $name:ident => $s:expr) => {
87 #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
88 #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
89 #[derive(Default)]
90 pub struct $name(pub Span);
91
92 impl $name {
93 #[cfg(feature = "printing")]
94 pub fn surround<F>(&self,
95 tokens: &mut ::quote::Tokens,
96 f: F)
97 where F: FnOnce(&mut ::quote::Tokens)
98 {
99 printing::delim($s, &self.0, tokens, f);
100 }
101
102 #[cfg(feature = "parsing")]
Michael Layzell760fd662017-05-31 22:46:05 -0400103 pub fn parse<F, R>(tokens: $crate::Cursor, f: F) -> $crate::PResult<(R, $name)>
104 where F: FnOnce($crate::Cursor) -> $crate::PResult<R>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700105 {
106 parsing::delim($s, tokens, $name, f)
107 }
108 }
109 }
110}
111
112tokens! {
113 ops: {
114 (pub struct Add([Span; 1]) => "+"),
115 (pub struct AddEq([Span; 2]) => "+="),
116 (pub struct And([Span; 1]) => "&"),
117 (pub struct AndAnd([Span; 2]) => "&&"),
118 (pub struct AndEq([Span; 2]) => "&="),
119 (pub struct At([Span; 1]) => "@"),
120 (pub struct Bang([Span; 1]) => "!"),
121 (pub struct Caret([Span; 1]) => "^"),
122 (pub struct CaretEq([Span; 2]) => "^="),
123 (pub struct Colon([Span; 1]) => ":"),
124 (pub struct Colon2([Span; 2]) => "::"),
125 (pub struct Comma([Span; 1]) => ","),
126 (pub struct Div([Span; 1]) => "/"),
127 (pub struct DivEq([Span; 2]) => "/="),
128 (pub struct Dot([Span; 1]) => "."),
129 (pub struct Dot2([Span; 2]) => ".."),
130 (pub struct Dot3([Span; 3]) => "..."),
David Tolnaybe55d7b2017-12-17 23:41:20 -0800131 (pub struct DotDotEq([Span; 3]) => "..="),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700132 (pub struct Eq([Span; 1]) => "="),
133 (pub struct EqEq([Span; 2]) => "=="),
134 (pub struct Ge([Span; 2]) => ">="),
135 (pub struct Gt([Span; 1]) => ">"),
136 (pub struct Le([Span; 2]) => "<="),
137 (pub struct Lt([Span; 1]) => "<"),
138 (pub struct MulEq([Span; 2]) => "*="),
139 (pub struct Ne([Span; 2]) => "!="),
140 (pub struct Or([Span; 1]) => "|"),
141 (pub struct OrEq([Span; 2]) => "|="),
142 (pub struct OrOr([Span; 2]) => "||"),
143 (pub struct Pound([Span; 1]) => "#"),
144 (pub struct Question([Span; 1]) => "?"),
145 (pub struct RArrow([Span; 2]) => "->"),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400146 (pub struct LArrow([Span; 2]) => "<-"),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700147 (pub struct Rem([Span; 1]) => "%"),
148 (pub struct RemEq([Span; 2]) => "%="),
149 (pub struct Rocket([Span; 2]) => "=>"),
150 (pub struct Semi([Span; 1]) => ";"),
151 (pub struct Shl([Span; 2]) => "<<"),
152 (pub struct ShlEq([Span; 3]) => "<<="),
153 (pub struct Shr([Span; 2]) => ">>"),
154 (pub struct ShrEq([Span; 3]) => ">>="),
155 (pub struct Star([Span; 1]) => "*"),
156 (pub struct Sub([Span; 1]) => "-"),
157 (pub struct SubEq([Span; 2]) => "-="),
158 (pub struct Underscore([Span; 1]) => "_"),
159 }
160 delim: {
161 (pub struct Brace => "{"),
162 (pub struct Bracket => "["),
163 (pub struct Paren => "("),
Michael Layzell93c36282017-06-04 20:43:14 -0400164 (pub struct Group => " "),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700165 }
166 syms: {
167 (pub struct As => "as"),
Nika Layzell0dc6e632017-11-18 12:55:25 -0500168 (pub struct Auto => "auto"),
David Tolnayf8db7ba2017-11-11 22:52:16 -0800169 (pub struct Box => "box"),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700170 (pub struct Break => "break"),
Alex Crichton954046c2017-05-30 21:49:42 -0700171 (pub struct CapSelf => "Self"),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700172 (pub struct Catch => "catch"),
173 (pub struct Const => "const"),
174 (pub struct Continue => "continue"),
175 (pub struct Crate => "crate"),
David Tolnayf8db7ba2017-11-11 22:52:16 -0800176 (pub struct Default => "default"),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700177 (pub struct Do => "do"),
178 (pub struct Else => "else"),
179 (pub struct Enum => "enum"),
180 (pub struct Extern => "extern"),
David Tolnayf8db7ba2017-11-11 22:52:16 -0800181 (pub struct Fn => "fn"),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700182 (pub struct For => "for"),
183 (pub struct If => "if"),
184 (pub struct Impl => "impl"),
185 (pub struct In => "in"),
186 (pub struct Let => "let"),
187 (pub struct Loop => "loop"),
188 (pub struct Match => "match"),
189 (pub struct Mod => "mod"),
190 (pub struct Move => "move"),
191 (pub struct Mut => "mut"),
192 (pub struct Pub => "pub"),
193 (pub struct Ref => "ref"),
194 (pub struct Return => "return"),
195 (pub struct Self_ => "self"),
196 (pub struct Static => "static"),
197 (pub struct Struct => "struct"),
Alex Crichton954046c2017-05-30 21:49:42 -0700198 (pub struct Super => "super"),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700199 (pub struct Trait => "trait"),
200 (pub struct Type => "type"),
201 (pub struct Union => "union"),
202 (pub struct Unsafe => "unsafe"),
203 (pub struct Use => "use"),
204 (pub struct Where => "where"),
205 (pub struct While => "while"),
Alex Crichtonfe110462017-06-01 12:49:27 -0700206 (pub struct Yield => "yield"),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700207 }
208}
209
David Tolnayf8db7ba2017-11-11 22:52:16 -0800210// Unfortunate duplication due to a rustdoc bug.
211// https://github.com/rust-lang/rust/issues/45939
212#[macro_export]
213macro_rules! Token {
214 (+) => { $crate::tokens::Add };
215 (+=) => { $crate::tokens::AddEq };
216 (&) => { $crate::tokens::And };
217 (&&) => { $crate::tokens::AndAnd };
218 (&=) => { $crate::tokens::AndEq };
219 (@) => { $crate::tokens::At };
220 (!) => { $crate::tokens::Bang };
221 (^) => { $crate::tokens::Caret };
222 (^=) => { $crate::tokens::CaretEq };
223 (:) => { $crate::tokens::Colon };
224 (::) => { $crate::tokens::Colon2 };
225 (,) => { $crate::tokens::Comma };
226 (/) => { $crate::tokens::Div };
227 (/=) => { $crate::tokens::DivEq };
228 (.) => { $crate::tokens::Dot };
229 (..) => { $crate::tokens::Dot2 };
230 (...) => { $crate::tokens::Dot3 };
David Tolnaybe55d7b2017-12-17 23:41:20 -0800231 (..=) => { $crate::tokens::DotDotEq };
David Tolnayf8db7ba2017-11-11 22:52:16 -0800232 (=) => { $crate::tokens::Eq };
233 (==) => { $crate::tokens::EqEq };
234 (>=) => { $crate::tokens::Ge };
235 (>) => { $crate::tokens::Gt };
236 (<=) => { $crate::tokens::Le };
237 (<) => { $crate::tokens::Lt };
238 (*=) => { $crate::tokens::MulEq };
239 (!=) => { $crate::tokens::Ne };
240 (|) => { $crate::tokens::Or };
241 (|=) => { $crate::tokens::OrEq };
242 (||) => { $crate::tokens::OrOr };
243 (#) => { $crate::tokens::Pound };
244 (?) => { $crate::tokens::Question };
245 (->) => { $crate::tokens::RArrow };
246 (<-) => { $crate::tokens::LArrow };
247 (%) => { $crate::tokens::Rem };
248 (%=) => { $crate::tokens::RemEq };
249 (=>) => { $crate::tokens::Rocket };
250 (;) => { $crate::tokens::Semi };
251 (<<) => { $crate::tokens::Shl };
252 (<<=) => { $crate::tokens::ShlEq };
253 (>>) => { $crate::tokens::Shr };
254 (>>=) => { $crate::tokens::ShrEq };
255 (*) => { $crate::tokens::Star };
256 (-) => { $crate::tokens::Sub };
257 (-=) => { $crate::tokens::SubEq };
258 (_) => { $crate::tokens::Underscore };
259 (as) => { $crate::tokens::As };
Nika Layzell0dc6e632017-11-18 12:55:25 -0500260 (auto) => { $crate::tokens::Auto };
David Tolnayf8db7ba2017-11-11 22:52:16 -0800261 (box) => { $crate::tokens::Box };
262 (break) => { $crate::tokens::Break };
263 (Self) => { $crate::tokens::CapSelf };
264 (catch) => { $crate::tokens::Catch };
265 (const) => { $crate::tokens::Const };
266 (continue) => { $crate::tokens::Continue };
267 (crate) => { $crate::tokens::Crate };
268 (default) => { $crate::tokens::Default };
269 (do) => { $crate::tokens::Do };
270 (else) => { $crate::tokens::Else };
271 (enum) => { $crate::tokens::Enum };
272 (extern) => { $crate::tokens::Extern };
273 (fn) => { $crate::tokens::Fn };
274 (for) => { $crate::tokens::For };
275 (if) => { $crate::tokens::If };
276 (impl) => { $crate::tokens::Impl };
277 (in) => { $crate::tokens::In };
278 (let) => { $crate::tokens::Let };
279 (loop) => { $crate::tokens::Loop };
280 (match) => { $crate::tokens::Match };
281 (mod) => { $crate::tokens::Mod };
282 (move) => { $crate::tokens::Move };
283 (mut) => { $crate::tokens::Mut };
284 (pub) => { $crate::tokens::Pub };
285 (ref) => { $crate::tokens::Ref };
286 (return) => { $crate::tokens::Return };
287 (self) => { $crate::tokens::Self_ };
288 (static) => { $crate::tokens::Static };
289 (struct) => { $crate::tokens::Struct };
290 (super) => { $crate::tokens::Super };
291 (trait) => { $crate::tokens::Trait };
292 (type) => { $crate::tokens::Type };
293 (union) => { $crate::tokens::Union };
294 (unsafe) => { $crate::tokens::Unsafe };
295 (use) => { $crate::tokens::Use };
296 (where) => { $crate::tokens::Where };
297 (while) => { $crate::tokens::While };
298 (yield) => { $crate::tokens::Yield };
299}
300
301#[macro_export]
302macro_rules! punct {
303 ($i:expr, +) => { call!($i, <$crate::tokens::Add as $crate::Synom>::parse) };
304 ($i:expr, +=) => { call!($i, <$crate::tokens::AddEq as $crate::Synom>::parse) };
305 ($i:expr, &) => { call!($i, <$crate::tokens::And as $crate::Synom>::parse) };
306 ($i:expr, &&) => { call!($i, <$crate::tokens::AndAnd as $crate::Synom>::parse) };
307 ($i:expr, &=) => { call!($i, <$crate::tokens::AndEq as $crate::Synom>::parse) };
308 ($i:expr, @) => { call!($i, <$crate::tokens::At as $crate::Synom>::parse) };
309 ($i:expr, !) => { call!($i, <$crate::tokens::Bang as $crate::Synom>::parse) };
310 ($i:expr, ^) => { call!($i, <$crate::tokens::Caret as $crate::Synom>::parse) };
311 ($i:expr, ^=) => { call!($i, <$crate::tokens::CaretEq as $crate::Synom>::parse) };
312 ($i:expr, :) => { call!($i, <$crate::tokens::Colon as $crate::Synom>::parse) };
313 ($i:expr, ::) => { call!($i, <$crate::tokens::Colon2 as $crate::Synom>::parse) };
314 ($i:expr, ,) => { call!($i, <$crate::tokens::Comma as $crate::Synom>::parse) };
315 ($i:expr, /) => { call!($i, <$crate::tokens::Div as $crate::Synom>::parse) };
316 ($i:expr, /=) => { call!($i, <$crate::tokens::DivEq as $crate::Synom>::parse) };
317 ($i:expr, .) => { call!($i, <$crate::tokens::Dot as $crate::Synom>::parse) };
318 ($i:expr, ..) => { call!($i, <$crate::tokens::Dot2 as $crate::Synom>::parse) };
319 ($i:expr, ...) => { call!($i, <$crate::tokens::Dot3 as $crate::Synom>::parse) };
David Tolnaybe55d7b2017-12-17 23:41:20 -0800320 ($i:expr, ..=) => { call!($i, <$crate::tokens::DotDotEq as $crate::Synom>::parse) };
David Tolnayf8db7ba2017-11-11 22:52:16 -0800321 ($i:expr, =) => { call!($i, <$crate::tokens::Eq as $crate::Synom>::parse) };
322 ($i:expr, ==) => { call!($i, <$crate::tokens::EqEq as $crate::Synom>::parse) };
323 ($i:expr, >=) => { call!($i, <$crate::tokens::Ge as $crate::Synom>::parse) };
324 ($i:expr, >) => { call!($i, <$crate::tokens::Gt as $crate::Synom>::parse) };
325 ($i:expr, <=) => { call!($i, <$crate::tokens::Le as $crate::Synom>::parse) };
326 ($i:expr, <) => { call!($i, <$crate::tokens::Lt as $crate::Synom>::parse) };
327 ($i:expr, *=) => { call!($i, <$crate::tokens::MulEq as $crate::Synom>::parse) };
328 ($i:expr, !=) => { call!($i, <$crate::tokens::Ne as $crate::Synom>::parse) };
329 ($i:expr, |) => { call!($i, <$crate::tokens::Or as $crate::Synom>::parse) };
330 ($i:expr, |=) => { call!($i, <$crate::tokens::OrEq as $crate::Synom>::parse) };
331 ($i:expr, ||) => { call!($i, <$crate::tokens::OrOr as $crate::Synom>::parse) };
332 ($i:expr, #) => { call!($i, <$crate::tokens::Pound as $crate::Synom>::parse) };
333 ($i:expr, ?) => { call!($i, <$crate::tokens::Question as $crate::Synom>::parse) };
334 ($i:expr, ->) => { call!($i, <$crate::tokens::RArrow as $crate::Synom>::parse) };
335 ($i:expr, <-) => { call!($i, <$crate::tokens::LArrow as $crate::Synom>::parse) };
336 ($i:expr, %) => { call!($i, <$crate::tokens::Rem as $crate::Synom>::parse) };
337 ($i:expr, %=) => { call!($i, <$crate::tokens::RemEq as $crate::Synom>::parse) };
338 ($i:expr, =>) => { call!($i, <$crate::tokens::Rocket as $crate::Synom>::parse) };
339 ($i:expr, ;) => { call!($i, <$crate::tokens::Semi as $crate::Synom>::parse) };
340 ($i:expr, <<) => { call!($i, <$crate::tokens::Shl as $crate::Synom>::parse) };
341 ($i:expr, <<=) => { call!($i, <$crate::tokens::ShlEq as $crate::Synom>::parse) };
342 ($i:expr, >>) => { call!($i, <$crate::tokens::Shr as $crate::Synom>::parse) };
343 ($i:expr, >>=) => { call!($i, <$crate::tokens::ShrEq as $crate::Synom>::parse) };
344 ($i:expr, *) => { call!($i, <$crate::tokens::Star as $crate::Synom>::parse) };
345 ($i:expr, -) => { call!($i, <$crate::tokens::Sub as $crate::Synom>::parse) };
346 ($i:expr, -=) => { call!($i, <$crate::tokens::SubEq as $crate::Synom>::parse) };
347 ($i:expr, _) => { call!($i, <$crate::tokens::Underscore as $crate::Synom>::parse) };
348}
349
350#[macro_export]
351macro_rules! keyword {
352 ($i:expr, as) => { call!($i, <$crate::tokens::As as $crate::Synom>::parse) };
Nika Layzell0dc6e632017-11-18 12:55:25 -0500353 ($i:expr, auto) => { call!($i, <$crate::tokens::Auto as $crate::Synom>::parse) };
David Tolnayf8db7ba2017-11-11 22:52:16 -0800354 ($i:expr, box) => { call!($i, <$crate::tokens::Box as $crate::Synom>::parse) };
355 ($i:expr, break) => { call!($i, <$crate::tokens::Break as $crate::Synom>::parse) };
356 ($i:expr, Self) => { call!($i, <$crate::tokens::CapSelf as $crate::Synom>::parse) };
357 ($i:expr, catch) => { call!($i, <$crate::tokens::Catch as $crate::Synom>::parse) };
358 ($i:expr, const) => { call!($i, <$crate::tokens::Const as $crate::Synom>::parse) };
359 ($i:expr, continue) => { call!($i, <$crate::tokens::Continue as $crate::Synom>::parse) };
360 ($i:expr, crate) => { call!($i, <$crate::tokens::Crate as $crate::Synom>::parse) };
361 ($i:expr, default) => { call!($i, <$crate::tokens::Default as $crate::Synom>::parse) };
362 ($i:expr, do) => { call!($i, <$crate::tokens::Do as $crate::Synom>::parse) };
363 ($i:expr, else) => { call!($i, <$crate::tokens::Else as $crate::Synom>::parse) };
364 ($i:expr, enum) => { call!($i, <$crate::tokens::Enum as $crate::Synom>::parse) };
365 ($i:expr, extern) => { call!($i, <$crate::tokens::Extern as $crate::Synom>::parse) };
366 ($i:expr, fn) => { call!($i, <$crate::tokens::Fn as $crate::Synom>::parse) };
367 ($i:expr, for) => { call!($i, <$crate::tokens::For as $crate::Synom>::parse) };
368 ($i:expr, if) => { call!($i, <$crate::tokens::If as $crate::Synom>::parse) };
369 ($i:expr, impl) => { call!($i, <$crate::tokens::Impl as $crate::Synom>::parse) };
370 ($i:expr, in) => { call!($i, <$crate::tokens::In as $crate::Synom>::parse) };
371 ($i:expr, let) => { call!($i, <$crate::tokens::Let as $crate::Synom>::parse) };
372 ($i:expr, loop) => { call!($i, <$crate::tokens::Loop as $crate::Synom>::parse) };
373 ($i:expr, match) => { call!($i, <$crate::tokens::Match as $crate::Synom>::parse) };
374 ($i:expr, mod) => { call!($i, <$crate::tokens::Mod as $crate::Synom>::parse) };
375 ($i:expr, move) => { call!($i, <$crate::tokens::Move as $crate::Synom>::parse) };
376 ($i:expr, mut) => { call!($i, <$crate::tokens::Mut as $crate::Synom>::parse) };
377 ($i:expr, pub) => { call!($i, <$crate::tokens::Pub as $crate::Synom>::parse) };
378 ($i:expr, ref) => { call!($i, <$crate::tokens::Ref as $crate::Synom>::parse) };
379 ($i:expr, return) => { call!($i, <$crate::tokens::Return as $crate::Synom>::parse) };
380 ($i:expr, self) => { call!($i, <$crate::tokens::Self_ as $crate::Synom>::parse) };
381 ($i:expr, static) => { call!($i, <$crate::tokens::Static as $crate::Synom>::parse) };
382 ($i:expr, struct) => { call!($i, <$crate::tokens::Struct as $crate::Synom>::parse) };
383 ($i:expr, super) => { call!($i, <$crate::tokens::Super as $crate::Synom>::parse) };
384 ($i:expr, trait) => { call!($i, <$crate::tokens::Trait as $crate::Synom>::parse) };
385 ($i:expr, type) => { call!($i, <$crate::tokens::Type as $crate::Synom>::parse) };
386 ($i:expr, union) => { call!($i, <$crate::tokens::Union as $crate::Synom>::parse) };
387 ($i:expr, unsafe) => { call!($i, <$crate::tokens::Unsafe as $crate::Synom>::parse) };
388 ($i:expr, use) => { call!($i, <$crate::tokens::Use as $crate::Synom>::parse) };
389 ($i:expr, where) => { call!($i, <$crate::tokens::Where as $crate::Synom>::parse) };
390 ($i:expr, while) => { call!($i, <$crate::tokens::While as $crate::Synom>::parse) };
391 ($i:expr, yield) => { call!($i, <$crate::tokens::Yield as $crate::Synom>::parse) };
392}
393
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700394#[cfg(feature = "parsing")]
395mod parsing {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700396 use proc_macro2::{Delimiter, Spacing};
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700397
Michael Layzell760fd662017-05-31 22:46:05 -0400398 use {PResult, Cursor, parse_error};
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700399 use span::Span;
400
401 pub trait FromSpans: Sized {
402 fn from_spans(spans: &[Span]) -> Self;
403 }
404
405 impl FromSpans for [Span; 1] {
406 fn from_spans(spans: &[Span]) -> Self {
407 [spans[0]]
408 }
409 }
410
411 impl FromSpans for [Span; 2] {
412 fn from_spans(spans: &[Span]) -> Self {
413 [spans[0], spans[1]]
414 }
415 }
416
417 impl FromSpans for [Span; 3] {
418 fn from_spans(spans: &[Span]) -> Self {
419 [spans[0], spans[1], spans[2]]
420 }
421 }
422
423 pub fn op<'a, T, R>(s: &str,
Michael Layzell0a1a6632017-06-02 18:07:43 -0400424 mut tokens: Cursor<'a>,
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700425 new: fn(T) -> R)
Michael Layzell760fd662017-05-31 22:46:05 -0400426 -> PResult<'a, R>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700427 where T: FromSpans,
428 {
429 let mut spans = [Span::default(); 3];
Alex Crichton954046c2017-05-30 21:49:42 -0700430 assert!(s.len() <= spans.len());
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700431 let chars = s.chars();
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700432
Alex Crichton954046c2017-05-30 21:49:42 -0700433 for (i, (ch, slot)) in chars.zip(&mut spans).enumerate() {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400434 match tokens.op() {
435 Some((rest, span, c, kind)) if c == ch => {
436 if i != s.len() - 1 {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700437 match kind {
438 Spacing::Joint => {}
439 _ => return parse_error(),
Michael Layzell0a1a6632017-06-02 18:07:43 -0400440 }
441 }
442 *slot = Span(span);
443 tokens = rest;
Alex Crichton954046c2017-05-30 21:49:42 -0700444 }
Michael Layzell0a1a6632017-06-02 18:07:43 -0400445 _ => return parse_error()
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700446 }
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700447 }
Michael Layzell0a1a6632017-06-02 18:07:43 -0400448 Ok((tokens, new(T::from_spans(&spans))))
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700449 }
450
451 pub fn sym<'a, T>(sym: &str,
Michael Layzell760fd662017-05-31 22:46:05 -0400452 tokens: Cursor<'a>,
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700453 new: fn(Span) -> T)
Michael Layzell760fd662017-05-31 22:46:05 -0400454 -> PResult<'a, T>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700455 {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400456 if let Some((rest, span, s)) = tokens.word() {
457 if s.as_str() == sym {
458 return Ok((rest, new(Span(span))));
459 }
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700460 }
Michael Layzell0a1a6632017-06-02 18:07:43 -0400461 parse_error()
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700462 }
463
464 pub fn delim<'a, F, R, T>(delim: &str,
Michael Layzell760fd662017-05-31 22:46:05 -0400465 tokens: Cursor<'a>,
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700466 new: fn(Span) -> T,
467 f: F)
Michael Layzell760fd662017-05-31 22:46:05 -0400468 -> PResult<'a, (R, T)>
469 where F: FnOnce(Cursor) -> PResult<R>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700470 {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400471 // NOTE: We should support none-delimited sequences here.
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700472 let delim = match delim {
473 "(" => Delimiter::Parenthesis,
474 "{" => Delimiter::Brace,
475 "[" => Delimiter::Bracket,
Michael Layzell93c36282017-06-04 20:43:14 -0400476 " " => Delimiter::None,
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700477 _ => panic!("unknown delimiter: {}", delim),
478 };
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700479
Michael Layzell0a1a6632017-06-02 18:07:43 -0400480 if let Some(seqinfo) = tokens.seq(delim) {
481 match f(seqinfo.inside) {
482 Ok((remaining, ret)) => {
483 if remaining.eof() {
484 return Ok((seqinfo.outside, (ret, new(Span(seqinfo.span)))));
485 }
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700486 }
Michael Layzell0a1a6632017-06-02 18:07:43 -0400487 Err(err) => return Err(err),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700488 }
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700489 }
Michael Layzell0a1a6632017-06-02 18:07:43 -0400490 parse_error()
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700491 }
492}
493
494#[cfg(feature = "printing")]
495mod printing {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700496 use proc_macro2::{TokenTree, TokenNode, Spacing, Term};
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700497 use quote::Tokens;
498
499 use span::Span;
500
501 pub fn op(s: &str, spans: &[Span], tokens: &mut Tokens) {
502 assert_eq!(s.len(), spans.len());
503
504 let mut chars = s.chars();
505 let mut spans = spans.iter();
506 let ch = chars.next_back().unwrap();
507 let span = spans.next_back().unwrap();
508 for (ch, span) in chars.zip(spans) {
509 tokens.append(TokenTree {
510 span: span.0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700511 kind: TokenNode::Op(ch, Spacing::Joint),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700512 });
513 }
514
515 tokens.append(TokenTree {
516 span: span.0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700517 kind: TokenNode::Op(ch, Spacing::Alone),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700518 });
519 }
520
521 pub fn sym(s: &str, span: &Span, tokens: &mut Tokens) {
522 tokens.append(TokenTree {
523 span: span.0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700524 kind: TokenNode::Term(Term::intern(s)),
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700525 });
526 }
527
528 pub fn delim<F>(s: &str, span: &Span, tokens: &mut Tokens, f: F)
529 where F: FnOnce(&mut Tokens)
530 {
531 tokens.append_delimited(s, span.0, f)
532 }
533}