ziyy_core/scanner/
mod.rs

1pub use source::Source;
2
3use crate::common::Span;
4
5mod source;
6
7pub fn is_alpha(c: char) -> bool {
8    matches!(c, 'a'..='z' | 'A'..='Z' | '_')
9}
10
11pub fn is_digit(c: char) -> bool {
12    c.is_ascii_digit()
13}
14
15pub fn is_alpha_numeric(c: char) -> bool {
16    is_alpha(c) || is_digit(c)
17}
18
19pub fn is_hexdigit(c: char) -> bool {
20    c.is_ascii_hexdigit()
21}
22
23pub trait GenericScanner<T: PartialEq, U> {
24    fn source(&self) -> &impl Source<T>;
25    fn tokens(&mut self) -> &mut Vec<U>;
26    fn set_start(&mut self, n: usize);
27    fn current(&self) -> usize;
28    fn set_current(&mut self, n: usize);
29    fn span(&mut self) -> &mut Span;
30    fn scan_token(&mut self);
31
32    fn scan_tokens<'a>(&'a mut self) -> Vec<U>
33    where
34        T: 'a,
35    {
36        while !self.is_at_end() {
37            self.set_start(self.current());
38            self.scan_token();
39        }
40
41        std::mem::take(self.tokens())
42    }
43
44    fn peek(&self) -> T {
45        if self.is_at_end() {
46            self.source().null()
47        } else {
48            self.source().at(self.current())
49        }
50    }
51
52    fn peek_next(&self) -> T {
53        if self.current() + 1 > self.source().len() {
54            self.source().null()
55        } else {
56            self.source().at(self.current() + 1)
57        }
58    }
59
60    fn is_at_end(&self) -> bool {
61        self.current() >= self.source().len()
62    }
63
64    fn advance(&mut self) -> T {
65        self.set_current(self.current() + 1);
66        *self.span() += (0, 1);
67        let ch = self.source().at(self.current() - 1);
68        if ch == self.source().nl() {
69            *self.span() += (1, 0);
70        }
71        ch
72    }
73}
74
75macro_rules! impl_generic_scanner {
76    ( $f:expr ) => {
77        impl GenericScanner<char, Token> for Scanner {
78            fn source(&self) -> &impl Source<char> {
79                &self.source
80            }
81
82            fn tokens(&mut self) -> &mut Vec<Token> {
83                &mut self.tokens
84            }
85
86            fn set_start(&mut self, n: usize) {
87                self.start = n;
88            }
89
90            fn current(&self) -> usize {
91                self.current
92            }
93
94            fn set_current(&mut self, n: usize) {
95                self.current = n;
96            }
97
98            fn span(&mut self) -> &mut Span {
99                &mut self.span
100            }
101
102            fn scan_token(&mut self) {
103                $f(self);
104            }
105        }
106    };
107}