1use std::collections::HashMap;
2use veryl_parser::resource_table::TokenId;
3use veryl_parser::veryl_token::{Token, VerylToken};
4
5#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash)]
6pub struct Location {
7 pub line: u32,
8 pub column: u32,
9 pub length: u32,
10 pub duplicated: Option<usize>,
11}
12
13impl From<&Token> for Location {
14 fn from(x: &Token) -> Self {
15 Self {
16 line: x.line,
17 column: x.column,
18 length: x.length,
19 duplicated: None,
20 }
21 }
22}
23
24impl From<Token> for Location {
25 fn from(x: Token) -> Self {
26 Self {
27 line: x.line,
28 column: x.column,
29 length: x.length,
30 duplicated: None,
31 }
32 }
33}
34
35#[derive(Default)]
36pub struct Align {
37 enable: bool,
38 index: usize,
39 max_width: u32,
40 width: u32,
41 line: u32,
42 rest: Vec<(Location, u32)>,
43 additions: HashMap<Location, u32>,
44 disable_auto_finish: bool,
45 pub last_location: Option<Location>,
46}
47
48impl Align {
49 fn finish_group(&mut self) {
50 for (loc, width) in &self.rest {
51 self.additions.insert(*loc, self.max_width - width);
52 }
53 self.rest.clear();
54 self.max_width = 0;
55 }
56
57 pub fn finish_item(&mut self) {
58 if self.enable {
59 self.enable = false;
60 if let Some(loc) = self.last_location {
61 if !self.disable_auto_finish && (self.line > loc.line || loc.line - self.line > 1) {
62 self.finish_group();
63 }
64 self.max_width = u32::max(self.max_width, self.width);
65 self.line = loc.line;
66 self.rest.push((loc, self.width));
67
68 self.width = 0;
69 self.index += 1;
70 }
71 }
72 }
73
74 pub fn start_item(&mut self) {
75 self.enable = true;
76 self.width = 0;
77 }
78
79 fn token(&mut self, x: &VerylToken) {
80 if self.enable {
81 self.width += x.token.length;
82 let loc: Location = x.token.into();
83 self.last_location = Some(loc);
84 }
85 }
86
87 pub fn dummy_location(&mut self, x: Location) {
88 if self.enable {
89 self.width += 0; self.last_location = Some(x);
91 }
92 }
93
94 pub fn dummy_token(&mut self, x: &VerylToken) {
95 if self.enable {
96 self.width += 0; let loc: Location = x.token.into();
98 self.last_location = Some(loc);
99 }
100 }
101
102 pub fn duplicated_token(&mut self, x: &VerylToken, i: usize) {
103 if self.enable {
104 self.width += x.token.length;
105 let mut loc: Location = x.token.into();
106 loc.duplicated = Some(i);
107 self.last_location = Some(loc);
108 }
109 }
110
111 pub fn add_width(&mut self, width: u32) {
112 if self.enable {
113 self.width += width;
114 }
115 }
116
117 fn space(&mut self, x: usize) {
118 if self.enable {
119 self.width += x as u32;
120 }
121 }
122}
123
124pub mod align_kind {
125 pub const IDENTIFIER: usize = 0;
126 pub const TYPE: usize = 1;
127 pub const EXPRESSION: usize = 2;
128 pub const WIDTH: usize = 3;
129 pub const ARRAY: usize = 4;
130 pub const ASSIGNMENT: usize = 5;
131 pub const PARAMETER: usize = 6;
132 pub const DIRECTION: usize = 7;
133 pub const CLOCK_DOMAIN: usize = 8;
134 pub const NUMBER: usize = 9;
135 pub const VAR_KEYWORD: usize = 10;
136}
137
138#[derive(Default)]
139pub struct Aligner {
140 pub additions: HashMap<Location, u32>,
141 pub aligns: [Align; 11],
142}
143
144impl Aligner {
145 pub fn new() -> Self {
146 Default::default()
147 }
148
149 pub fn token(&mut self, x: &VerylToken) {
150 for i in 0..self.aligns.len() {
151 self.aligns[i].token(x);
152 }
153 }
154
155 pub fn duplicated_token(&mut self, x: &VerylToken, idx: usize) {
156 for i in 0..self.aligns.len() {
157 self.aligns[i].duplicated_token(x, idx);
158 }
159 }
160
161 pub fn space(&mut self, x: usize) {
162 for i in 0..self.aligns.len() {
163 self.aligns[i].space(x);
164 }
165 }
166
167 pub fn finish_group(&mut self) {
168 for i in 0..self.aligns.len() {
169 self.aligns[i].finish_group();
170 }
171 }
172
173 pub fn finish_item(&mut self) {
174 for i in 0..self.aligns.len() {
175 self.aligns[i].finish_item();
176 }
177 }
178
179 pub fn gather_additions(&mut self) {
180 for align in &self.aligns {
181 for (x, y) in &align.additions {
182 self.additions
183 .entry(*x)
184 .and_modify(|val| *val += *y)
185 .or_insert(*y);
186 }
187 }
188 }
189
190 pub fn enable_auto_finish(&mut self) {
191 for align in &mut self.aligns {
192 align.disable_auto_finish = false;
193 }
194 }
195
196 pub fn disable_auto_finish(&mut self) {
197 for align in &mut self.aligns {
198 align.disable_auto_finish = true;
199 }
200 }
201
202 pub fn any_enabled(&self) -> bool {
203 self.aligns.iter().any(|x| x.enable)
204 }
205}
206
207#[derive(Clone, Debug, Default)]
208pub struct Measure {
209 widths: Vec<u32>,
210 table: HashMap<TokenId, u32>,
211}
212
213impl Measure {
214 pub fn start(&mut self) {
215 self.widths.push(0);
216 }
217
218 pub fn finish(&mut self, id: TokenId) {
219 let width = self.widths.pop().unwrap();
220 self.table.insert(id, width);
221 }
222
223 pub fn add(&mut self, value: u32) {
224 for w in &mut self.widths {
225 *w += value;
226 }
227 }
228
229 pub fn get(&mut self, id: TokenId) -> Option<u32> {
230 self.table.get(&id).copied()
231 }
232}