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}