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 fn space(&mut self, x: usize) {
112 if self.enable {
113 self.width += x as u32;
114 }
115 }
116}
117
118pub mod align_kind {
119 pub const IDENTIFIER: usize = 0;
120 pub const TYPE: usize = 1;
121 pub const EXPRESSION: usize = 2;
122 pub const WIDTH: usize = 3;
123 pub const ARRAY: usize = 4;
124 pub const ASSIGNMENT: usize = 5;
125 pub const PARAMETER: usize = 6;
126 pub const DIRECTION: usize = 7;
127 pub const CLOCK_DOMAIN: usize = 8;
128 pub const NUMBER: usize = 9;
129}
130
131#[derive(Default)]
132pub struct Aligner {
133 pub additions: HashMap<Location, u32>,
134 pub aligns: [Align; 10],
135}
136
137impl Aligner {
138 pub fn new() -> Self {
139 Default::default()
140 }
141
142 pub fn token(&mut self, x: &VerylToken) {
143 for i in 0..self.aligns.len() {
144 self.aligns[i].token(x);
145 }
146 }
147
148 pub fn duplicated_token(&mut self, x: &VerylToken, idx: usize) {
149 for i in 0..self.aligns.len() {
150 self.aligns[i].duplicated_token(x, idx);
151 }
152 }
153
154 pub fn space(&mut self, x: usize) {
155 for i in 0..self.aligns.len() {
156 self.aligns[i].space(x);
157 }
158 }
159
160 pub fn finish_group(&mut self) {
161 for i in 0..self.aligns.len() {
162 self.aligns[i].finish_group();
163 }
164 }
165
166 pub fn finish_item(&mut self) {
167 for i in 0..self.aligns.len() {
168 self.aligns[i].finish_item();
169 }
170 }
171
172 pub fn gather_additions(&mut self) {
173 for align in &self.aligns {
174 for (x, y) in &align.additions {
175 self.additions
176 .entry(*x)
177 .and_modify(|val| *val += *y)
178 .or_insert(*y);
179 }
180 }
181 }
182
183 pub fn enable_auto_finish(&mut self) {
184 for align in &mut self.aligns {
185 align.disable_auto_finish = false;
186 }
187 }
188
189 pub fn disable_auto_finish(&mut self) {
190 for align in &mut self.aligns {
191 align.disable_auto_finish = true;
192 }
193 }
194
195 pub fn any_enabled(&self) -> bool {
196 self.aligns.iter().any(|x| x.enable)
197 }
198}
199
200#[derive(Clone, Debug, Default)]
201pub struct Measure {
202 widths: Vec<u32>,
203 table: HashMap<TokenId, u32>,
204}
205
206impl Measure {
207 pub fn start(&mut self) {
208 self.widths.push(0);
209 }
210
211 pub fn finish(&mut self, id: TokenId) {
212 let width = self.widths.pop().unwrap();
213 self.table.insert(id, width);
214 }
215
216 pub fn add(&mut self, value: u32) {
217 for w in &mut self.widths {
218 *w += value;
219 }
220 }
221
222 pub fn get(&mut self, id: TokenId) -> Option<u32> {
223 self.table.get(&id).copied()
224 }
225}