aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/tt_cursor.rs
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2019-04-24 16:01:32 +0100
committerEdwin Cheng <[email protected]>2019-04-25 19:03:55 +0100
commit299d97b6d98cec673ff056c188ac45a17febc7d4 (patch)
treecaec1cdbcd6350d26ebe984b3eca177079aa02b3 /crates/ra_mbe/src/tt_cursor.rs
parentdfab545d5df974d4a50325695a25f763b7613baf (diff)
Add handling `token` seperator in mbe
Diffstat (limited to 'crates/ra_mbe/src/tt_cursor.rs')
-rw-r--r--crates/ra_mbe/src/tt_cursor.rs91
1 files changed, 91 insertions, 0 deletions
diff --git a/crates/ra_mbe/src/tt_cursor.rs b/crates/ra_mbe/src/tt_cursor.rs
index 87bcf8b0d..343416421 100644
--- a/crates/ra_mbe/src/tt_cursor.rs
+++ b/crates/ra_mbe/src/tt_cursor.rs
@@ -1,5 +1,7 @@
1use crate::ParseError; 1use crate::ParseError;
2use crate::subtree_parser::Parser; 2use crate::subtree_parser::Parser;
3use crate::subtree_source::TokenPeek;
4use smallvec::{SmallVec, smallvec};
3 5
4#[derive(Clone)] 6#[derive(Clone)]
5pub(crate) struct TtCursor<'a> { 7pub(crate) struct TtCursor<'a> {
@@ -162,6 +164,95 @@ impl<'a> TtCursor<'a> {
162 } 164 }
163 } 165 }
164 166
167 fn eat_punct3(&mut self, p: &tt::Punct) -> Option<SmallVec<[tt::Punct; 3]>> {
168 let sec = self.eat_punct()?.clone();
169 let third = self.eat_punct()?.clone();
170 Some(smallvec![p.clone(), sec, third])
171 }
172
173 fn eat_punct2(&mut self, p: &tt::Punct) -> Option<SmallVec<[tt::Punct; 3]>> {
174 let sec = self.eat_punct()?.clone();
175 Some(smallvec![p.clone(), sec])
176 }
177
178 fn eat_multi_char_punct<'b, I>(
179 &mut self,
180 p: &tt::Punct,
181 iter: &mut TokenPeek<'b, I>,
182 ) -> Option<SmallVec<[tt::Punct; 3]>>
183 where
184 I: Iterator<Item = &'b tt::TokenTree>,
185 {
186 if let Some((m, _)) = iter.current_punct3(p) {
187 if let r @ Some(_) = match m {
188 ('<', '<', '=') | ('>', '>', '=') | ('.', '.', '.') | ('.', '.', '=') => {
189 self.eat_punct3(p)
190 }
191 _ => None,
192 } {
193 return r;
194 }
195 }
196
197 if let Some((m, _)) = iter.current_punct2(p) {
198 if let r @ Some(_) = match m {
199 ('<', '=')
200 | ('>', '=')
201 | ('+', '=')
202 | ('-', '=')
203 | ('|', '=')
204 | ('&', '=')
205 | ('^', '=')
206 | ('/', '=')
207 | ('*', '=')
208 | ('%', '=')
209 | ('&', '&')
210 | ('|', '|')
211 | ('<', '<')
212 | ('>', '>')
213 | ('-', '>')
214 | ('!', '=')
215 | ('=', '>')
216 | ('=', '=')
217 | ('.', '.')
218 | (':', ':') => self.eat_punct2(p),
219
220 _ => None,
221 } {
222 return r;
223 }
224 }
225
226 None
227 }
228
229 pub(crate) fn eat_seperator(&mut self) -> Option<crate::Separator> {
230 match self.eat()? {
231 tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
232 Some(crate::Separator::Literal(lit.clone()))
233 }
234 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
235 Some(crate::Separator::Ident(ident.clone()))
236 }
237 tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => {
238 match punct.char {
239 '*' | '+' | '?' => return None,
240 _ => {}
241 };
242
243 // FIXME: The parser is only handle some compositeable punct,
244 // But at this phase, some punct still is jointed.
245 // So we by pass that check here.
246 let mut peekable = TokenPeek::new(self.subtree.token_trees[self.pos..].iter());
247 let puncts = self.eat_multi_char_punct(punct, &mut peekable);
248 let puncts = puncts.unwrap_or_else(|| smallvec![punct.clone()]);
249
250 Some(crate::Separator::Puncts(puncts))
251 }
252 _ => None,
253 }
254 }
255
165 #[must_use] 256 #[must_use]
166 pub(crate) fn save(&self) -> TtCursorMemento { 257 pub(crate) fn save(&self) -> TtCursorMemento {
167 TtCursorMemento { pos: self.pos } 258 TtCursorMemento { pos: self.pos }