aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_macros/src/tt_cursor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_macros/src/tt_cursor.rs')
-rw-r--r--crates/ra_macros/src/tt_cursor.rs92
1 files changed, 92 insertions, 0 deletions
diff --git a/crates/ra_macros/src/tt_cursor.rs b/crates/ra_macros/src/tt_cursor.rs
new file mode 100644
index 000000000..380c60b40
--- /dev/null
+++ b/crates/ra_macros/src/tt_cursor.rs
@@ -0,0 +1,92 @@
1use crate::tt;
2
3pub(crate) struct TtCursor<'a> {
4 subtree: &'a tt::Subtree,
5 pos: usize,
6}
7
8impl<'a> TtCursor<'a> {
9 pub(crate) fn new(subtree: &'a tt::Subtree) -> TtCursor<'a> {
10 TtCursor { subtree, pos: 0 }
11 }
12
13 pub(crate) fn is_eof(&self) -> bool {
14 self.pos == self.subtree.token_trees.len()
15 }
16
17 pub(crate) fn current(&self) -> Option<&'a tt::TokenTree> {
18 self.subtree.token_trees.get(self.pos)
19 }
20
21 pub(crate) fn at_punct(&self) -> Option<&'a tt::Punct> {
22 match self.current() {
23 Some(tt::TokenTree::Leaf(tt::Leaf::Punct(it))) => Some(it),
24 _ => None,
25 }
26 }
27
28 pub(crate) fn at_char(&self, char: char) -> bool {
29 match self.at_punct() {
30 Some(tt::Punct { char: c }) if *c == char => true,
31 _ => false,
32 }
33 }
34
35 pub(crate) fn at_ident(&mut self) -> Option<&'a tt::Ident> {
36 match self.current() {
37 Some(tt::TokenTree::Leaf(tt::Leaf::Ident(i))) => Some(i),
38 _ => None,
39 }
40 }
41
42 pub(crate) fn bump(&mut self) {
43 self.pos += 1;
44 }
45 pub(crate) fn rev_bump(&mut self) {
46 self.pos -= 1;
47 }
48
49 pub(crate) fn eat(&mut self) -> Option<&'a tt::TokenTree> {
50 match self.current() {
51 Some(it) => {
52 self.bump();
53 Some(it)
54 }
55 None => None,
56 }
57 }
58
59 pub(crate) fn eat_subtree(&mut self) -> Option<&'a tt::Subtree> {
60 match self.current()? {
61 tt::TokenTree::Subtree(sub) => {
62 self.bump();
63 Some(sub)
64 }
65 _ => return None,
66 }
67 }
68
69 pub(crate) fn eat_punct(&mut self) -> Option<&'a tt::Punct> {
70 if let Some(it) = self.at_punct() {
71 self.bump();
72 return Some(it);
73 }
74 None
75 }
76
77 pub(crate) fn eat_ident(&mut self) -> Option<&'a tt::Ident> {
78 if let Some(i) = self.at_ident() {
79 self.bump();
80 return Some(i);
81 }
82 None
83 }
84
85 pub(crate) fn expect_char(&mut self, char: char) -> Option<()> {
86 if self.at_char(char) {
87 self.bump();
88 return Some(());
89 }
90 None
91 }
92}