1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use crate::common::position::CaretPos;
use crate::parse::lex::token::Lex;
use crate::parse::lex::token::Token;
#[derive(Clone, Debug)]
pub struct State {
newlines: Vec<Lex>,
cur_indent: i32,
line_indent: i32,
token_this_line: bool,
pub pos: CaretPos,
}
impl State {
pub fn new() -> State {
let pos = CaretPos::new(1, 1);
State { newlines: vec![], cur_indent: 1, line_indent: 1, token_this_line: false, pos }
}
pub fn flush_indents(&mut self) -> Vec<Lex> {
let amount = ((self.cur_indent) / 4) as usize;
self.cur_indent = 1;
vec![Lex::new(self.pos, Token::Dedent); amount]
}
pub fn token(&mut self, token: Token) -> Vec<Lex> {
if token == Token::NL {
self.newline();
return vec![];
}
self.token_this_line = true;
let mut res = self.newlines.pop().map_or(vec![], |nl| vec![nl]);
if self.line_indent >= self.cur_indent {
let amount = ((self.line_indent - self.cur_indent) / 4) as usize;
res.append(&mut vec![Lex::new(self.pos, Token::Indent); amount]);
} else {
let amount = ((self.cur_indent - self.line_indent) / 4) as usize;
res.append(&mut vec![Lex::new(self.pos, Token::Dedent); amount]);
res.push(Lex::new(self.pos, Token::NL));
}
res.append(&mut self.newlines);
res.push(Lex::new(self.pos, token.clone()));
self.cur_indent = self.line_indent;
self.pos = self.pos.offset_pos(token.clone().width());
if let Token::Str(_str, _) = &token {
self.pos = self.pos.offset_line((_str.lines().count() as i32 - 1) as usize);
} else if let Token::DocStr(_str) = &token {
self.pos = self.pos.offset_line((_str.lines().count() as i32 - 1) as usize);
}
res
}
fn newline(&mut self) {
self.newlines.push(Lex::new(self.pos, Token::NL));
self.token_this_line = false;
self.line_indent = 1;
self.pos = self.pos.newline();
}
pub fn space(&mut self) {
self.pos = self.pos.offset_pos(1);
self.line_indent += if self.token_this_line { 0 } else { 1 };
}
}