tenda_parser/
token_iter.rs1use peekmore::{PeekMore, PeekMoreIterator};
2use std::{cell::RefCell, ops::Neg, rc::Rc, slice::Iter};
3use tenda_scanner::{Token, TokenKind};
4
5#[derive(Debug, Clone)]
6pub struct TokenIterator<'a> {
7 tokens: PeekMoreIterator<Iter<'a, Token>>,
8 ignoring_newline_counter: Rc<RefCell<isize>>,
9 last_token: &'a Token,
10}
11
12impl TokenIterator<'_> {
13 pub fn peek(&mut self) -> Option<&&Token> {
14 self.skip_ignored_newlines();
15 self.tokens.peek()
16 }
17
18 pub fn set_ignoring_newline(&mut self) -> NewlineGuard {
19 NewlineGuard::new(self.ignoring_newline_counter.clone(), None)
20 }
21
22 pub fn halt_ignoring_newline(&mut self) -> NewlineGuard {
23 let size = self.ignoring_newline_counter.borrow().neg();
24
25 NewlineGuard::new(self.ignoring_newline_counter.clone(), Some(size))
26 }
27
28 pub fn consume_one_of(&mut self, token_types: &[TokenKind]) -> Option<Token> {
29 self.tokens.reset_cursor();
30
31 while let Some(token) = self.tokens.peek() {
32 if token.kind == TokenKind::Newline && *self.ignoring_newline_counter.borrow() > 0 {
33 self.tokens.advance_cursor();
34 } else {
35 break;
36 }
37 }
38
39 let skipped = self.tokens.cursor();
40
41 if let Some(token) = self.tokens.peek() {
42 if token_types.contains(&token.kind) {
43 for _ in 0..skipped {
44 self.tokens.next();
45 }
46
47 return self.tokens.next().cloned();
48 }
49 }
50
51 self.tokens.reset_cursor();
52
53 None
54 }
55
56 pub fn consume_sequence(&mut self, token_types: &[TokenKind]) -> Option<Vec<Token>> {
57 self.tokens.reset_cursor();
58
59 for token_type in token_types {
60 while let Some(token) = self.tokens.peek() {
61 if token.kind == TokenKind::Newline && *self.ignoring_newline_counter.borrow() > 0 {
62 self.tokens.advance_cursor();
63 } else {
64 break;
65 }
66 }
67
68 match self.tokens.peek() {
69 Some(token) if token.kind == *token_type => {
70 self.tokens.advance_cursor();
71 }
72 _ => {
73 self.tokens.reset_cursor();
74
75 return None;
76 }
77 }
78 }
79
80 let count = self.tokens.cursor();
81 let mut tokens = Vec::with_capacity(count);
82
83 for _ in 0..count {
84 tokens.push(self.tokens.next().cloned().unwrap());
85 }
86
87 Some(tokens)
88 }
89
90 pub fn check_sequence(&mut self, token_types: &[TokenKind]) -> bool {
91 self.tokens.reset_cursor();
92
93 for token_type in token_types {
94 while let Some(token) = self.tokens.peek() {
95 if token.kind == TokenKind::Newline && *self.ignoring_newline_counter.borrow() > 0 {
96 self.tokens.advance_cursor();
97 } else {
98 break;
99 }
100 }
101
102 match self.tokens.peek() {
103 Some(token) if token.kind == *token_type => {
104 self.tokens.advance_cursor();
105 }
106 _ => {
107 self.tokens.reset_cursor();
108
109 return false;
110 }
111 }
112 }
113
114 self.tokens.reset_cursor();
115
116 true
117 }
118
119 pub fn is_next_token(&mut self, token_type: TokenKind) -> bool {
120 self.tokens.reset_cursor();
121
122 while let Some(token) = self.tokens.peek() {
123 if token.kind == TokenKind::Newline && *self.ignoring_newline_counter.borrow() > 0 {
124 self.tokens.advance_cursor();
125 } else {
126 break;
127 }
128 }
129
130 if let Some(token) = self.tokens.peek() {
131 if token.kind == token_type {
132 return true;
133 }
134 }
135
136 self.tokens.reset_cursor();
137
138 false
139 }
140
141 pub fn is_next_eof(&mut self) -> bool {
142 self.tokens.reset_cursor();
143
144 while let Some(token) = self.tokens.peek() {
145 if token.kind == TokenKind::Newline {
146 self.tokens.advance_cursor();
147 } else {
148 break;
149 }
150 }
151
152 let is_eof = matches!(
153 self.tokens.peek(),
154 None | Some(Token {
155 kind: TokenKind::Eof,
156 ..
157 })
158 );
159
160 self.tokens.reset_cursor();
161
162 is_eof
163 }
164
165 pub fn is_next_valid(&mut self) -> bool {
166 self.tokens.reset_cursor();
167
168 while let Some(token) = self.tokens.peek() {
169 if token.kind == TokenKind::Newline && *self.ignoring_newline_counter.borrow() > 0 {
170 self.tokens.advance_cursor();
171 } else {
172 break;
173 }
174 }
175
176 let is_next_valid = !matches!(
177 self.tokens.peek(),
178 None | Some(Token {
179 kind: TokenKind::Eof,
180 ..
181 })
182 );
183
184 self.tokens.reset_cursor();
185
186 is_next_valid
187 }
188
189 pub fn advance_while(&mut self, expected_types: &[TokenKind]) {
190 while let Some(token) = self.tokens.peek() {
191 if expected_types.contains(&token.kind) {
192 self.tokens.next();
193 } else {
194 break;
195 }
196 }
197 }
198
199 pub fn last_token(&self) -> &Token {
200 self.last_token
201 }
202
203 fn skip_ignored_newlines(&mut self) {
204 while let Some(token) = self.tokens.peek() {
205 if token.kind == TokenKind::Newline && *self.ignoring_newline_counter.borrow() > 0 {
206 self.tokens.next();
207 } else {
208 break;
209 }
210 }
211 }
212}
213
214impl<'a> Iterator for TokenIterator<'a> {
215 type Item = &'a Token;
216
217 fn next(&mut self) -> Option<Self::Item> {
218 self.skip_ignored_newlines();
219 self.tokens.next()
220 }
221}
222
223impl<'a> From<&'a [Token]> for TokenIterator<'a> {
224 fn from(value: &'a [Token]) -> Self {
225 TokenIterator {
226 tokens: value.iter().peekmore(),
227 ignoring_newline_counter: Rc::new(RefCell::new(0)),
228 last_token: value.last().expect("token list should not be empty"),
229 }
230 }
231}
232
233pub struct NewlineGuard {
234 counter: Rc<RefCell<isize>>,
235 size: isize,
236}
237
238impl NewlineGuard {
239 pub fn new(counter: Rc<RefCell<isize>>, custom_size: Option<isize>) -> Self {
240 let size = custom_size.unwrap_or(1);
241
242 *counter.borrow_mut() += size;
243
244 NewlineGuard { counter, size }
245 }
246}
247
248impl Drop for NewlineGuard {
249 fn drop(&mut self) {
250 *self.counter.borrow_mut() -= self.size;
251 }
252}
253
254#[macro_export]
255macro_rules! token_slice {
256 ($($kind:expr),*) => {
257 {
258 use tenda_scanner::TokenKind::*;
259 &[$($kind),*]
260 }
261 };
262}