Skip to content

Commit b1480b9

Browse files
committed
char window owns its source
1 parent 54869e9 commit b1480b9

1 file changed

Lines changed: 35 additions & 28 deletions

File tree

compiler/parser/src/lexer.rs

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -94,39 +94,52 @@ impl Default for Indentations {
9494
}
9595
}
9696

97-
struct CharWindow<const N: usize>([Option<char>; N]);
97+
struct CharWindow<T: Iterator<Item = char>, const N: usize> {
98+
source: T,
99+
window: [Option<char>; N],
100+
}
101+
102+
impl<T, const N: usize> CharWindow<T, N>
103+
where
104+
T: Iterator<Item = char>,
105+
{
106+
fn new(source: T) -> Self {
107+
Self {
108+
source,
109+
window: [None; N],
110+
}
111+
}
98112

99-
impl<const N: usize> CharWindow<N> {
100-
fn slide(&mut self, next_char: Option<char>) {
101-
self.0.rotate_left(1);
102-
*self.0.last_mut().expect("never empty") = next_char;
113+
fn slide(&mut self) {
114+
self.window.rotate_left(1);
115+
*self.window.last_mut().expect("never empty") = self.source.next();
103116
}
104117

105-
fn swap_first(&mut self, ch: char) {
106-
*self.0.first_mut().expect("never empty") = Some(ch);
118+
fn fill(&mut self) {
119+
while self.window[0] == None {
120+
self.slide();
121+
}
107122
}
108-
}
109123

110-
impl<const N: usize> Default for CharWindow<N> {
111-
fn default() -> Self {
112-
Self([None; N])
124+
fn change_first(&mut self, ch: char) {
125+
*self.window.first_mut().expect("never empty") = Some(ch);
113126
}
114127
}
115128

116-
impl<const N: usize, Idx> Index<Idx> for CharWindow<N>
129+
impl<T, const N: usize, Idx> Index<Idx> for CharWindow<T, N>
117130
where
131+
T: Iterator<Item = char>,
118132
Idx: SliceIndex<[Option<char>], Output = Option<char>>,
119133
{
120134
type Output = Option<char>;
121135

122136
fn index(&self, index: Idx) -> &Self::Output {
123-
self.0.index(index)
137+
self.window.index(index)
124138
}
125139
}
126140

127141
pub struct Lexer<T: Iterator<Item = char>> {
128-
chars: T,
129-
window: CharWindow<3>,
142+
window: CharWindow<T, 3>,
130143

131144
at_begin_of_line: bool,
132145
nesting: usize, // Amount of parenthesis
@@ -159,8 +172,7 @@ pub fn make_tokenizer_located(
159172
// The newline handler is an iterator which collapses different newline
160173
// types into \n always.
161174
pub struct NewlineHandler<T: Iterator<Item = char>> {
162-
source: T,
163-
window: CharWindow<2>,
175+
window: CharWindow<T, 2>,
164176
}
165177

166178
impl<T> NewlineHandler<T>
@@ -169,8 +181,7 @@ where
169181
{
170182
pub fn new(source: T) -> Self {
171183
let mut nlh = NewlineHandler {
172-
source,
173-
window: CharWindow::default(),
184+
window: CharWindow::new(source),
174185
};
175186
nlh.shift();
176187
nlh.shift();
@@ -179,7 +190,7 @@ where
179190

180191
fn shift(&mut self) -> Option<char> {
181192
let result = self.window[0];
182-
self.window.slide(self.source.next());
193+
self.window.slide();
183194
result
184195
}
185196
}
@@ -200,7 +211,7 @@ where
200211
}
201212
(Some('\r'), _) => {
202213
// MAC EOL into \n
203-
self.window.swap_first('\n');
214+
self.window.change_first('\n');
204215
}
205216
_ => break,
206217
}
@@ -219,17 +230,14 @@ where
219230
{
220231
pub fn new(input: T, start: Location) -> Self {
221232
let mut lxr = Lexer {
222-
chars: input,
223233
at_begin_of_line: true,
224234
nesting: 0,
225235
indentations: Indentations::default(),
226236
pending: Vec::new(),
227237
location: start,
228-
window: CharWindow::default(),
238+
window: CharWindow::new(input),
229239
};
230-
lxr.next_char();
231-
lxr.next_char();
232-
lxr.next_char();
240+
lxr.window.fill();
233241
// Start at top row (=1) left column (=1)
234242
lxr.location.reset();
235243
lxr
@@ -1293,8 +1301,7 @@ where
12931301
/// Helper function to go to the next character coming up.
12941302
fn next_char(&mut self) -> Option<char> {
12951303
let c = self.window[0];
1296-
let nxt = self.chars.next();
1297-
self.window.slide(nxt);
1304+
self.window.slide();
12981305
if c == Some('\n') {
12991306
self.location.newline();
13001307
} else {

0 commit comments

Comments
 (0)