diff options
Diffstat (limited to 'crates/ra_macros')
-rw-r--r-- | crates/ra_macros/Cargo.toml | 9 | ||||
-rw-r--r-- | crates/ra_macros/src/lib.rs | 17 | ||||
-rw-r--r-- | crates/ra_macros/src/mbe.rs | 72 | ||||
-rw-r--r-- | crates/ra_macros/src/mbe_expander.rs | 169 | ||||
-rw-r--r-- | crates/ra_macros/src/mbe_parser.rs | 94 | ||||
-rw-r--r-- | crates/ra_macros/src/tt.rs | 119 | ||||
-rw-r--r-- | crates/ra_macros/src/tt_cursor.rs | 93 |
7 files changed, 0 insertions, 573 deletions
diff --git a/crates/ra_macros/Cargo.toml b/crates/ra_macros/Cargo.toml deleted file mode 100644 index 7d3cb055c..000000000 --- a/crates/ra_macros/Cargo.toml +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | [package] | ||
2 | edition = "2018" | ||
3 | name = "ra_macros" | ||
4 | version = "0.1.0" | ||
5 | authors = ["Aleksey Kladov <[email protected]>"] | ||
6 | |||
7 | [dependencies] | ||
8 | rustc-hash = "1.0.0" | ||
9 | smol_str = "0.1.9" | ||
diff --git a/crates/ra_macros/src/lib.rs b/crates/ra_macros/src/lib.rs deleted file mode 100644 index e35a056cc..000000000 --- a/crates/ra_macros/src/lib.rs +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | macro_rules! impl_froms { | ||
2 | ($e:ident: $($v:ident), *) => { | ||
3 | $( | ||
4 | impl From<$v> for $e { | ||
5 | fn from(it: $v) -> $e { | ||
6 | $e::$v(it) | ||
7 | } | ||
8 | } | ||
9 | )* | ||
10 | } | ||
11 | } | ||
12 | |||
13 | pub mod tt; | ||
14 | pub mod mbe; | ||
15 | mod tt_cursor; | ||
16 | mod mbe_parser; | ||
17 | mod mbe_expander; | ||
diff --git a/crates/ra_macros/src/mbe.rs b/crates/ra_macros/src/mbe.rs deleted file mode 100644 index d4106a41c..000000000 --- a/crates/ra_macros/src/mbe.rs +++ /dev/null | |||
@@ -1,72 +0,0 @@ | |||
1 | use smol_str::SmolStr; | ||
2 | |||
3 | pub(crate) use crate::tt::{Delimiter, Punct}; | ||
4 | |||
5 | pub use crate::{ | ||
6 | mbe_parser::parse, | ||
7 | mbe_expander::exapnd, | ||
8 | }; | ||
9 | |||
10 | #[derive(Debug)] | ||
11 | pub struct MacroRules { | ||
12 | pub(crate) rules: Vec<Rule>, | ||
13 | } | ||
14 | |||
15 | #[derive(Debug)] | ||
16 | pub(crate) struct Rule { | ||
17 | pub(crate) lhs: Subtree, | ||
18 | pub(crate) rhs: Subtree, | ||
19 | } | ||
20 | |||
21 | #[derive(Debug)] | ||
22 | pub(crate) enum TokenTree { | ||
23 | Leaf(Leaf), | ||
24 | Subtree(Subtree), | ||
25 | Repeat(Repeat), | ||
26 | } | ||
27 | impl_froms!(TokenTree: Leaf, Subtree, Repeat); | ||
28 | |||
29 | #[derive(Debug)] | ||
30 | pub(crate) enum Leaf { | ||
31 | Literal(Literal), | ||
32 | Punct(Punct), | ||
33 | Ident(Ident), | ||
34 | Var(Var), | ||
35 | } | ||
36 | impl_froms!(Leaf: Literal, Punct, Ident, Var); | ||
37 | |||
38 | #[derive(Debug)] | ||
39 | pub(crate) struct Subtree { | ||
40 | pub(crate) delimiter: Delimiter, | ||
41 | pub(crate) token_trees: Vec<TokenTree>, | ||
42 | } | ||
43 | |||
44 | #[derive(Debug)] | ||
45 | pub(crate) struct Repeat { | ||
46 | pub(crate) subtree: Subtree, | ||
47 | pub(crate) kind: RepeatKind, | ||
48 | pub(crate) separator: Option<char>, | ||
49 | } | ||
50 | |||
51 | #[derive(Debug)] | ||
52 | pub(crate) enum RepeatKind { | ||
53 | ZeroOrMore, | ||
54 | OneOrMore, | ||
55 | ZeroOrOne, | ||
56 | } | ||
57 | |||
58 | #[derive(Debug)] | ||
59 | pub(crate) struct Literal { | ||
60 | pub(crate) text: SmolStr, | ||
61 | } | ||
62 | |||
63 | #[derive(Debug)] | ||
64 | pub(crate) struct Ident { | ||
65 | pub(crate) text: SmolStr, | ||
66 | } | ||
67 | |||
68 | #[derive(Debug)] | ||
69 | pub(crate) struct Var { | ||
70 | pub(crate) text: SmolStr, | ||
71 | pub(crate) kind: Option<SmolStr>, | ||
72 | } | ||
diff --git a/crates/ra_macros/src/mbe_expander.rs b/crates/ra_macros/src/mbe_expander.rs deleted file mode 100644 index 5d5363261..000000000 --- a/crates/ra_macros/src/mbe_expander.rs +++ /dev/null | |||
@@ -1,169 +0,0 @@ | |||
1 | use rustc_hash::FxHashMap; | ||
2 | use smol_str::SmolStr; | ||
3 | |||
4 | use crate::{mbe, tt, tt_cursor::TtCursor}; | ||
5 | |||
6 | pub fn exapnd(rules: &mbe::MacroRules, input: &tt::Subtree) -> Option<tt::Subtree> { | ||
7 | rules.rules.iter().find_map(|it| expand_rule(it, input)) | ||
8 | } | ||
9 | |||
10 | fn expand_rule(rule: &mbe::Rule, input: &tt::Subtree) -> Option<tt::Subtree> { | ||
11 | let mut input = TtCursor::new(input); | ||
12 | let bindings = match_lhs(&rule.lhs, &mut input)?; | ||
13 | expand_subtree(&rule.rhs, &bindings, &mut Vec::new()) | ||
14 | } | ||
15 | |||
16 | #[derive(Debug, Default)] | ||
17 | struct Bindings { | ||
18 | inner: FxHashMap<SmolStr, Binding>, | ||
19 | } | ||
20 | |||
21 | #[derive(Debug)] | ||
22 | enum Binding { | ||
23 | Simple(tt::TokenTree), | ||
24 | Nested(Vec<Binding>), | ||
25 | } | ||
26 | |||
27 | impl Bindings { | ||
28 | fn get(&self, name: &SmolStr, nesting: &[usize]) -> Option<&tt::TokenTree> { | ||
29 | let mut b = self.inner.get(name)?; | ||
30 | for &idx in nesting.iter() { | ||
31 | b = match b { | ||
32 | Binding::Simple(_) => break, | ||
33 | Binding::Nested(bs) => bs.get(idx)?, | ||
34 | }; | ||
35 | } | ||
36 | match b { | ||
37 | Binding::Simple(it) => Some(it), | ||
38 | Binding::Nested(_) => None, | ||
39 | } | ||
40 | } | ||
41 | fn push_nested(&mut self, nested: Bindings) -> Option<()> { | ||
42 | for (key, value) in nested.inner { | ||
43 | if !self.inner.contains_key(&key) { | ||
44 | self.inner.insert(key.clone(), Binding::Nested(Vec::new())); | ||
45 | } | ||
46 | match self.inner.get_mut(&key) { | ||
47 | Some(Binding::Nested(it)) => it.push(value), | ||
48 | _ => return None, | ||
49 | } | ||
50 | } | ||
51 | Some(()) | ||
52 | } | ||
53 | } | ||
54 | |||
55 | fn match_lhs(pattern: &mbe::Subtree, input: &mut TtCursor) -> Option<Bindings> { | ||
56 | let mut res = Bindings::default(); | ||
57 | for pat in pattern.token_trees.iter() { | ||
58 | match pat { | ||
59 | mbe::TokenTree::Leaf(leaf) => match leaf { | ||
60 | mbe::Leaf::Var(mbe::Var { text, kind }) => { | ||
61 | let kind = kind.clone()?; | ||
62 | match kind.as_str() { | ||
63 | "ident" => { | ||
64 | let ident = input.eat_ident()?.clone(); | ||
65 | res.inner.insert( | ||
66 | text.clone(), | ||
67 | Binding::Simple(tt::Leaf::from(ident).into()), | ||
68 | ); | ||
69 | } | ||
70 | _ => return None, | ||
71 | } | ||
72 | } | ||
73 | mbe::Leaf::Punct(punct) => { | ||
74 | if input.eat_punct()? != punct { | ||
75 | return None; | ||
76 | } | ||
77 | } | ||
78 | _ => return None, | ||
79 | }, | ||
80 | mbe::TokenTree::Repeat(mbe::Repeat { | ||
81 | subtree, | ||
82 | kind: _, | ||
83 | separator, | ||
84 | }) => { | ||
85 | while let Some(nested) = match_lhs(subtree, input) { | ||
86 | res.push_nested(nested)?; | ||
87 | if separator.is_some() && !input.is_eof() { | ||
88 | input.eat_punct()?; | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | _ => {} | ||
93 | } | ||
94 | } | ||
95 | Some(res) | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | |||
100 | macro_rules! impl_froms { | ||
101 | ($e:ident: $($v:ident),*) => { | ||
102 | $( | ||
103 | impl From<$v> for $e { | ||
104 | fn from(it: $v) -> $e { | ||
105 | $e::$v(it) | ||
106 | } | ||
107 | } | ||
108 | )* | ||
109 | } | ||
110 | } | ||
111 | |||
112 | impl_froms! (Foo: Bar, Baz) | ||
113 | |||
114 | */ | ||
115 | |||
116 | fn expand_subtree( | ||
117 | template: &mbe::Subtree, | ||
118 | bindings: &Bindings, | ||
119 | nesting: &mut Vec<usize>, | ||
120 | ) -> Option<tt::Subtree> { | ||
121 | let token_trees = template | ||
122 | .token_trees | ||
123 | .iter() | ||
124 | .map(|it| expand_tt(it, bindings, nesting)) | ||
125 | .collect::<Option<Vec<_>>>()?; | ||
126 | |||
127 | Some(tt::Subtree { | ||
128 | token_trees, | ||
129 | delimiter: template.delimiter, | ||
130 | }) | ||
131 | } | ||
132 | |||
133 | fn expand_tt( | ||
134 | template: &mbe::TokenTree, | ||
135 | bindings: &Bindings, | ||
136 | nesting: &mut Vec<usize>, | ||
137 | ) -> Option<tt::TokenTree> { | ||
138 | let res: tt::TokenTree = match template { | ||
139 | mbe::TokenTree::Subtree(subtree) => expand_subtree(subtree, bindings, nesting)?.into(), | ||
140 | mbe::TokenTree::Repeat(repeat) => { | ||
141 | let mut token_trees = Vec::new(); | ||
142 | nesting.push(0); | ||
143 | while let Some(t) = expand_subtree(&repeat.subtree, bindings, nesting) { | ||
144 | let idx = nesting.pop().unwrap(); | ||
145 | nesting.push(idx + 1); | ||
146 | token_trees.push(t.into()) | ||
147 | } | ||
148 | nesting.pop().unwrap(); | ||
149 | tt::Subtree { | ||
150 | token_trees, | ||
151 | delimiter: tt::Delimiter::None, | ||
152 | } | ||
153 | .into() | ||
154 | } | ||
155 | mbe::TokenTree::Leaf(leaf) => match leaf { | ||
156 | mbe::Leaf::Ident(ident) => tt::Leaf::from(tt::Ident { | ||
157 | text: ident.text.clone(), | ||
158 | }) | ||
159 | .into(), | ||
160 | mbe::Leaf::Punct(punct) => tt::Leaf::from(punct.clone()).into(), | ||
161 | mbe::Leaf::Var(v) => bindings.get(&v.text, nesting)?.clone(), | ||
162 | mbe::Leaf::Literal(l) => tt::Leaf::from(tt::Literal { | ||
163 | text: l.text.clone(), | ||
164 | }) | ||
165 | .into(), | ||
166 | }, | ||
167 | }; | ||
168 | Some(res) | ||
169 | } | ||
diff --git a/crates/ra_macros/src/mbe_parser.rs b/crates/ra_macros/src/mbe_parser.rs deleted file mode 100644 index 483594590..000000000 --- a/crates/ra_macros/src/mbe_parser.rs +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | use crate::{tt, mbe}; | ||
2 | use crate::tt_cursor::TtCursor; | ||
3 | |||
4 | /// This module parses a raw `tt::TokenStream` into macro-by-example token | ||
5 | /// stream. This is a *mostly* identify function, expect for handling of | ||
6 | /// `$var:tt_kind` and `$(repeat),*` constructs. | ||
7 | |||
8 | pub fn parse(tt: &tt::Subtree) -> Option<mbe::MacroRules> { | ||
9 | let mut parser = TtCursor::new(tt); | ||
10 | let mut rules = Vec::new(); | ||
11 | while !parser.is_eof() { | ||
12 | rules.push(parse_rule(&mut parser)?) | ||
13 | } | ||
14 | Some(mbe::MacroRules { rules }) | ||
15 | } | ||
16 | |||
17 | fn parse_rule(p: &mut TtCursor) -> Option<mbe::Rule> { | ||
18 | let lhs = parse_subtree(p.eat_subtree()?)?; | ||
19 | p.expect_char('=')?; | ||
20 | p.expect_char('>')?; | ||
21 | let rhs = parse_subtree(p.eat_subtree()?)?; | ||
22 | Some(mbe::Rule { lhs, rhs }) | ||
23 | } | ||
24 | |||
25 | fn parse_subtree(tt: &tt::Subtree) -> Option<mbe::Subtree> { | ||
26 | let mut token_trees = Vec::new(); | ||
27 | let mut p = TtCursor::new(tt); | ||
28 | while let Some(tt) = p.eat() { | ||
29 | let child: mbe::TokenTree = match tt { | ||
30 | tt::TokenTree::Leaf(leaf) => match leaf { | ||
31 | tt::Leaf::Punct(tt::Punct { char: '$', .. }) => { | ||
32 | if p.at_ident().is_some() { | ||
33 | mbe::Leaf::from(parse_var(&mut p)?).into() | ||
34 | } else { | ||
35 | parse_repeat(&mut p)?.into() | ||
36 | } | ||
37 | } | ||
38 | tt::Leaf::Punct(punct) => mbe::Leaf::from(*punct).into(), | ||
39 | tt::Leaf::Ident(tt::Ident { text }) => { | ||
40 | mbe::Leaf::from(mbe::Ident { text: text.clone() }).into() | ||
41 | } | ||
42 | tt::Leaf::Literal(tt::Literal { text }) => { | ||
43 | mbe::Leaf::from(mbe::Literal { text: text.clone() }).into() | ||
44 | } | ||
45 | }, | ||
46 | tt::TokenTree::Subtree(subtree) => parse_subtree(subtree)?.into(), | ||
47 | }; | ||
48 | token_trees.push(child); | ||
49 | } | ||
50 | Some(mbe::Subtree { | ||
51 | token_trees, | ||
52 | delimiter: tt.delimiter, | ||
53 | }) | ||
54 | } | ||
55 | |||
56 | fn parse_var(p: &mut TtCursor) -> Option<mbe::Var> { | ||
57 | let ident = p.eat_ident().unwrap(); | ||
58 | let text = ident.text.clone(); | ||
59 | let kind = if p.at_char(':') { | ||
60 | p.bump(); | ||
61 | if let Some(ident) = p.eat_ident() { | ||
62 | Some(ident.text.clone()) | ||
63 | } else { | ||
64 | p.rev_bump(); | ||
65 | None | ||
66 | } | ||
67 | } else { | ||
68 | None | ||
69 | }; | ||
70 | Some(mbe::Var { text, kind }) | ||
71 | } | ||
72 | |||
73 | fn parse_repeat(p: &mut TtCursor) -> Option<mbe::Repeat> { | ||
74 | let subtree = p.eat_subtree().unwrap(); | ||
75 | let subtree = parse_subtree(subtree)?; | ||
76 | let sep = p.eat_punct()?; | ||
77 | let (separator, rep) = match sep.char { | ||
78 | '*' | '+' | '?' => (None, sep.char), | ||
79 | char => (Some(char), p.eat_punct()?.char), | ||
80 | }; | ||
81 | |||
82 | let kind = match rep { | ||
83 | '*' => mbe::RepeatKind::ZeroOrMore, | ||
84 | '+' => mbe::RepeatKind::OneOrMore, | ||
85 | '?' => mbe::RepeatKind::ZeroOrOne, | ||
86 | _ => return None, | ||
87 | }; | ||
88 | p.bump(); | ||
89 | Some(mbe::Repeat { | ||
90 | subtree, | ||
91 | kind, | ||
92 | separator, | ||
93 | }) | ||
94 | } | ||
diff --git a/crates/ra_macros/src/tt.rs b/crates/ra_macros/src/tt.rs deleted file mode 100644 index 2855bae51..000000000 --- a/crates/ra_macros/src/tt.rs +++ /dev/null | |||
@@ -1,119 +0,0 @@ | |||
1 | use std::fmt; | ||
2 | |||
3 | use smol_str::SmolStr; | ||
4 | |||
5 | #[derive(Debug, Clone)] | ||
6 | pub enum TokenTree { | ||
7 | Leaf(Leaf), | ||
8 | Subtree(Subtree), | ||
9 | } | ||
10 | impl_froms!(TokenTree: Leaf, Subtree); | ||
11 | |||
12 | #[derive(Debug, Clone)] | ||
13 | pub enum Leaf { | ||
14 | Literal(Literal), | ||
15 | Punct(Punct), | ||
16 | Ident(Ident), | ||
17 | } | ||
18 | impl_froms!(Leaf: Literal, Punct, Ident); | ||
19 | |||
20 | #[derive(Debug, Clone)] | ||
21 | pub struct Subtree { | ||
22 | pub delimiter: Delimiter, | ||
23 | pub token_trees: Vec<TokenTree>, | ||
24 | } | ||
25 | |||
26 | #[derive(Clone, Copy, Debug)] | ||
27 | pub enum Delimiter { | ||
28 | Parenthesis, | ||
29 | Brace, | ||
30 | Bracket, | ||
31 | None, | ||
32 | } | ||
33 | |||
34 | #[derive(Debug, Clone)] | ||
35 | pub struct Literal { | ||
36 | pub text: SmolStr, | ||
37 | } | ||
38 | |||
39 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
40 | pub struct Punct { | ||
41 | pub char: char, | ||
42 | pub spacing: Spacing, | ||
43 | } | ||
44 | |||
45 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
46 | pub enum Spacing { | ||
47 | Alone, | ||
48 | Joint, | ||
49 | } | ||
50 | |||
51 | #[derive(Debug, Clone)] | ||
52 | pub struct Ident { | ||
53 | pub text: SmolStr, | ||
54 | } | ||
55 | |||
56 | impl fmt::Display for TokenTree { | ||
57 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
58 | match self { | ||
59 | TokenTree::Leaf(it) => fmt::Display::fmt(it, f), | ||
60 | TokenTree::Subtree(it) => fmt::Display::fmt(it, f), | ||
61 | } | ||
62 | } | ||
63 | } | ||
64 | |||
65 | impl fmt::Display for Subtree { | ||
66 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
67 | let (l, r) = match self.delimiter { | ||
68 | Delimiter::Parenthesis => ("(", ")"), | ||
69 | Delimiter::Brace => ("{", "}"), | ||
70 | Delimiter::Bracket => ("[", "]"), | ||
71 | Delimiter::None => ("", ""), | ||
72 | }; | ||
73 | f.write_str(l)?; | ||
74 | let mut needs_space = false; | ||
75 | for tt in self.token_trees.iter() { | ||
76 | if needs_space { | ||
77 | f.write_str(" ")?; | ||
78 | } | ||
79 | needs_space = true; | ||
80 | match tt { | ||
81 | TokenTree::Leaf(Leaf::Punct(p)) => { | ||
82 | needs_space = p.spacing == Spacing::Alone; | ||
83 | fmt::Display::fmt(p, f)? | ||
84 | } | ||
85 | tt => fmt::Display::fmt(tt, f)?, | ||
86 | } | ||
87 | } | ||
88 | f.write_str(r)?; | ||
89 | Ok(()) | ||
90 | } | ||
91 | } | ||
92 | |||
93 | impl fmt::Display for Leaf { | ||
94 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
95 | match self { | ||
96 | Leaf::Ident(it) => fmt::Display::fmt(it, f), | ||
97 | Leaf::Literal(it) => fmt::Display::fmt(it, f), | ||
98 | Leaf::Punct(it) => fmt::Display::fmt(it, f), | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | |||
103 | impl fmt::Display for Ident { | ||
104 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
105 | fmt::Display::fmt(&self.text, f) | ||
106 | } | ||
107 | } | ||
108 | |||
109 | impl fmt::Display for Literal { | ||
110 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
111 | fmt::Display::fmt(&self.text, f) | ||
112 | } | ||
113 | } | ||
114 | |||
115 | impl fmt::Display for Punct { | ||
116 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
117 | fmt::Display::fmt(&self.char, f) | ||
118 | } | ||
119 | } | ||
diff --git a/crates/ra_macros/src/tt_cursor.rs b/crates/ra_macros/src/tt_cursor.rs deleted file mode 100644 index 046770a0f..000000000 --- a/crates/ra_macros/src/tt_cursor.rs +++ /dev/null | |||
@@ -1,93 +0,0 @@ | |||
1 | use crate::tt; | ||
2 | |||
3 | #[derive(Clone)] | ||
4 | pub(crate) struct TtCursor<'a> { | ||
5 | subtree: &'a tt::Subtree, | ||
6 | pos: usize, | ||
7 | } | ||
8 | |||
9 | impl<'a> TtCursor<'a> { | ||
10 | pub(crate) fn new(subtree: &'a tt::Subtree) -> TtCursor<'a> { | ||
11 | TtCursor { subtree, pos: 0 } | ||
12 | } | ||
13 | |||
14 | pub(crate) fn is_eof(&self) -> bool { | ||
15 | self.pos == self.subtree.token_trees.len() | ||
16 | } | ||
17 | |||
18 | pub(crate) fn current(&self) -> Option<&'a tt::TokenTree> { | ||
19 | self.subtree.token_trees.get(self.pos) | ||
20 | } | ||
21 | |||
22 | pub(crate) fn at_punct(&self) -> Option<&'a tt::Punct> { | ||
23 | match self.current() { | ||
24 | Some(tt::TokenTree::Leaf(tt::Leaf::Punct(it))) => Some(it), | ||
25 | _ => None, | ||
26 | } | ||
27 | } | ||
28 | |||
29 | pub(crate) fn at_char(&self, char: char) -> bool { | ||
30 | match self.at_punct() { | ||
31 | Some(tt::Punct { char: c, .. }) if *c == char => true, | ||
32 | _ => false, | ||
33 | } | ||
34 | } | ||
35 | |||
36 | pub(crate) fn at_ident(&mut self) -> Option<&'a tt::Ident> { | ||
37 | match self.current() { | ||
38 | Some(tt::TokenTree::Leaf(tt::Leaf::Ident(i))) => Some(i), | ||
39 | _ => None, | ||
40 | } | ||
41 | } | ||
42 | |||
43 | pub(crate) fn bump(&mut self) { | ||
44 | self.pos += 1; | ||
45 | } | ||
46 | pub(crate) fn rev_bump(&mut self) { | ||
47 | self.pos -= 1; | ||
48 | } | ||
49 | |||
50 | pub(crate) fn eat(&mut self) -> Option<&'a tt::TokenTree> { | ||
51 | match self.current() { | ||
52 | Some(it) => { | ||
53 | self.bump(); | ||
54 | Some(it) | ||
55 | } | ||
56 | None => None, | ||
57 | } | ||
58 | } | ||
59 | |||
60 | pub(crate) fn eat_subtree(&mut self) -> Option<&'a tt::Subtree> { | ||
61 | match self.current()? { | ||
62 | tt::TokenTree::Subtree(sub) => { | ||
63 | self.bump(); | ||
64 | Some(sub) | ||
65 | } | ||
66 | _ => return None, | ||
67 | } | ||
68 | } | ||
69 | |||
70 | pub(crate) fn eat_punct(&mut self) -> Option<&'a tt::Punct> { | ||
71 | if let Some(it) = self.at_punct() { | ||
72 | self.bump(); | ||
73 | return Some(it); | ||
74 | } | ||
75 | None | ||
76 | } | ||
77 | |||
78 | pub(crate) fn eat_ident(&mut self) -> Option<&'a tt::Ident> { | ||
79 | if let Some(i) = self.at_ident() { | ||
80 | self.bump(); | ||
81 | return Some(i); | ||
82 | } | ||
83 | None | ||
84 | } | ||
85 | |||
86 | pub(crate) fn expect_char(&mut self, char: char) -> Option<()> { | ||
87 | if self.at_char(char) { | ||
88 | self.bump(); | ||
89 | return Some(()); | ||
90 | } | ||
91 | None | ||
92 | } | ||
93 | } | ||