jetcrab\lexer\utils/
position.rs1use crate::vm::types::{ColumnNumber, LineNumber};
2
3pub trait PositionManager {
4 fn skip_whitespace(&mut self);
5 fn advance(&mut self);
6 fn peek_char(&self, offset: usize) -> Option<char>;
7 fn update_position(&mut self, start_line: LineNumber, start_col: ColumnNumber);
8}
9
10pub trait PositionCore {
11 fn source(&self) -> &[char];
12 fn pos(&self) -> usize;
13 fn line(&self) -> LineNumber;
14 fn column(&self) -> ColumnNumber;
15 fn set_pos(&mut self, pos: usize);
16 fn set_line(&mut self, line: LineNumber);
17 fn set_column(&mut self, column: ColumnNumber);
18}
19
20impl<T> PositionManager for T
21where
22 T: PositionCore,
23{
24 fn skip_whitespace(&mut self) {
25 while self.pos() < self.source().len() {
26 let c = self.source()[self.pos()];
27 if c.is_whitespace() {
28 if c == '\n' {
29 let mut new_line = self.line();
30 new_line += 1;
31 self.set_line(new_line);
32 self.set_column(ColumnNumber::new(1));
33 } else {
34 let mut new_column = self.column();
35 new_column += 1;
36 self.set_column(new_column);
37 }
38 self.advance();
39 } else {
40 break;
41 }
42 }
43 }
44
45 fn advance(&mut self) {
46 if self.pos() < self.source().len() {
47 self.set_pos(self.pos() + 1);
48 let mut new_column = self.column();
49 new_column += 1;
50 self.set_column(new_column);
51 }
52 }
53
54 fn peek_char(&self, offset: usize) -> Option<char> {
55 if self.pos() + offset < self.source().len() {
56 Some(self.source()[self.pos() + offset])
57 } else {
58 None
59 }
60 }
61
62 fn update_position(&mut self, _start_line: LineNumber, _start_col: ColumnNumber) {}
63}