rust_hdl_core/
verilog_visitor.rs

1use crate::ast::{
2    VerilogBlock, VerilogBlockOrConditional, VerilogCase, VerilogConditional, VerilogExpression,
3    VerilogIndexAssignment, VerilogLink, VerilogLiteral, VerilogLoop, VerilogMatch, VerilogOp,
4    VerilogOpUnary, VerilogStatement,
5};
6
7pub trait VerilogVisitor {
8    fn visit_block(&mut self, b: &VerilogBlock) {
9        walk_block(self, b);
10    }
11
12    fn visit_statement(&mut self, s: &VerilogStatement) {
13        walk_statement(self, s);
14    }
15
16    fn visit_index_assignment(&mut self, a: &VerilogIndexAssignment) {
17        walk_index_assignment(self, a);
18    }
19
20    fn visit_loop(&mut self, a: &VerilogLoop) {
21        walk_loop(self, a);
22    }
23
24    fn visit_slice_assignment(
25        &mut self,
26        base: &VerilogExpression,
27        width: &usize,
28        offset: &VerilogExpression,
29        replacement: &VerilogExpression,
30    ) {
31        walk_slice_assignment(self, base, width, offset, replacement);
32    }
33
34    fn visit_conditional(&mut self, c: &VerilogConditional) {
35        walk_conditional(self, c);
36    }
37
38    fn visit_block_or_conditional(&mut self, c: &VerilogBlockOrConditional) {
39        walk_block_or_conditional(self, c);
40    }
41
42    fn visit_match(&mut self, m: &VerilogMatch) {
43        walk_match(self, m);
44    }
45
46    fn visit_comment(&mut self, _c: &str) {
47        // Terminal
48    }
49
50    fn visit_signal(&mut self, _c: &str) {
51        // Terminal
52    }
53
54    fn visit_literal(&mut self, _a: &VerilogLiteral) {
55        // Terminal
56    }
57
58    fn visit_link(&mut self, _c: &[VerilogLink]) {
59        // Terminal
60    }
61
62    fn visit_case(&mut self, c: &VerilogCase) {
63        walk_case(self, c);
64    }
65
66    fn visit_lhs_expression(&mut self, e: &VerilogExpression) {
67        walk_lhs_expression(self, e);
68    }
69
70    fn visit_expression(&mut self, e: &VerilogExpression) {
71        walk_expression(self, e);
72    }
73
74    fn visit_binop(&mut self, l: &VerilogExpression, o: &VerilogOp, r: &VerilogExpression) {
75        walk_binop(self, l, o, r);
76    }
77
78    fn visit_unop(&mut self, o: &VerilogOpUnary, ex: &VerilogExpression) {
79        walk_unop(self, o, ex);
80    }
81
82    fn visit_assignment(&mut self, l: &VerilogExpression, r: &VerilogExpression) {
83        walk_assignment(self, l, r);
84    }
85
86    fn visit_paren(&mut self, p: &VerilogExpression) {
87        walk_paren(self, p);
88    }
89
90    fn visit_cast(&mut self, a: &VerilogExpression, b: &usize) {
91        walk_cast(self, a, b);
92    }
93
94    fn visit_signed(&mut self, a: &VerilogExpression) {
95        walk_signed(self, a);
96    }
97
98    fn visit_unsigned(&mut self, a: &VerilogExpression) {
99        walk_unsigned(self, a);
100    }
101
102    fn visit_index(&mut self, a: &VerilogExpression, b: &VerilogExpression) {
103        walk_index(self, a, b);
104    }
105
106    fn visit_slice(&mut self, a: &VerilogExpression, b: &usize, c: &VerilogExpression) {
107        walk_slice(self, a, b, c);
108    }
109
110    fn visit_slice_replace(
111        &mut self,
112        a: &VerilogExpression,
113        b: &usize,
114        c: &VerilogExpression,
115        d: &VerilogExpression,
116    ) {
117        walk_slice_replace(self, a, b, c, d);
118    }
119
120    fn visit_index_replace(
121        &mut self,
122        a: &VerilogExpression,
123        b: &VerilogExpression,
124        c: &VerilogExpression,
125    ) {
126        walk_index_replacement(self, a, b, c);
127    }
128}
129
130pub fn walk_index_replacement<V: VerilogVisitor + ?Sized>(
131    visitor: &mut V,
132    a: &VerilogExpression,
133    b: &VerilogExpression,
134    c: &VerilogExpression,
135) {
136    visitor.visit_expression(a);
137    visitor.visit_expression(b);
138    visitor.visit_expression(c);
139}
140
141pub fn walk_slice<V: VerilogVisitor + ?Sized>(
142    visitor: &mut V,
143    a: &VerilogExpression,
144    _b: &usize,
145    c: &VerilogExpression,
146) {
147    visitor.visit_expression(a);
148    visitor.visit_expression(c);
149}
150
151pub fn walk_slice_replace<V: VerilogVisitor + ?Sized>(
152    visitor: &mut V,
153    a: &VerilogExpression,
154    _b: &usize,
155    c: &VerilogExpression,
156    d: &VerilogExpression,
157) {
158    visitor.visit_expression(a);
159    visitor.visit_expression(c);
160    visitor.visit_expression(d);
161}
162
163pub fn walk_index<V: VerilogVisitor + ?Sized>(
164    visitor: &mut V,
165    a: &VerilogExpression,
166    b: &VerilogExpression,
167) {
168    visitor.visit_expression(a);
169    visitor.visit_expression(b);
170}
171
172pub fn walk_cast<V: VerilogVisitor + ?Sized>(visitor: &mut V, a: &VerilogExpression, _b: &usize) {
173    visitor.visit_expression(a)
174}
175
176pub fn walk_signed<V: VerilogVisitor + ?Sized>(visitor: &mut V, a: &VerilogExpression) {
177    visitor.visit_expression(a)
178}
179
180pub fn walk_unsigned<V: VerilogVisitor + ?Sized>(visitor: &mut V, a: &VerilogExpression) {
181    visitor.visit_expression(a);
182}
183
184pub fn walk_paren<V: VerilogVisitor + ?Sized>(visitor: &mut V, p: &VerilogExpression) {
185    visitor.visit_expression(p);
186}
187
188pub fn walk_block<V: VerilogVisitor + ?Sized>(visitor: &mut V, b: &VerilogBlock) {
189    for s in b {
190        visitor.visit_statement(s)
191    }
192}
193
194pub fn walk_loop<V: VerilogVisitor + ?Sized>(visitor: &mut V, lp: &VerilogLoop) {
195    visitor.visit_literal(&lp.from);
196    visitor.visit_literal(&lp.to);
197    visitor.visit_block(&lp.block);
198}
199
200pub fn walk_slice_assignment<V: VerilogVisitor + ?Sized>(
201    visitor: &mut V,
202    base: &VerilogExpression,
203    _width: &usize,
204    offset: &VerilogExpression,
205    replacement: &VerilogExpression,
206) {
207    visitor.visit_expression(base);
208    visitor.visit_expression(offset);
209    visitor.visit_expression(replacement);
210}
211
212pub fn walk_assignment<V: VerilogVisitor + ?Sized>(
213    visitor: &mut V,
214    l: &VerilogExpression,
215    r: &VerilogExpression,
216) {
217    visitor.visit_expression(l);
218    visitor.visit_expression(r);
219}
220
221pub fn walk_statement<V: VerilogVisitor + ?Sized>(visitor: &mut V, s: &VerilogStatement) {
222    match s {
223        VerilogStatement::Assignment(l, r) => {
224            visitor.visit_assignment(l, r);
225        }
226        VerilogStatement::SliceAssignment {
227            base,
228            width,
229            offset,
230            replacement,
231        } => {
232            visitor.visit_slice_assignment(base, width, offset, replacement);
233        }
234        VerilogStatement::If(c) => {
235            visitor.visit_conditional(c);
236        }
237        VerilogStatement::Match(m) => {
238            visitor.visit_match(m);
239        }
240        VerilogStatement::Comment(x) => {
241            visitor.visit_comment(x);
242        }
243        VerilogStatement::Loop(l) => {
244            visitor.visit_loop(l);
245        }
246        VerilogStatement::Link(l) => {
247            visitor.visit_link(l);
248        }
249        VerilogStatement::Macro(m) => {
250            for statement in m {
251                visitor.visit_statement(statement);
252            }
253        }
254    }
255}
256
257pub fn walk_index_assignment<V: VerilogVisitor + ?Sized>(
258    visitor: &mut V,
259    a: &VerilogIndexAssignment,
260) {
261    visitor.visit_expression(&a.value);
262    visitor.visit_expression(&a.index);
263    visitor.visit_expression(&a.target);
264}
265
266pub fn walk_conditional<V: VerilogVisitor + ?Sized>(visitor: &mut V, c: &VerilogConditional) {
267    visitor.visit_expression(&c.test);
268    visitor.visit_block(&c.then);
269    visitor.visit_block_or_conditional(&c.otherwise);
270}
271
272pub fn walk_block_or_conditional<V: VerilogVisitor + ?Sized>(
273    visitor: &mut V,
274    o: &VerilogBlockOrConditional,
275) {
276    match o {
277        VerilogBlockOrConditional::Block(b) => {
278            visitor.visit_block(b);
279        }
280        VerilogBlockOrConditional::Conditional(c) => {
281            visitor.visit_statement(&c);
282        }
283        VerilogBlockOrConditional::None => {
284            // No-op
285        }
286    }
287}
288
289pub fn walk_match<V: VerilogVisitor + ?Sized>(visitor: &mut V, m: &VerilogMatch) {
290    visitor.visit_expression(&m.test);
291    for case in &m.cases {
292        visitor.visit_case(case)
293    }
294}
295
296pub fn walk_case<V: VerilogVisitor + ?Sized>(visitor: &mut V, c: &VerilogCase) {
297    visitor.visit_block(&c.block)
298}
299
300pub fn walk_lhs_expression<V: VerilogVisitor + ?Sized>(visitor: &mut V, e: &VerilogExpression) {
301    visitor.visit_expression(e)
302}
303
304pub fn walk_binop<V: VerilogVisitor + ?Sized>(
305    visitor: &mut V,
306    l: &VerilogExpression,
307    _op: &VerilogOp,
308    r: &VerilogExpression,
309) {
310    visitor.visit_expression(l);
311    visitor.visit_expression(r);
312}
313
314pub fn walk_unop<V: VerilogVisitor + ?Sized>(
315    visitor: &mut V,
316    _op: &VerilogOpUnary,
317    e: &VerilogExpression,
318) {
319    visitor.visit_expression(e);
320}
321
322pub fn walk_expression<V: VerilogVisitor + ?Sized>(visitor: &mut V, e: &VerilogExpression) {
323    match e {
324        VerilogExpression::Signal(s) => {
325            visitor.visit_signal(s);
326        }
327        VerilogExpression::Literal(a) => {
328            visitor.visit_literal(a);
329        }
330        VerilogExpression::Cast(a, b) => {
331            visitor.visit_cast(a, b);
332        }
333        VerilogExpression::Paren(x) => {
334            visitor.visit_paren(x);
335        }
336        VerilogExpression::Binary(l, op, r) => {
337            visitor.visit_binop(l, op, r);
338        }
339        VerilogExpression::Unary(op, ex) => {
340            visitor.visit_unop(op, ex);
341        }
342        VerilogExpression::Index(a, b) => {
343            visitor.visit_index(a, b);
344        }
345        VerilogExpression::Slice(a, b, c) => {
346            visitor.visit_slice(a, b, c);
347        }
348        VerilogExpression::IndexReplace(a, b, c) => {
349            visitor.visit_index_replace(a, b, c);
350        }
351        VerilogExpression::Signed(a) => {
352            visitor.visit_signed(a);
353        }
354        VerilogExpression::Unsigned(a) => {
355            visitor.visit_unsigned(a);
356        }
357    }
358}