moore_svlog_syntax/
ast.rs

1// Copyright (c) 2016-2021 Fabian Schuiki
2
3//! An abstract syntax tree for SystemVerilog.
4
5#![allow(unused_variables)]
6
7use crate::token::{Lit, Op};
8use moore_common::{
9    id::NodeId,
10    name::Name,
11    source::{Span, Spanned},
12    util::{HasDesc, HasSpan},
13};
14use moore_derive::AnyNodeData;
15use std::{
16    cell::Cell,
17    hash::{Hash, Hasher},
18};
19
20/// An AST node.
21pub trait AnyNode<'a>: BasicNode<'a> + AnyNodeData + std::fmt::Display + Send + Sync {
22    /// Get this node's unique ID.
23    fn id(&self) -> NodeId;
24
25    /// Get this node's span in the input.
26    fn span(&self) -> Span;
27
28    /// Get a span that is terse and suitable to pinpoint the node for a human.
29    fn human_span(&self) -> Span {
30        self.span()
31    }
32
33    /// Get this node's lexical order.
34    fn order(&self) -> usize;
35
36    /// Get this node's parent.
37    fn get_parent(&self) -> Option<&'a dyn AnyNode<'a>> {
38        None
39    }
40
41    /// Link up this node.
42    fn link(&'a self, parent: Option<&'a dyn AnyNode<'a>>, order: &mut usize) {}
43
44    /// Link up this node as an expansion of another node.
45    ///
46    /// All subnodes inherit the order from their parent. Useful if a node is
47    /// generated as part of a later expansion/analysis pass, but needs to hook
48    /// into the AST somewhere.
49    fn link_attach(&'a self, parent: &'a dyn AnyNode<'a>, order: usize) {}
50
51    /// Convert this node reference to a pointer for identity comparisons.
52    fn as_ptr(&self) -> *const u8 {
53        self as *const _ as *const u8
54    }
55}
56
57// Compare and hash nodes by reference for use in the query system.
58impl<'a> Eq for &'a dyn AnyNode<'a> {}
59impl<'a> PartialEq for &'a dyn AnyNode<'a> {
60    fn eq(&self, other: &Self) -> bool {
61        std::ptr::eq(self.as_ptr(), other.as_ptr())
62    }
63}
64impl<'a> Hash for &'a dyn AnyNode<'a> {
65    fn hash<H: Hasher>(&self, h: &mut H) {
66        std::ptr::hash(self.as_ptr(), h)
67    }
68}
69
70/// Basic attributes of an AST node.
71///
72/// If this trait is present on `Node<T>`, then `Node<T>` will automatically
73/// implement the full `AnyNode` trait.
74pub trait BasicNode<'a>:
75    std::fmt::Debug + AcceptVisitor<'a> + ForEachChild<'a> + ForEachNode<'a>
76{
77    /// Get the type name of the node.
78    fn type_name(&self) -> &'static str;
79
80    /// Convert this node to the exhaustive `AllNode` enum.
81    fn as_all(&'a self) -> AllNode<'a>;
82
83    /// Convert this node to an `AnyNode` trait object.
84    fn as_any(&'a self) -> &'a dyn AnyNode<'a>;
85}
86
87/// Common details of an AST node.
88pub trait AnyNodeData {
89    fn as_data(&self) -> &dyn AnyNodeData
90    where
91        Self: Sized,
92    {
93        self
94    }
95
96    /// Get this node's name, or `None` if it does not have one.
97    fn get_name(&self) -> Option<Spanned<Name>> {
98        None
99    }
100
101    /// Describe this node for diagnostics in indefinite form, e.g. *"entity"*.
102    ///
103    /// This should not include any node name. Generally, we want to describe
104    /// the *kind* of node to the user, for example as in *"cannot use <XYZ> at
105    /// this point in the code"*.
106    fn fmt_indefinite(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result;
107
108    /// Describe this node for diagnostics in definite form, e.g. *"entity
109    /// 'top'"*.
110    ///
111    /// If the node has a name, this should include it. Generally, we want to
112    /// provide enough information for the user to pinpoint an exact node in
113    /// their design.
114    fn fmt_definite(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
115        self.fmt_indefinite(fmt)?;
116        if let Some(name) = self.get_name() {
117            write!(fmt, " `{}`", name)?
118        }
119        Ok(())
120    }
121
122    /// Describe this node for diagnostics in indefinite form, e.g. *"entity"*.
123    fn format_indefinite(&self) -> FormatNodeIndefinite
124    where
125        Self: Sized,
126    {
127        FormatNodeIndefinite(self.as_data())
128    }
129
130    /// Describe this node for diagnostics in definite form, e.g. *"entity
131    /// 'top'"*.
132    fn format_definite(&self) -> FormatNodeDefinite
133    where
134        Self: Sized,
135    {
136        FormatNodeDefinite(self.as_data())
137    }
138
139    /// Describe this node for diagnostics in indefinite form, e.g. *"entity"*.
140    fn to_indefinite_string(&self) -> String
141    where
142        Self: Sized,
143    {
144        self.format_indefinite().to_string()
145    }
146
147    /// Describe this node for diagnostics in definite form, e.g. *"entity
148    /// 'top'"*.
149    fn to_definite_string(&self) -> String
150    where
151        Self: Sized,
152    {
153        self.format_definite().to_string()
154    }
155}
156
157/// Format a node in indefinite form.
158pub struct FormatNodeIndefinite<'a>(&'a dyn AnyNodeData);
159
160/// Format a node in definite form.
161pub struct FormatNodeDefinite<'a>(&'a dyn AnyNodeData);
162
163impl<'a> std::fmt::Display for FormatNodeIndefinite<'a> {
164    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
165        self.0.fmt_indefinite(fmt)
166    }
167}
168
169impl<'a> std::fmt::Display for FormatNodeDefinite<'a> {
170    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
171        self.0.fmt_definite(fmt)
172    }
173}
174
175/// A node which allows iterating over each child node.
176pub trait ForEachChild<'a> {
177    /// Apply a function to each child node.
178    fn for_each_child(&'a self, each: &mut dyn FnMut(&'a dyn AnyNode<'a>));
179}
180
181/// A node which can pass itself as `AnyNode` to a callback.
182pub trait ForEachNode<'a> {
183    /// Apply a function to this node.
184    fn for_each_node(&'a self, each: &mut dyn FnMut(&'a dyn AnyNode<'a>)) {}
185}
186
187impl<'a, T> ForEachNode<'a> for &'_ T
188where
189    T: ForEachNode<'a>,
190{
191    fn for_each_node(&'a self, each: &mut dyn FnMut(&'a dyn AnyNode<'a>)) {
192        (*self).for_each_node(each);
193    }
194}
195
196impl<'a, T> ForEachNode<'a> for Option<T>
197where
198    T: ForEachNode<'a>,
199{
200    fn for_each_node(&'a self, each: &mut dyn FnMut(&'a dyn AnyNode<'a>)) {
201        if let Some(node) = self {
202            node.for_each_node(each);
203        }
204    }
205}
206
207impl<'a, T> ForEachNode<'a> for Vec<T>
208where
209    T: ForEachNode<'a>,
210{
211    fn for_each_node(&'a self, each: &mut dyn FnMut(&'a dyn AnyNode<'a>)) {
212        for node in self {
213            node.for_each_node(each);
214        }
215    }
216}
217
218impl<'a, T> ForEachNode<'a> for Spanned<T>
219where
220    T: ForEachNode<'a>,
221{
222    fn for_each_node(&'a self, each: &mut dyn FnMut(&'a dyn AnyNode<'a>)) {
223        self.value.for_each_node(each);
224    }
225}
226
227impl<'a, T> ForEachNode<'a> for Box<T>
228where
229    T: ForEachNode<'a>,
230{
231    fn for_each_node(&'a self, each: &mut dyn FnMut(&'a dyn AnyNode<'a>)) {
232        self.as_ref().for_each_node(each);
233    }
234}
235
236impl<'a> ForEachNode<'a> for Span {}
237impl<'a> ForEachNode<'a> for Name {}
238impl<'a> ForEachNode<'a> for Identifier {}
239impl<'a> ForEachNode<'a> for Lit {}
240impl<'a> ForEachNode<'a> for Op {}
241impl<'a> ForEachNode<'a> for bool {}
242impl<'a> ForEachNode<'a> for usize {}
243
244/// Common denominator across all AST nodes.
245#[derive(Clone)]
246pub struct Node<'a, T> {
247    /// Unique ID assigned to the node.
248    pub id: NodeId,
249    /// Full span the node covers in the input.
250    pub span: Span,
251    /// Parent node.
252    pub parent: Cell<Option<&'a dyn AnyNode<'a>>>,
253    /// Lexical order of the node.
254    pub order: Cell<usize>,
255    /// Per-node data.
256    pub data: T,
257}
258
259impl<'a, T> Node<'a, T> {
260    /// Create a new AST node.
261    pub fn new(span: Span, data: T) -> Self {
262        Node {
263            id: NodeId::alloc(),
264            span,
265            data,
266            parent: Default::default(),
267            order: Default::default(),
268        }
269    }
270}
271
272// The following are needed due to the `Cell`s in `Node`. It is safe to share
273// nodes between threads if we never change `parent` and `order` afterwards.
274// We only set these cells once immediately after constructing an AST, and never
275// again after.
276unsafe impl<'a, T> Send for Node<'a, T> where T: Send {}
277unsafe impl<'a, T> Sync for Node<'a, T> where T: Sync {}
278
279/// Automatically implement `AnyNode` for `Node<T>` if enough information is
280/// present.
281impl<'a, T> AnyNode<'a> for Node<'a, T>
282where
283    Self: BasicNode<'a> + std::fmt::Display + AnyNodeData,
284    T: std::fmt::Debug + ForEachChild<'a> + Send + Sync,
285{
286    fn id(&self) -> NodeId {
287        self.id
288    }
289
290    fn span(&self) -> Span {
291        self.span
292    }
293
294    fn order(&self) -> usize {
295        self.order.get()
296    }
297
298    fn get_parent(&self) -> Option<&'a dyn AnyNode<'a>> {
299        self.parent.get()
300    }
301
302    fn link(&'a self, parent: Option<&'a dyn AnyNode<'a>>, order: &mut usize) {
303        trace!("Linking {:?}", self);
304        self.parent.set(parent);
305        self.order.set(*order);
306        *order += 1;
307        self.for_each_child(&mut |node| {
308            node.link(Some(self.as_any()), order);
309        });
310    }
311
312    fn link_attach(&'a self, parent: &'a dyn AnyNode<'a>, order: usize) {
313        trace!("Linking {:?} as child attachment to {:?}", self, parent);
314        self.parent.set(Some(parent));
315        self.order.set(order);
316        self.for_each_child(&mut |node| {
317            node.link_attach(self.as_any(), order);
318        });
319    }
320}
321
322/// Automatically implement `AnyNodeData` for `Node<T>` if the inner node
323/// implements it.
324impl<'a, T> AnyNodeData for Node<'a, T>
325where
326    T: AnyNodeData,
327{
328    fn get_name(&self) -> Option<Spanned<Name>> {
329        self.data.get_name()
330    }
331
332    fn fmt_indefinite(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
333        self.data.fmt_indefinite(fmt)
334    }
335
336    fn fmt_definite(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
337        self.data.fmt_definite(fmt)
338    }
339}
340
341/// Allow any node to be printed in diagnostics in a human-friendly form.
342impl<'a, T> std::fmt::Display for Node<'a, T>
343where
344    T: AnyNodeData,
345{
346    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
347        if f.alternate() {
348            self.data.fmt_indefinite(f)
349        } else {
350            self.data.fmt_definite(f)
351        }
352    }
353}
354
355/// Allow any node to be debug-formatted.
356impl<'a, T> std::fmt::Debug for Node<'a, T>
357where
358    Self: BasicNode<'a>,
359    T: std::fmt::Debug,
360{
361    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
362        let w = f.width().unwrap_or(0);
363        if w > 0 {
364            write!(f, "{:?}", self)?;
365            if let Some(parent) = self.parent.get() {
366                write!(f, " (#{} in {:?})", self.order.get(), parent)?;
367            }
368            if f.alternate() {
369                write!(f, " {:#w$?}", self.data, w = (w - 1))
370            } else {
371                write!(f, " {:w$?}", self.data, w = (w - 1))
372            }
373        } else {
374            write!(f, "{} #{}", self.type_name(), self.id.as_usize())
375        }
376    }
377}
378
379// Compare and hash nodes by reference for use in the query system.
380impl<'a, T> Eq for Node<'a, T> {}
381impl<'a, T> PartialEq for Node<'a, T> {
382    fn eq(&self, other: &Self) -> bool {
383        std::ptr::eq(self, other)
384    }
385}
386impl<'a, T> Hash for Node<'a, T> {
387    fn hash<H: Hasher>(&self, h: &mut H) {
388        std::ptr::hash(self, h)
389    }
390}
391
392impl<'a, T> ForEachChild<'a> for Node<'a, T>
393where
394    T: ForEachChild<'a>,
395{
396    fn for_each_child(&'a self, each: &mut dyn FnMut(&'a dyn AnyNode<'a>)) {
397        self.data.for_each_child(each)
398    }
399}
400
401impl<'a, T> ForEachNode<'a> for Node<'a, T>
402where
403    Node<'a, T>: AnyNode<'a>,
404{
405    fn for_each_node(&'a self, each: &mut dyn FnMut(&'a dyn AnyNode<'a>)) {
406        each(self);
407    }
408}
409
410impl<'a, 'b: 'a, T> AcceptVisitor<'a> for Node<'b, T>
411where
412    T: AcceptVisitor<'a>,
413{
414    fn accept(&'a self, visitor: &mut dyn Visitor<'a>) {
415        self.data.accept(visitor)
416    }
417}
418
419impl<'a, T> std::ops::Deref for Node<'a, T> {
420    type Target = T;
421
422    fn deref(&self) -> &T {
423        &self.data
424    }
425}
426
427impl<'a, T> std::ops::DerefMut for Node<'a, T> {
428    fn deref_mut(&mut self) -> &mut T {
429        &mut self.data
430    }
431}
432
433/// A node that accepts `Visitor`s.
434pub trait AcceptVisitor<'a> {
435    /// Walk a visitor over the contents of `self`.
436    fn accept(&'a self, visitor: &mut dyn Visitor<'a>);
437}
438
439impl<'a, T> AcceptVisitor<'a> for &'_ T
440where
441    T: AcceptVisitor<'a>,
442{
443    fn accept(&'a self, visitor: &mut dyn Visitor<'a>) {
444        (*self).accept(visitor);
445    }
446}
447
448impl<'a, T> AcceptVisitor<'a> for Vec<T>
449where
450    T: AcceptVisitor<'a>,
451{
452    fn accept(&'a self, visitor: &mut dyn Visitor<'a>) {
453        for c in self {
454            c.accept(visitor);
455        }
456    }
457}
458
459impl<'a, T> AcceptVisitor<'a> for Option<T>
460where
461    T: AcceptVisitor<'a>,
462{
463    fn accept(&'a self, visitor: &mut dyn Visitor<'a>) {
464        if let Some(c) = self {
465            c.accept(visitor);
466        }
467    }
468}
469
470impl<'a, T> AcceptVisitor<'a> for Spanned<T>
471where
472    T: AcceptVisitor<'a>,
473{
474    fn accept(&'a self, visitor: &mut dyn Visitor<'a>) {
475        self.value.accept(visitor);
476    }
477}
478
479/// A node that walks a `Visitor` over itself.
480pub trait WalkVisitor<'a> {
481    /// Walk a visitor over `self`.
482    fn walk(&'a self, visitor: &mut dyn Visitor<'a>);
483}
484
485impl<'a, T> WalkVisitor<'a> for &'_ T
486where
487    T: WalkVisitor<'a>,
488{
489    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {
490        (*self).walk(visitor);
491    }
492}
493
494impl<'a, T> WalkVisitor<'a> for Vec<T>
495where
496    T: WalkVisitor<'a>,
497{
498    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {
499        for c in self {
500            c.walk(visitor);
501        }
502    }
503}
504
505impl<'a, T> WalkVisitor<'a> for Option<T>
506where
507    T: WalkVisitor<'a>,
508{
509    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {
510        if let Some(c) = self {
511            c.walk(visitor);
512        }
513    }
514}
515
516impl<'a, T> WalkVisitor<'a> for Spanned<T>
517where
518    T: WalkVisitor<'a>,
519{
520    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {
521        self.value.walk(visitor);
522    }
523}
524
525impl<'a, T> WalkVisitor<'a> for Box<T>
526where
527    T: WalkVisitor<'a>,
528{
529    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {
530        self.as_ref().walk(visitor);
531    }
532}
533
534impl<'a> WalkVisitor<'a> for Span {
535    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {}
536}
537
538impl<'a> WalkVisitor<'a> for Name {
539    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {}
540}
541
542impl<'a> WalkVisitor<'a> for Identifier {
543    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {}
544}
545
546impl<'a> WalkVisitor<'a> for Lit {
547    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {}
548}
549
550impl<'a> WalkVisitor<'a> for Op {
551    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {}
552}
553
554impl<'a> WalkVisitor<'a> for bool {
555    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {}
556}
557
558impl<'a> WalkVisitor<'a> for usize {
559    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {}
560}
561
562macro_rules! tuple_impls {
563    ($($idx:tt => $args:ident),*) => {
564        impl<'a $(, $args: AcceptVisitor<'a>)*> AcceptVisitor<'a> for ($($args),*) {
565            fn accept(&'a self, visitor: &mut dyn Visitor<'a>) {
566                $(self.$idx.accept(visitor);)*
567            }
568        }
569
570        impl<'a $(, $args: WalkVisitor<'a>)*> WalkVisitor<'a> for ($($args),*) {
571            fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {
572                $(self.$idx.walk(visitor);)*
573            }
574        }
575
576        impl<'a $(, $args: ForEachNode<'a>)*> ForEachNode<'a> for ($($args),*) {
577            fn for_each_node(&'a self, each: &mut dyn FnMut(&'a dyn AnyNode<'a>)) {
578                $(self.$idx.for_each_node(each);)*
579            }
580        }
581    };
582}
583
584tuple_impls!();
585tuple_impls!(0 => T0, 1 => T1);
586tuple_impls!(0 => T0, 1 => T1, 2 => T2);
587tuple_impls!(0 => T0, 1 => T1, 2 => T2, 3 => T3);
588
589pub use self::ExprData::*;
590pub use self::StmtKind::*;
591pub use self::TypeKindData::*;
592
593// Deprecated names.
594#[deprecated(note = "use ast::Module instead")]
595pub type ModDecl<'a> = Module<'a>;
596#[deprecated(note = "use ast::Interface instead")]
597pub type IntfDecl<'a> = Interface<'a>;
598#[deprecated(note = "use ast::Package instead")]
599pub type PackageDecl<'a> = Package<'a>;
600#[deprecated(note = "use ast::Modport instead")]
601pub type ModportDecl<'a> = Modport<'a>;
602
603/// A parsing result which may be ambiguous.
604#[derive(Debug, PartialEq, Eq, Clone)]
605pub enum Ambiguous<R> {
606    Unique(R),
607    Ambiguous(Vec<R>),
608}
609
610impl<'a, R> WalkVisitor<'a> for Ambiguous<R>
611where
612    R: WalkVisitor<'a>,
613{
614    fn walk(&'a self, visitor: &mut dyn Visitor<'a>) {
615        match self {
616            Self::Unique(x) => x.walk(visitor),
617            Self::Ambiguous(x) => x.walk(visitor),
618        }
619    }
620}
621
622impl<'a, R> ForEachNode<'a> for Ambiguous<R>
623where
624    R: ForEachNode<'a>,
625{
626    fn for_each_node(&'a self, each: &mut dyn FnMut(&'a dyn AnyNode<'a>)) {
627        match self {
628            Self::Unique(x) => x.for_each_node(each),
629            Self::Ambiguous(x) => x.for_each_node(each),
630        }
631    }
632}
633
634/// All things being compiled.
635#[moore_derive::node]
636#[indefinite("root")]
637#[derive(Debug)]
638pub struct Root<'a> {
639    pub files: Vec<&'a SourceFile<'a>>,
640}
641
642/// An entire source file.
643#[moore_derive::node]
644#[indefinite("source file")]
645#[derive(Debug)]
646pub struct SourceFile<'a> {
647    pub timeunits: Timeunit,
648    pub items: Vec<Item<'a>>,
649}
650
651/// An item that may appear in a hierarchical scope.
652///
653/// This includes the following scopes:
654/// - file root
655/// - modules
656/// - interfaces
657/// - packages
658/// - classes
659/// - generates
660#[moore_derive::node]
661#[indefinite("item")]
662#[derive(Debug, PartialEq, Eq, Clone)]
663pub enum Item<'a> {
664    #[indefinite("dummy item")]
665    Dummy,
666    ModuleDecl(#[forward] Module<'a>),
667    InterfaceDecl(#[forward] Interface<'a>),
668    PackageDecl(#[forward] Package<'a>),
669    ClassDecl(#[forward] ClassDecl<'a>),
670    ProgramDecl(()),
671    ImportDecl(#[forward] ImportDecl<'a>),
672    DpiDecl(#[forward] DpiDecl<'a>),
673    ParamDecl(#[forward] ParamDecl<'a>),
674    ModportDecl(#[forward] Modport<'a>),
675    Typedef(#[forward] Typedef<'a>),
676    PortDecl(#[forward] PortDecl<'a>),
677    Procedure(#[forward] Procedure<'a>),
678    SubroutineDecl(#[forward] SubroutineDecl<'a>),
679    ContAssign(#[forward] ContAssign<'a>),
680    GenvarDecl(Vec<GenvarDecl<'a>>),
681    GenerateRegion(Span, Vec<Item<'a>>),
682    GenerateFor(#[forward] GenerateFor<'a>),
683    GenerateIf(#[forward] GenerateIf<'a>),
684    GenerateCase(#[forward] GenerateCase<'a>),
685    Assertion(Assertion<'a>),
686    NetDecl(NetDecl<'a>),
687    VarDecl(#[forward] VarDecl<'a>),
688    Inst(Inst<'a>),
689    Timeunit(Timeunit),
690}
691
692/// A module.
693#[moore_derive::node]
694#[indefinite("module")]
695#[definite("module `{}`", name)]
696#[derive(Clone, Debug, PartialEq, Eq)]
697pub struct Module<'a> {
698    pub lifetime: Lifetime, // default static
699    #[name]
700    pub name: Spanned<Name>,
701    pub imports: Vec<ImportDecl<'a>>,
702    pub params: Vec<ParamDecl<'a>>,
703    pub ports: Vec<Port<'a>>,
704    pub items: Vec<Item<'a>>,
705}
706
707/// An interface.
708#[moore_derive::node]
709#[indefinite("interface")]
710#[definite("interface `{}`", name)]
711#[derive(Clone, Debug, PartialEq, Eq)]
712pub struct Interface<'a> {
713    pub lifetime: Lifetime, // default static
714    #[name]
715    pub name: Spanned<Name>,
716    pub params: Vec<ParamDecl<'a>>,
717    pub ports: Vec<Port<'a>>,
718    pub items: Vec<Item<'a>>,
719}
720
721/// A package.
722#[moore_derive::node]
723#[indefinite("package")]
724#[definite("package `{}`", name)]
725#[derive(Clone, Debug, PartialEq, Eq)]
726pub struct Package<'a> {
727    pub lifetime: Lifetime,
728    #[name]
729    pub name: Spanned<Name>,
730    pub items: Vec<Item<'a>>,
731}
732
733/// Lifetime specifier for variables, tasks, and functions. Defaults to static.
734#[moore_derive::visit]
735#[derive(Debug, PartialEq, Eq, Clone)]
736pub enum Lifetime {
737    Static,
738    Automatic,
739}
740
741/// A time unit specification.
742///
743/// ```text
744/// "timeunit" time_literal ["/" time_literal] ";"
745/// "timeprecision" time_literal ";"
746/// ```
747#[moore_derive::visit]
748#[derive(Debug, PartialEq, Eq, Clone)]
749pub struct Timeunit {
750    pub unit: Option<Spanned<Lit>>,
751    pub prec: Option<Spanned<Lit>>,
752}
753
754/// A type.
755#[moore_derive::node]
756#[indefinite("type")]
757#[derive(Debug, PartialEq, Eq, Clone)]
758pub struct Type<'a> {
759    pub kind: TypeKind<'a>,
760    pub sign: TypeSign,
761    pub dims: Vec<TypeDim<'a>>,
762}
763
764impl<'a> Type<'a> {
765    /// Check if this is an implicit type.
766    pub fn is_implicit(&self) -> bool {
767        self.kind.is_implicit()
768    }
769}
770
771/// A type without sign and packed dimensions.
772#[moore_derive::node]
773#[indefinite("type")]
774#[derive(Debug, Clone, PartialEq, Eq)]
775pub enum TypeKind<'a> {
776    ImplicitType,
777    VoidType,
778    NamedType(Spanned<Name>),
779    StringType,
780    ChandleType,
781    VirtIntfType(Name),
782    EventType,
783    MailboxType,
784    ImplicitSignedType,
785    ImplicitUnsignedType,
786
787    // Scoping
788    ScopedType {
789        ty: Box<Type<'a>>,
790        member: bool,
791        name: Spanned<Name>,
792    },
793
794    // Forward declarations
795    ForwardType {
796        kind: Box<TypeKind<'a>>,
797    },
798
799    // Integer Vector Types
800    BitType,
801    LogicType,
802    RegType,
803
804    // Integer Atom Types
805    ByteType,
806    ShortIntType,
807    IntType,
808    IntegerType,
809    LongIntType,
810    TimeType,
811
812    // Non-integer Types
813    ShortRealType,
814    RealType,
815    RealtimeType,
816
817    // Enumerations
818    EnumType(Enum<'a>),
819    StructType(Struct<'a>),
820
821    // Specialization
822    SpecializedType(Box<Type<'a>>, Vec<ParamAssignment<'a>>),
823
824    /// Type reference, such as `type(x)` or `type(int)`.
825    TypeRef(Box<TypeOrExpr<'a>>),
826}
827
828impl<'a> TypeKind<'a> {
829    /// Check if this is an implicit type.
830    pub fn is_implicit(&self) -> bool {
831        match self.data {
832            ImplicitType => true,
833            ImplicitSignedType => true,
834            ImplicitUnsignedType => true,
835            _ => false,
836        }
837    }
838}
839
840#[moore_derive::visit]
841#[derive(Debug, Clone, PartialEq, Eq, Copy)]
842pub enum TypeSign {
843    None,
844    Signed,
845    Unsigned,
846}
847
848#[moore_derive::visit]
849#[derive(Debug, Clone, PartialEq, Eq)]
850pub enum TypeDim<'a> {
851    Expr(Expr<'a>),
852    Range(Expr<'a>, Expr<'a>),
853    Queue(Option<Expr<'a>>),
854    Unsized,
855    Associative(Option<Type<'a>>),
856}
857
858impl HasDesc for TypeDim<'_> {
859    fn desc(&self) -> &'static str {
860        "type dimension"
861    }
862
863    fn desc_full(&self) -> String {
864        match *self {
865            TypeDim::Expr(ref expr) => format!("`[{}]`", expr.span.extract()),
866            TypeDim::Range(ref lhs, ref rhs) => {
867                format!("`[{}:{}]`", lhs.span.extract(), rhs.span.extract())
868            }
869            TypeDim::Queue(None) => format!("`[$]`"),
870            TypeDim::Queue(Some(ref expr)) => format!("`[$:{}]`", expr.span.extract()),
871            TypeDim::Unsized => format!("`[]`"),
872            TypeDim::Associative(None) => format!("[*]"),
873            TypeDim::Associative(Some(ref ty)) => format!("[{}]", ty.span.extract()),
874        }
875    }
876}
877
878/// An enum definition.
879///
880/// For example `enum { FOO = 42 }`.
881#[moore_derive::node]
882#[indefinite("enum definition")]
883#[derive(Debug, Clone, PartialEq, Eq)]
884pub struct Enum<'a> {
885    pub base_type: Option<Box<Type<'a>>>,
886    pub variants: Vec<EnumName<'a>>,
887}
888
889/// A single entry in an enum.
890///
891/// For example the `FOO = 42` in `enum { FOO = 42 }`.
892#[moore_derive::node]
893#[indefinite("enum variant")]
894#[derive(Debug, Clone, PartialEq, Eq)]
895pub struct EnumName<'a> {
896    #[name]
897    pub name: Spanned<Name>,
898    pub range: Option<Expr<'a>>,
899    pub value: Option<Expr<'a>>,
900}
901
902/// A struct definition.
903///
904/// For example `struct packed { byte foo; }`.
905#[moore_derive::node]
906#[indefinite("struct definition")]
907#[derive(Debug, Clone, PartialEq, Eq)]
908pub struct Struct<'a> {
909    pub kind: StructKind,
910    pub packed: bool,
911    pub signing: TypeSign,
912    pub members: Vec<StructMember<'a>>,
913}
914
915#[moore_derive::visit]
916#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
917pub enum StructKind {
918    /// A `struct`.
919    Struct,
920    /// A `union`.
921    Union,
922    /// A `union tagged`.
923    TaggedUnion,
924}
925
926impl std::fmt::Display for StructKind {
927    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
928        match self {
929            Self::Struct => write!(f, "struct"),
930            Self::Union => write!(f, "union"),
931            Self::TaggedUnion => write!(f, "union tagged"),
932        }
933    }
934}
935
936/// A struct field.
937///
938/// For example the `byte foo;` in `struct packed { byte foo; }`.
939#[moore_derive::node]
940#[indefinite("struct member")]
941#[derive(Debug, Clone, PartialEq, Eq)]
942pub struct StructMember<'a> {
943    pub rand_qualifier: Option<RandomQualifier>,
944    pub ty: Box<Type<'a>>,
945    pub names: Vec<VarDeclName<'a>>,
946}
947
948/// A module or interface port as declared in the port list.
949#[moore_derive::node]
950#[indefinite("port")]
951#[derive(Debug, Clone, PartialEq, Eq)]
952pub enum Port<'a> {
953    Intf {
954        modport: Option<Spanned<Name>>,
955        #[name]
956        name: Spanned<Name>,
957        dims: Vec<TypeDim<'a>>,
958        expr: Option<Expr<'a>>,
959    },
960    Explicit {
961        dir: Option<PortDir>,
962        #[name]
963        name: Spanned<Name>,
964        expr: Option<Expr<'a>>,
965    },
966    Named {
967        dir: Option<PortDir>,
968        kind: Option<VarKind>,
969        ty: Type<'a>,
970        #[name]
971        name: Spanned<Name>,
972        dims: Vec<TypeDim<'a>>,
973        expr: Option<Expr<'a>>,
974    },
975    #[indefinite("implicit port")]
976    Implicit(Expr<'a>),
977}
978
979impl HasDesc for Port<'_> {
980    fn desc(&self) -> &'static str {
981        match self.data {
982            PortData::Intf { name, .. } => "interface port",
983            PortData::Explicit { name, .. } => "explicit port",
984            PortData::Named { name, .. } => "port",
985            PortData::Implicit(ref expr) => "implicit port",
986        }
987    }
988
989    fn desc_full(&self) -> String {
990        match self.data {
991            PortData::Intf { name, .. }
992            | PortData::Explicit { name, .. }
993            | PortData::Named { name, .. } => format!("{} `{}`", self.desc(), name),
994            PortData::Implicit(ref expr) => format!("{} `{}`", self.desc(), expr.span.extract()),
995        }
996    }
997}
998
999/// A port declaration in an item body.
1000#[moore_derive::node]
1001#[indefinite("port declaration")]
1002#[derive(Debug, Clone, PartialEq, Eq)]
1003pub struct PortDecl<'a> {
1004    pub dir: PortDir,
1005    pub kind: Option<VarKind>,
1006    pub ty: Type<'a>,
1007    pub names: Vec<VarDeclName<'a>>,
1008}
1009
1010/// Whether a declaration is a variable or a net.
1011#[moore_derive::visit]
1012#[derive(Debug, Clone, PartialEq, Eq, Copy)]
1013pub enum VarKind {
1014    /// A variable declaration.
1015    Var,
1016    /// A net declaration.
1017    Net {
1018        /// The net type, such as `wire` or `trireg`.
1019        ty: NetType,
1020        /// Additional `vectored` or `scalared` specifier.
1021        kind: NetKind,
1022    },
1023}
1024
1025impl VarKind {
1026    /// Check if this is a variable declaration.
1027    pub fn is_var(&self) -> bool {
1028        match self {
1029            Self::Var => true,
1030            _ => false,
1031        }
1032    }
1033
1034    /// Check if this is a net declaration.
1035    pub fn is_net(&self) -> bool {
1036        match self {
1037            Self::Net { .. } => true,
1038            _ => false,
1039        }
1040    }
1041}
1042
1043impl std::fmt::Display for VarKind {
1044    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1045        match self {
1046            Self::Net { ty, kind } => {
1047                write!(f, "{}", ty)?;
1048                match kind {
1049                    NetKind::Vectored => write!(f, " vectored"),
1050                    NetKind::Scalared => write!(f, " scalared"),
1051                    NetKind::None => Ok(()),
1052                }
1053            }
1054            Self::Var => write!(f, "var"),
1055        }
1056    }
1057}
1058
1059#[moore_derive::visit]
1060#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
1061pub enum PortDir {
1062    Input,
1063    Output,
1064    Inout,
1065    Ref,
1066}
1067
1068impl std::fmt::Display for PortDir {
1069    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1070        match self {
1071            PortDir::Input => write!(f, "input"),
1072            PortDir::Output => write!(f, "output"),
1073            PortDir::Inout => write!(f, "inout"),
1074            PortDir::Ref => write!(f, "ref"),
1075        }
1076    }
1077}
1078
1079#[moore_derive::visit]
1080#[derive(Debug, Clone, PartialEq, Eq, Copy)]
1081pub enum NetType {
1082    Supply0,
1083    Supply1,
1084    Tri,
1085    TriAnd,
1086    TriOr,
1087    TriReg,
1088    Tri0,
1089    Tri1,
1090    Uwire,
1091    Wire,
1092    WireAnd,
1093    WireOr,
1094}
1095
1096impl std::fmt::Display for NetType {
1097    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1098        match self {
1099            NetType::Supply0 => write!(f, "supply0"),
1100            NetType::Supply1 => write!(f, "supply1"),
1101            NetType::Tri => write!(f, "tri"),
1102            NetType::TriAnd => write!(f, "triand"),
1103            NetType::TriOr => write!(f, "trior"),
1104            NetType::TriReg => write!(f, "trireg"),
1105            NetType::Tri0 => write!(f, "tri0"),
1106            NetType::Tri1 => write!(f, "tri1"),
1107            NetType::Uwire => write!(f, "uwire"),
1108            NetType::Wire => write!(f, "wire"),
1109            NetType::WireAnd => write!(f, "wand"),
1110            NetType::WireOr => write!(f, "wor"),
1111        }
1112    }
1113}
1114
1115/// A procedure such as `always*`, `initial`, or `final`.
1116#[moore_derive::node]
1117#[indefinite("procedure")]
1118#[derive(Debug, Clone, PartialEq, Eq)]
1119pub struct Procedure<'a> {
1120    pub kind: ProcedureKind,
1121    pub stmt: Stmt<'a>,
1122}
1123
1124#[moore_derive::visit]
1125#[derive(Debug, Clone, PartialEq, Eq, Copy)]
1126pub enum ProcedureKind {
1127    Initial,
1128    Always,
1129    AlwaysComb,
1130    AlwaysLatch,
1131    AlwaysFf,
1132    Final,
1133}
1134
1135/// A statement.
1136#[moore_derive::node]
1137#[indefinite("statement")]
1138#[derive(Debug, Clone, PartialEq, Eq)]
1139pub struct Stmt<'a> {
1140    pub label: Option<Name>,
1141    pub kind: StmtKind<'a>,
1142}
1143
1144/// The different kinds of statement.
1145#[moore_derive::visit]
1146#[derive(Debug, Clone, PartialEq, Eq)]
1147pub enum StmtKind<'a> {
1148    NullStmt,
1149    SequentialBlock(Vec<Stmt<'a>>),
1150    ParallelBlock(Vec<Stmt<'a>>, JoinKind),
1151    IfStmt {
1152        up: Option<UniquePriority>,
1153        cond: Expr<'a>,
1154        main_stmt: Box<Stmt<'a>>,
1155        else_stmt: Option<Box<Stmt<'a>>>,
1156    },
1157    BlockingAssignStmt {
1158        lhs: Expr<'a>,
1159        rhs: Expr<'a>,
1160        op: AssignOp,
1161    },
1162    NonblockingAssignStmt {
1163        lhs: Expr<'a>,
1164        rhs: Expr<'a>,
1165        delay: Option<DelayControl<'a>>,
1166        event: Option<()>,
1167    },
1168    TimedStmt(TimingControl<'a>, Box<Stmt<'a>>),
1169    CaseStmt {
1170        up: Option<UniquePriority>,
1171        kind: CaseKind,
1172        expr: Expr<'a>,
1173        mode: CaseMode,
1174        items: Vec<CaseItem<'a>>,
1175    },
1176    ForeverStmt(Box<Stmt<'a>>),
1177    RepeatStmt(Expr<'a>, Box<Stmt<'a>>),
1178    WhileStmt(Expr<'a>, Box<Stmt<'a>>),
1179    DoStmt(Box<Stmt<'a>>, Expr<'a>),
1180    ForStmt(Box<Stmt<'a>>, Expr<'a>, Expr<'a>, Box<Stmt<'a>>),
1181    ForeachStmt(Expr<'a>, Vec<ForeachIndex<'a>>, Box<Stmt<'a>>),
1182    ExprStmt(Expr<'a>),
1183    VarDeclStmt(VarDecl<'a>),
1184    GenvarDeclStmt(Vec<GenvarDecl<'a>>),
1185    ContinueStmt,
1186    BreakStmt,
1187    ReturnStmt(Option<Expr<'a>>),
1188    ImportStmt(ImportDecl<'a>),
1189    AssertionStmt(Box<Assertion<'a>>),
1190    WaitExprStmt(Expr<'a>, Box<Stmt<'a>>),
1191    WaitForkStmt,
1192    DisableForkStmt,
1193    DisableStmt(Name),
1194}
1195
1196impl<'a> Stmt<'a> {
1197    pub fn new_null(span: Span) -> Stmt<'a> {
1198        Stmt::new(
1199            span,
1200            StmtData {
1201                label: None,
1202                kind: NullStmt,
1203            },
1204        )
1205    }
1206}
1207
1208#[moore_derive::visit]
1209#[derive(Debug, Clone, PartialEq, Eq, Copy)]
1210pub enum JoinKind {
1211    All,
1212    Any,
1213    None,
1214}
1215
1216#[moore_derive::visit]
1217#[derive(Debug, Clone, PartialEq, Eq, Copy)]
1218pub enum UniquePriority {
1219    Unique,
1220    Unique0,
1221    Priority,
1222}
1223
1224#[moore_derive::visit]
1225#[derive(Debug, Clone, PartialEq, Eq, Copy)]
1226pub enum CaseKind {
1227    Normal,
1228    DontCareZ,
1229    DontCareXZ,
1230}
1231
1232#[moore_derive::visit]
1233#[derive(Debug, Clone, PartialEq, Eq, Copy)]
1234pub enum CaseMode {
1235    Normal,
1236    Inside,
1237    Pattern,
1238}
1239
1240#[moore_derive::visit]
1241#[derive(Debug, Clone, PartialEq, Eq)]
1242pub enum CaseItem<'a> {
1243    Default(Box<Stmt<'a>>),
1244    Expr(Vec<Expr<'a>>, Box<Stmt<'a>>),
1245}
1246
1247#[moore_derive::visit]
1248#[derive(Debug, Clone, PartialEq, Eq)]
1249pub struct DelayControl<'a> {
1250    pub span: Span,
1251    pub expr: Expr<'a>,
1252}
1253
1254#[moore_derive::visit]
1255#[derive(Debug, Clone, PartialEq, Eq)]
1256pub struct EventControl<'a> {
1257    pub span: Span,
1258    pub data: EventControlData<'a>,
1259}
1260
1261#[moore_derive::visit]
1262#[derive(Debug, Clone, PartialEq, Eq)]
1263pub enum EventControlData<'a> {
1264    Implicit,
1265    Expr(EventExpr<'a>),
1266}
1267
1268#[moore_derive::visit]
1269#[derive(Debug, Clone, PartialEq, Eq)]
1270pub struct CycleDelay {}
1271
1272#[moore_derive::visit]
1273#[derive(Debug, Clone, PartialEq, Eq)]
1274pub enum TimingControl<'a> {
1275    Delay(DelayControl<'a>),
1276    Event(EventControl<'a>),
1277    Cycle(CycleDelay),
1278}
1279
1280#[moore_derive::visit]
1281#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1282pub enum AssignOp {
1283    Identity,
1284    Add,
1285    Sub,
1286    Mul,
1287    Div,
1288    Mod,
1289    BitAnd,
1290    BitOr,
1291    BitXor,
1292    LogicShL,
1293    LogicShR,
1294    ArithShL,
1295    ArithShR,
1296}
1297
1298/// A variable declaration.
1299///
1300/// For example `logic x, y, z`.
1301#[moore_derive::node]
1302#[indefinite("variable declaration")]
1303#[derive(Debug, Clone, PartialEq, Eq)]
1304pub struct VarDecl<'a> {
1305    pub konst: bool,
1306    pub var: bool,
1307    pub lifetime: Option<Lifetime>,
1308    pub ty: Type<'a>,
1309    pub names: Vec<VarDeclName<'a>>,
1310}
1311
1312/// A variable or net declaration name.
1313///
1314/// For example the `x` in `logic x, y, z`.
1315#[moore_derive::node]
1316#[indefinite("variable")]
1317#[derive(Debug, Clone, PartialEq, Eq)]
1318pub struct VarDeclName<'a> {
1319    pub name: Name,
1320    pub name_span: Span,
1321    pub dims: Vec<TypeDim<'a>>,
1322    pub init: Option<Expr<'a>>,
1323}
1324
1325/// A generate variable declaration.
1326#[moore_derive::node]
1327#[indefinite("genvar")]
1328#[derive(Debug, Clone, PartialEq, Eq)]
1329pub struct GenvarDecl<'a> {
1330    #[name]
1331    pub name: Spanned<Name>,
1332    pub init: Option<Expr<'a>>,
1333}
1334
1335/// A foreach-loop index variable.
1336#[moore_derive::node]
1337#[indefinite("index variable")]
1338#[derive(Debug, Clone, PartialEq, Eq)]
1339pub struct ForeachIndex {
1340    /// The name of the index.
1341    #[name]
1342    pub name: Spanned<Name>,
1343    /// At which index nesting level this index is located.
1344    pub index: usize,
1345}
1346
1347/// An expression.
1348#[moore_derive::node]
1349#[indefinite("expression")]
1350#[derive(Debug, Clone, PartialEq, Eq)]
1351pub enum Expr<'a> {
1352    DummyExpr,
1353    LiteralExpr(Lit),
1354    /// An identifier, like `foo`.
1355    IdentExpr(Spanned<Name>),
1356    /// A system identifier, like `$foo`.
1357    SysIdentExpr(Spanned<Name>),
1358    ThisExpr,
1359    DollarExpr,
1360    NullExpr,
1361    ScopeExpr(Box<Expr<'a>>, Spanned<Name>),
1362    IndexExpr {
1363        indexee: Box<Expr<'a>>,
1364        index: Box<Expr<'a>>,
1365    },
1366    UnaryExpr {
1367        op: Op,
1368        expr: Box<Expr<'a>>,
1369        postfix: bool,
1370    },
1371    BinaryExpr {
1372        op: Op,
1373        lhs: Box<Expr<'a>>,
1374        rhs: Box<Expr<'a>>,
1375    },
1376    TernaryExpr {
1377        cond: Box<Expr<'a>>,
1378        true_expr: Box<Expr<'a>>,
1379        false_expr: Box<Expr<'a>>,
1380    },
1381    AssignExpr {
1382        op: AssignOp,
1383        lhs: Box<Expr<'a>>,
1384        rhs: Box<Expr<'a>>,
1385    },
1386    CallExpr(Box<Expr<'a>>, Vec<CallArg<'a>>),
1387    TypeExpr(Box<Type<'a>>), // TODO: Check if this is still needed, otherwise remove
1388    ConstructorCallExpr(Vec<CallArg<'a>>),
1389    ClassNewExpr(Option<Box<Expr<'a>>>),
1390    ArrayNewExpr(Box<Expr<'a>>, Option<Box<Expr<'a>>>),
1391    EmptyQueueExpr,
1392    StreamConcatExpr {
1393        slice: Option<StreamConcatSlice<'a>>,
1394        exprs: Vec<StreamExpr<'a>>,
1395    },
1396    ConcatExpr {
1397        repeat: Option<Box<Expr<'a>>>,
1398        exprs: Vec<Expr<'a>>,
1399    },
1400    MinTypMaxExpr {
1401        min: Box<Expr<'a>>,
1402        typ: Box<Expr<'a>>,
1403        max: Box<Expr<'a>>,
1404    },
1405    RangeExpr {
1406        mode: RangeMode,
1407        lhs: Box<Expr<'a>>,
1408        rhs: Box<Expr<'a>>,
1409    },
1410    /// A member expression, like `a.b`.
1411    MemberExpr {
1412        expr: Box<Expr<'a>>,
1413        name: Spanned<Name>,
1414    },
1415    PatternExpr(Vec<PatternField<'a>>),
1416    InsideExpr(Box<Expr<'a>>, Vec<ValueRange<'a>>),
1417    CastExpr(Type<'a>, Box<Expr<'a>>),
1418    CastSizeExpr(Box<Expr<'a>>, Box<Expr<'a>>),
1419    CastSignExpr(Spanned<TypeSign>, Box<Expr<'a>>),
1420    /// A `$bits` call.
1421    BitsExpr {
1422        name: Spanned<Name>,
1423        arg: TypeOrExpr<'a>,
1424    },
1425}
1426
1427/// An ambiguous node that can either be a type or and expression.
1428///
1429/// Use the `disamb_type_or_expr` query to disambiguate based on name
1430/// resolution.
1431#[moore_derive::arena]
1432#[moore_derive::visit]
1433#[derive(AnyNodeData, Debug, Clone, Copy, PartialEq, Eq)]
1434#[forward]
1435pub enum TypeOrExpr<'a> {
1436    Type(&'a Type<'a>),
1437    Expr(&'a Expr<'a>),
1438}
1439
1440impl<'a> AnyNode<'a> for TypeOrExpr<'a> {
1441    fn id(&self) -> NodeId {
1442        match self {
1443            TypeOrExpr::Type(x) => x.id(),
1444            TypeOrExpr::Expr(x) => x.id(),
1445        }
1446    }
1447
1448    fn span(&self) -> Span {
1449        match self {
1450            TypeOrExpr::Type(x) => x.span(),
1451            TypeOrExpr::Expr(x) => x.span(),
1452        }
1453    }
1454
1455    fn human_span(&self) -> Span {
1456        match self {
1457            TypeOrExpr::Type(x) => x.human_span(),
1458            TypeOrExpr::Expr(x) => x.human_span(),
1459        }
1460    }
1461
1462    fn order(&self) -> usize {
1463        match self {
1464            TypeOrExpr::Type(x) => x.order(),
1465            TypeOrExpr::Expr(x) => x.order(),
1466        }
1467    }
1468
1469    fn get_parent(&self) -> Option<&'a dyn AnyNode<'a>> {
1470        match self {
1471            TypeOrExpr::Type(x) => x.get_parent(),
1472            TypeOrExpr::Expr(x) => x.get_parent(),
1473        }
1474    }
1475
1476    fn link(&'a self, parent: Option<&'a dyn AnyNode<'a>>, order: &mut usize) {
1477        match self {
1478            TypeOrExpr::Type(x) => x.link(parent, order),
1479            TypeOrExpr::Expr(x) => x.link(parent, order),
1480        }
1481    }
1482
1483    fn link_attach(&'a self, parent: &'a dyn AnyNode<'a>, order: usize) {
1484        match self {
1485            TypeOrExpr::Type(x) => x.link_attach(parent, order),
1486            TypeOrExpr::Expr(x) => x.link_attach(parent, order),
1487        }
1488    }
1489}
1490
1491impl<'a> BasicNode<'a> for TypeOrExpr<'a> {
1492    fn type_name(&self) -> &'static str {
1493        match self {
1494            TypeOrExpr::Type(x) => x.type_name(),
1495            TypeOrExpr::Expr(x) => x.type_name(),
1496        }
1497    }
1498
1499    fn as_all(&'a self) -> AllNode<'a> {
1500        match self {
1501            TypeOrExpr::Type(x) => x.as_all(),
1502            TypeOrExpr::Expr(x) => x.as_all(),
1503        }
1504    }
1505
1506    fn as_any(&'a self) -> &'a dyn AnyNode<'a> {
1507        match self {
1508            TypeOrExpr::Type(x) => x.as_any(),
1509            TypeOrExpr::Expr(x) => x.as_any(),
1510        }
1511    }
1512}
1513
1514impl<'a> std::fmt::Display for TypeOrExpr<'a> {
1515    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
1516        match self {
1517            TypeOrExpr::Type(x) => std::fmt::Display::fmt(x, fmt),
1518            TypeOrExpr::Expr(x) => std::fmt::Display::fmt(x, fmt),
1519        }
1520    }
1521}
1522
1523#[moore_derive::visit]
1524#[derive(Debug, Clone, PartialEq, Eq)]
1525pub enum ValueRange<'a> {
1526    Single(Expr<'a>),
1527    Range {
1528        lo: Expr<'a>,
1529        hi: Expr<'a>,
1530        span: Span,
1531    },
1532}
1533
1534#[moore_derive::visit]
1535#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1536pub enum RangeMode {
1537    Absolute,
1538    RelativeDown,
1539    RelativeUp,
1540}
1541
1542#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1543pub struct Identifier {
1544    pub span: Span,
1545    pub name: Name,
1546}
1547
1548/// An argument to a a function or task call.
1549#[moore_derive::node]
1550#[indefinite("call argument")]
1551#[derive(Debug, Clone, PartialEq, Eq)]
1552pub struct CallArg<'a> {
1553    /// An optional name of the argument, e.g. `.foo(x)` instead of just `x`.
1554    pub name: Option<Spanned<Name>>,
1555    /// An optional value to assign to the argument. Omitting this causes the
1556    /// call to use the default argument in the function/task declaration.
1557    pub expr: Option<Expr<'a>>,
1558}
1559
1560#[moore_derive::visit]
1561#[derive(Debug, Clone, PartialEq, Eq)]
1562pub enum StreamConcatSlice<'a> {
1563    Expr(Box<Expr<'a>>),
1564    Type(Type<'a>),
1565}
1566
1567#[moore_derive::visit]
1568#[derive(Debug, Clone, PartialEq, Eq)]
1569pub struct StreamExpr<'a> {
1570    pub expr: Box<Expr<'a>>,
1571    pub range: Option<Box<Expr<'a>>>,
1572}
1573
1574#[moore_derive::visit]
1575#[derive(Debug, Clone, PartialEq, Eq)]
1576pub enum EventExpr<'a> {
1577    Edge {
1578        span: Span,
1579        edge: EdgeIdent,
1580        value: Expr<'a>,
1581    },
1582    Iff {
1583        span: Span,
1584        expr: Box<EventExpr<'a>>,
1585        cond: Expr<'a>,
1586    },
1587    Or {
1588        span: Span,
1589        lhs: Box<EventExpr<'a>>,
1590        rhs: Box<EventExpr<'a>>,
1591    },
1592}
1593
1594#[moore_derive::visit]
1595#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1596pub enum EdgeIdent {
1597    Implicit,
1598    Edge,
1599    Posedge,
1600    Negedge,
1601}
1602
1603impl HasSpan for EventExpr<'_> {
1604    fn span(&self) -> Span {
1605        match *self {
1606            EventExpr::Edge { span: sp, .. } => sp,
1607            EventExpr::Iff { span: sp, .. } => sp,
1608            EventExpr::Or { span: sp, .. } => sp,
1609        }
1610    }
1611}
1612
1613impl HasDesc for EventExpr<'_> {
1614    fn desc(&self) -> &'static str {
1615        "event expression"
1616    }
1617}
1618
1619/// A class declaration.
1620#[moore_derive::node]
1621#[indefinite("class declaration")]
1622#[definite("class `{}`", name)]
1623#[derive(Debug, Clone, PartialEq, Eq)]
1624pub struct ClassDecl<'a> {
1625    pub virt: bool,
1626    pub lifetime: Lifetime, // default static
1627    pub name: Spanned<Name>,
1628    pub params: Vec<ParamDecl<'a>>,
1629    pub extends: Option<(Type<'a>, Vec<CallArg<'a>>)>,
1630    pub impls: Vec<Spanned<Name>>,
1631    pub items: Vec<ClassItem<'a>>,
1632}
1633
1634#[moore_derive::visit]
1635#[derive(Debug, Clone, PartialEq, Eq)]
1636pub struct ClassItem<'a> {
1637    pub span: Span,
1638    pub qualifiers: Vec<(ClassItemQualifier, Span)>,
1639    pub data: ClassItemData<'a>,
1640}
1641
1642#[moore_derive::visit]
1643#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1644pub enum ClassItemQualifier {
1645    Static,
1646    Protected,
1647    Local,
1648    Rand,
1649    Randc,
1650    Pure,
1651    Virtual,
1652    Const,
1653}
1654
1655#[moore_derive::visit]
1656#[derive(Debug, Clone, PartialEq, Eq)]
1657pub enum ClassItemData<'a> {
1658    Property,
1659    Typedef(Typedef<'a>),
1660    SubroutineDecl(SubroutineDecl<'a>),
1661    ExternSubroutine(SubroutinePrototype<'a>),
1662    Constraint(Constraint<'a>),
1663    ClassDecl,
1664    CovergroupDecl,
1665    ParamDecl(ParamDecl<'a>),
1666    Null,
1667}
1668
1669#[moore_derive::visit]
1670#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1671pub enum RandomQualifier {
1672    Rand,
1673    Randc,
1674}
1675
1676/// A type definition.
1677///
1678/// For example `typedef int my_type_t`.
1679#[moore_derive::node]
1680#[indefinite("typedef")]
1681#[derive(Debug, Clone, PartialEq, Eq)]
1682pub struct Typedef<'a> {
1683    #[name]
1684    pub name: Spanned<Name>,
1685    pub ty: Type<'a>,
1686    pub dims: Vec<TypeDim<'a>>,
1687}
1688
1689#[moore_derive::visit]
1690#[derive(Debug, Clone, PartialEq, Eq)]
1691pub struct Constraint<'a> {
1692    pub span: Span,
1693    pub kind: ConstraintKind,
1694    pub statik: bool,
1695    pub name: Name,
1696    pub name_span: Span,
1697    pub items: Vec<ConstraintItem<'a>>,
1698}
1699
1700#[moore_derive::visit]
1701#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1702pub enum ConstraintKind {
1703    Decl,
1704    Proto,
1705    ExternProto,
1706    PureProto,
1707}
1708
1709#[moore_derive::visit]
1710#[derive(Debug, Clone, PartialEq, Eq)]
1711pub struct ConstraintItem<'a> {
1712    pub span: Span,
1713    pub data: ConstraintItemData<'a>,
1714}
1715
1716#[moore_derive::visit]
1717#[derive(Debug, Clone, PartialEq, Eq)]
1718pub enum ConstraintItemData<'a> {
1719    If,
1720    Foreach,
1721    Expr(Expr<'a>),
1722}
1723
1724/// A function or task declaration.
1725#[moore_derive::node]
1726#[indefinite("subroutine declaration")]
1727#[derive(Debug, Clone, PartialEq, Eq)]
1728pub struct SubroutineDecl<'a> {
1729    #[forward]
1730    pub prototype: SubroutinePrototype<'a>,
1731    pub items: Vec<SubroutineItem<'a>>,
1732}
1733
1734/// A function or task prototype.
1735#[moore_derive::node]
1736#[indefinite("subroutine prototype")]
1737#[derive(Debug, Clone, PartialEq, Eq)]
1738pub struct SubroutinePrototype<'a> {
1739    /// Whether this is a function or a task.
1740    pub kind: SubroutineKind,
1741    /// The default lifetime of the subroutine.
1742    pub lifetime: Option<Lifetime>,
1743    /// The name of the subroutine.
1744    #[name]
1745    pub name: Spanned<Name>,
1746    /// The arguments of the function or task. `None` if no parentheses have
1747    /// been provided; `Some(vec![...])` otherwise.
1748    pub args: Option<Vec<SubroutinePort<'a>>>,
1749    /// The return type.
1750    pub retty: Option<Type<'a>>,
1751}
1752
1753#[moore_derive::visit]
1754#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1755pub enum SubroutineKind {
1756    Func,
1757    Task,
1758}
1759
1760/// A function or task port.
1761///
1762/// This is the `inout logic [7:0]` part in `inout logic [7:0] x[3]`.
1763///
1764/// Since the grammar allows for both omitting the type and omitting the port
1765/// name (the latter only if the subroutine has no body, i.e. is a prototype),
1766/// there is an ambiguity when just a name is provided: `foo` may be a port with
1767/// implicit type, if `foo` is not a defined type or the subroutine is not a
1768/// prototype, or `foo` may be a port of type `foo` without a name, if `foo` is
1769/// a defined type.
1770#[moore_derive::node]
1771#[indefinite("subroutine port")]
1772#[derive(Debug, Clone, PartialEq, Eq)]
1773pub struct SubroutinePort<'a> {
1774    /// The direction of the port, if provided.
1775    pub dir: Option<SubroutinePortDir>,
1776    /// Whether an explicit `var` keyword was present.
1777    pub var: bool,
1778    /// The type and/or name of the port.
1779    pub ty_name: Ambiguous<(Type<'a>, Option<SubroutinePortName<'a>>)>,
1780}
1781
1782/// A single name of a function or task port.
1783///
1784/// This is the `x[3]` part in `inout logic [7:0] x[3]`.
1785#[moore_derive::visit]
1786#[derive(Debug, Clone, PartialEq, Eq)]
1787pub struct SubroutinePortName<'a> {
1788    /// The name of the port.
1789    pub name: Spanned<Name>,
1790    /// The unpacked dimensions of the port.
1791    pub dims: Vec<TypeDim<'a>>,
1792    /// The optional default value of the port.
1793    pub expr: Option<Expr<'a>>,
1794}
1795
1796#[moore_derive::visit]
1797#[derive(Debug, Clone, PartialEq, Eq)]
1798pub enum SubroutineItem<'a> {
1799    PortDecl(SubroutinePortDecl<'a>),
1800    Stmt(Stmt<'a>),
1801}
1802
1803/// A function or task port declaration located in the body.
1804#[moore_derive::node]
1805#[indefinite("subroutine port")]
1806#[derive(Debug, Clone, PartialEq, Eq)]
1807pub struct SubroutinePortDecl<'a> {
1808    /// The direction of the port.
1809    pub dir: SubroutinePortDir,
1810    /// Whether an explicit `var` keyword was present.
1811    pub var: bool,
1812    /// The port type.
1813    pub ty: Type<'a>,
1814    /// The port name declarations.
1815    pub names: Vec<VarDeclName<'a>>,
1816}
1817
1818#[moore_derive::visit]
1819#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1820pub enum SubroutinePortDir {
1821    Input,
1822    Output,
1823    Inout,
1824    Ref,
1825    ConstRef,
1826}
1827
1828impl std::fmt::Display for SubroutinePortDir {
1829    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1830        match self {
1831            Self::Input => write!(f, "input"),
1832            Self::Output => write!(f, "output"),
1833            Self::Inout => write!(f, "inout"),
1834            Self::Ref => write!(f, "ref"),
1835            Self::ConstRef => write!(f, "const ref"),
1836        }
1837    }
1838}
1839
1840/// A net declaration.
1841///
1842/// For example `wire x, y, z`.
1843#[moore_derive::node]
1844#[indefinite("net declaration")]
1845#[derive(Debug, Clone, PartialEq, Eq)]
1846pub struct NetDecl<'a> {
1847    pub net_type: NetType,
1848    pub strength: Option<NetStrength>,
1849    pub kind: NetKind,
1850    pub ty: Type<'a>,
1851    pub delay: Option<DelayControl<'a>>,
1852    pub names: Vec<VarDeclName<'a>>,
1853}
1854
1855#[moore_derive::visit]
1856#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1857pub enum NetKind {
1858    Vectored,
1859    Scalared,
1860    None,
1861}
1862
1863#[moore_derive::visit]
1864#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1865pub enum NetStrength {
1866    Drive(DriveStrength, DriveStrength),
1867    Charge(ChargeStrength),
1868}
1869
1870#[moore_derive::visit]
1871#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1872pub enum DriveStrength {
1873    Supply0,
1874    Strong0,
1875    Pull0,
1876    Weak0,
1877    HighZ0,
1878    Supply1,
1879    Strong1,
1880    Pull1,
1881    Weak1,
1882    HighZ1,
1883}
1884
1885#[moore_derive::visit]
1886#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1887pub enum ChargeStrength {
1888    Small,
1889    Medium,
1890    Large,
1891}
1892
1893/// A field in a `'{...}` pattern.
1894#[moore_derive::node]
1895#[indefinite("pattern field")]
1896#[derive(Debug, Clone, PartialEq, Eq)]
1897pub enum PatternField<'a> {
1898    Default(Box<Expr<'a>>),
1899    Member(Box<Expr<'a>>, Box<Expr<'a>>),
1900    Type(Type<'a>, Box<Expr<'a>>),
1901    Expr(Box<Expr<'a>>),
1902    Repeat(Box<Expr<'a>>, Vec<Expr<'a>>),
1903}
1904
1905/// An import declaration.
1906///
1907/// For example `import a::b, c::*`.
1908#[moore_derive::node]
1909#[indefinite("import declaration")]
1910#[derive(Debug, Clone, PartialEq, Eq)]
1911pub struct ImportDecl<'a> {
1912    pub items: Vec<ImportItem<'a>>,
1913}
1914
1915/// A single import.
1916///
1917/// For example the `a::b` in `import a::b, c::*`.
1918#[moore_derive::node]
1919#[indefinite("import")]
1920#[derive(Debug, Clone, PartialEq, Eq)]
1921pub struct ImportItem {
1922    pub pkg: Spanned<Name>,
1923    pub name: Option<Spanned<Name>>, // None means `import pkg::*`
1924}
1925
1926#[moore_derive::visit]
1927#[derive(Debug, Clone, PartialEq, Eq)]
1928pub struct Assertion<'a> {
1929    pub span: Span,
1930    pub label: Option<(Name, Span)>,
1931    pub data: AssertionData<'a>,
1932}
1933
1934#[moore_derive::visit]
1935#[derive(Debug, Clone, PartialEq, Eq)]
1936pub enum AssertionData<'a> {
1937    Immediate(BlockingAssertion<'a>),
1938    Deferred(AssertionDeferred, BlockingAssertion<'a>),
1939    Concurrent(ConcurrentAssertion<'a>),
1940}
1941
1942#[moore_derive::visit]
1943#[derive(Debug, Clone, PartialEq, Eq)]
1944pub enum AssertionDeferred {
1945    /// `assert #0`
1946    Observed,
1947    /// `assert final`
1948    Final,
1949}
1950
1951#[moore_derive::visit]
1952#[derive(Debug, Clone, PartialEq, Eq)]
1953pub enum BlockingAssertion<'a> {
1954    Assert(Expr<'a>, AssertionActionBlock<'a>),
1955    Assume(Expr<'a>, AssertionActionBlock<'a>),
1956    Cover(Expr<'a>, Stmt<'a>),
1957}
1958
1959#[moore_derive::visit]
1960#[derive(Debug, Clone, PartialEq, Eq)]
1961pub enum ConcurrentAssertion<'a> {
1962    AssertProperty(PropSpec, AssertionActionBlock<'a>),
1963    AssumeProperty(PropSpec, AssertionActionBlock<'a>),
1964    CoverProperty(PropSpec, Stmt<'a>),
1965    CoverSequence,
1966    ExpectProperty(PropSpec, AssertionActionBlock<'a>),
1967    RestrictProperty(PropSpec),
1968}
1969
1970#[moore_derive::visit]
1971#[derive(Debug, Clone, PartialEq, Eq)]
1972pub enum AssertionActionBlock<'a> {
1973    Positive(Stmt<'a>),
1974    Negative(Stmt<'a>),
1975    Both(Stmt<'a>, Stmt<'a>),
1976}
1977
1978#[moore_derive::visit]
1979#[derive(Debug, Clone, PartialEq, Eq)]
1980pub struct SeqExpr<'a> {
1981    pub span: Span,
1982    pub data: SeqExprData<'a>,
1983}
1984
1985#[moore_derive::visit]
1986#[derive(Debug, Clone, PartialEq, Eq)]
1987pub enum SeqExprData<'a> {
1988    Expr(Expr<'a>, Option<SeqRep<'a>>),
1989    BinOp(SeqBinOp, Box<SeqExpr<'a>>, Box<SeqExpr<'a>>),
1990    Throughout(Expr<'a>, Box<SeqExpr<'a>>),
1991    Clocked(EventExpr<'a>, Box<SeqExpr<'a>>),
1992}
1993
1994#[moore_derive::visit]
1995#[derive(Debug, Clone, PartialEq, Eq)]
1996pub enum SeqRep<'a> {
1997    Consec(Expr<'a>),    // [* expr]
1998    ConsecStar,          // [*]
1999    ConsecPlus,          // [+]
2000    Nonconsec(Expr<'a>), // [= expr]
2001    Goto(Expr<'a>),      // [-> expr]
2002}
2003
2004#[moore_derive::visit]
2005#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2006pub enum SeqBinOp {
2007    Or,
2008    And,
2009    Intersect,
2010    Within,
2011}
2012
2013#[moore_derive::visit]
2014#[derive(Debug, Clone, PartialEq, Eq)]
2015pub struct PropSpec;
2016
2017#[moore_derive::visit]
2018#[derive(Debug, Clone, PartialEq, Eq)]
2019pub struct PropExpr<'a> {
2020    pub span: Span,
2021    pub data: PropExprData<'a>,
2022}
2023
2024#[moore_derive::visit]
2025#[derive(Debug, Clone, PartialEq, Eq)]
2026pub enum PropExprData<'a> {
2027    SeqOp(PropSeqOp, SeqExpr<'a>),
2028    SeqBinOp(PropSeqBinOp, PropSeqOp, SeqExpr<'a>, Box<PropExpr<'a>>),
2029    Not(Box<PropExpr<'a>>),
2030    BinOp(PropBinOp, Box<PropExpr<'a>>, Box<PropExpr<'a>>),
2031    Clocked(EventExpr<'a>, Box<PropExpr<'a>>),
2032}
2033
2034#[moore_derive::visit]
2035#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2036pub enum PropSeqOp {
2037    None,
2038    Weak,
2039    Strong,
2040}
2041
2042#[moore_derive::visit]
2043#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2044pub enum PropSeqBinOp {
2045    ImplOverlap,
2046    ImplNonoverlap,
2047    FollowOverlap,
2048    FollowNonoverlap,
2049}
2050
2051#[moore_derive::visit]
2052#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2053pub enum PropBinOp {
2054    Or,
2055    And,
2056    Until,
2057    SUntil,
2058    UntilWith,
2059    SUntilWith,
2060    Impl,
2061    Iff,
2062    SeqImplOl,
2063    SeqImplNol,
2064    SeqFollowOl,
2065    SeqFollowNol,
2066}
2067
2068/// An instantiation of a module.
2069///
2070/// For example `foo u0(), u1();`.
2071#[moore_derive::node]
2072#[indefinite("instantiation")]
2073#[definite("`{}` instantiation", target)]
2074#[derive(Debug, Clone, PartialEq, Eq)]
2075pub struct Inst<'a> {
2076    /// The name of the module to instantiate.
2077    #[name]
2078    pub target: Spanned<Name>,
2079    /// The parameters in the module to be assigned.
2080    pub params: Vec<ParamAssignment<'a>>,
2081    /// The names and ports of the module instantiations.
2082    pub names: Vec<InstName<'a>>,
2083}
2084
2085/// A single module instance.
2086///
2087/// For example the `u0()` in `foo u0(), u1();`.
2088#[moore_derive::node]
2089#[indefinite("instance")]
2090#[derive(Debug, Clone, PartialEq, Eq)]
2091pub struct InstName<'a> {
2092    /// The name of the instance.
2093    #[name]
2094    pub name: Spanned<Name>,
2095    /// The unpacked dimensions.
2096    pub dims: Vec<TypeDim<'a>>,
2097    /// The port connections.
2098    pub conns: Vec<PortConn<'a>>,
2099}
2100
2101impl<'a> InstName<'a> {
2102    /// Get the parent instantiation.
2103    pub fn inst(&self) -> &'a Inst<'a> {
2104        match self.get_parent().unwrap().as_all().get_inst() {
2105            Some(x) => x,
2106            None => panic!(
2107                "parent {:?} of InstName is not Inst",
2108                self.get_parent().unwrap()
2109            ),
2110        }
2111    }
2112}
2113
2114/// A modport declaration in an interface.
2115///
2116/// For example `modport in (...), out (...);`.
2117#[moore_derive::node]
2118#[indefinite("modport")]
2119#[derive(Debug, Clone, PartialEq, Eq)]
2120pub struct Modport<'a> {
2121    /// The names of the modports.
2122    pub names: Vec<&'a ModportName<'a>>,
2123}
2124
2125/// A single modport declaration.
2126///
2127/// For example the `in (...)` in `modport in (...), out (...);`.
2128#[moore_derive::node]
2129#[indefinite("modport")]
2130#[derive(Debug, Clone, PartialEq, Eq)]
2131pub struct ModportName<'a> {
2132    /// The name of the modport.
2133    #[name]
2134    pub name: Spanned<Name>,
2135    /// The individual port specifications.
2136    pub ports: Vec<&'a ModportPort<'a>>,
2137}
2138
2139/// A modport ports declaration.
2140///
2141/// For example `input a, .b(expr)`, or `import ...`, or `clocking foo`.
2142#[moore_derive::node]
2143#[indefinite("modport port")]
2144#[derive(Debug, Clone, PartialEq, Eq)]
2145pub enum ModportPort<'a> {
2146    /// A simple port, for example `input a, .b(expr)`.
2147    Simple {
2148        dir: Spanned<PortDir>,
2149        port: Vec<&'a ModportSimplePort<'a>>,
2150    },
2151}
2152
2153/// A single simple modport port.
2154///
2155/// For example the `a` or `.b(expr)` in `input a, .b(expr)`.
2156#[moore_derive::node]
2157#[indefinite("simple modport port")]
2158#[derive(Debug, Clone, PartialEq, Eq)]
2159pub struct ModportSimplePort<'a> {
2160    /// The name of the port.
2161    #[name]
2162    pub name: Spanned<Name>,
2163    /// The optional parenthesized expression of the port.
2164    pub expr: Option<&'a Expr<'a>>,
2165}
2166
2167/// A parameter or localparam declaration.
2168///
2169/// ```text
2170/// "localparam" data_type_or_implicit list_of_param_assignments
2171/// "localparam" "type" list_of_type_assignments
2172/// "parameter" data_type_or_implicit list_of_param_assignments
2173/// "parameter" "type" list_of_type_assignments
2174/// ```
2175#[moore_derive::node]
2176#[indefinite("parameter")]
2177#[derive(Debug, Clone, PartialEq, Eq)]
2178pub struct ParamDecl<'a> {
2179    pub local: bool,
2180    pub kind: ParamKind<'a>,
2181}
2182
2183#[moore_derive::visit]
2184#[derive(Debug, Clone, PartialEq, Eq)]
2185pub enum ParamKind<'a> {
2186    Type(Vec<ParamTypeDecl<'a>>),
2187    Value(Vec<ParamValueDecl<'a>>),
2188}
2189
2190/// A single type assignment within a parameter or localparam declaration.
2191///
2192/// ```text
2193/// ident ["=" type]
2194/// ```
2195#[moore_derive::node]
2196#[indefinite("type parameter")]
2197#[derive(Debug, Clone, PartialEq, Eq)]
2198pub struct ParamTypeDecl<'a> {
2199    #[name]
2200    pub name: Spanned<Name>,
2201    pub ty: Option<Type<'a>>,
2202}
2203
2204/// A single value assignment within a parameter or localparam declaration.
2205///
2206/// ```text
2207/// [type_or_implicit] ident {dimension} ["=" expr]
2208/// ```
2209#[moore_derive::node]
2210#[indefinite("value parameter")]
2211#[derive(Debug, Clone, PartialEq, Eq)]
2212pub struct ParamValueDecl<'a> {
2213    pub ty: Type<'a>,
2214    #[name]
2215    pub name: Spanned<Name>,
2216    pub dims: Vec<TypeDim<'a>>,
2217    pub expr: Option<Expr<'a>>,
2218}
2219
2220/// A continuous assignment statement.
2221///
2222/// ```text
2223/// "assign" [drive_strength] [delay3] list_of_assignments ";"
2224/// "assign" [delay_control] list_of_assignments ";"
2225/// ```
2226#[moore_derive::node]
2227#[indefinite("continuous assignment")]
2228#[derive(Debug, Clone, PartialEq, Eq)]
2229pub struct ContAssign<'a> {
2230    pub strength: Option<(DriveStrength, DriveStrength)>,
2231    pub delay: Option<Expr<'a>>,
2232    pub delay_control: Option<DelayControl<'a>>,
2233    pub assignments: Vec<(Expr<'a>, Expr<'a>)>,
2234}
2235
2236/// A `for` generate statement.
2237#[moore_derive::node]
2238#[indefinite("for-generate statement")]
2239#[derive(Debug, Clone, PartialEq, Eq)]
2240pub struct GenerateFor<'a> {
2241    pub init: Stmt<'a>,
2242    pub cond: Expr<'a>,
2243    pub step: Expr<'a>,
2244    pub block: GenerateBlock<'a>,
2245}
2246
2247/// An `if` generate statement.
2248#[moore_derive::node]
2249#[indefinite("if-generate statement")]
2250#[derive(Debug, Clone, PartialEq, Eq)]
2251pub struct GenerateIf<'a> {
2252    pub cond: Expr<'a>,
2253    pub main_block: GenerateBlock<'a>,
2254    pub else_block: Option<GenerateBlock<'a>>,
2255}
2256
2257/// A `case` generate statement.
2258#[moore_derive::node]
2259#[indefinite("case-generate statement")]
2260#[derive(Debug, Clone, PartialEq, Eq)]
2261pub struct GenerateCase {
2262    // TODO
2263}
2264
2265/// A body of a generate construct.
2266///
2267/// May contains hierarchy items or more generate constructs.
2268#[moore_derive::node]
2269#[indefinite("generate block")]
2270#[derive(Debug, Clone, PartialEq, Eq)]
2271pub struct GenerateBlock<'a> {
2272    pub label: Option<Spanned<Name>>,
2273    pub items: Vec<Item<'a>>,
2274}
2275
2276#[moore_derive::visit]
2277#[derive(Debug, Clone, PartialEq, Eq)]
2278pub struct ParamAssignment<'a> {
2279    pub span: Span,
2280    pub name: Option<Identifier>,
2281    pub expr: TypeOrExpr<'a>,
2282}
2283
2284/// A port connection in an instantiation.
2285///
2286/// For example:
2287/// ```verilog
2288/// foo bar (
2289///     .*,
2290///     .name,
2291///     .name(),
2292///     .name(expr),
2293///     expr,
2294/// );
2295/// ```
2296#[moore_derive::node]
2297#[indefinite("port connection")]
2298#[derive(Debug, Clone, PartialEq, Eq)]
2299pub enum PortConn<'a> {
2300    /// The `.*` case,
2301    Auto,
2302    /// The `.name`, `.name()`, or `.name(expr)` cases,
2303    Named(#[name] Spanned<Name>, PortConnMode<'a>),
2304    /// The `expr` case,
2305    Positional(Expr<'a>),
2306}
2307
2308/// How a named port connection is made.
2309#[moore_derive::visit]
2310#[derive(Debug, Clone, PartialEq, Eq)]
2311pub enum PortConnMode<'a> {
2312    /// The `.name` case.
2313    Auto,
2314    /// The `.name()` case.
2315    Unconnected,
2316    /// The `.name(expr)` case.
2317    Connected(Expr<'a>),
2318}
2319
2320/// A DPI declaration such as `import "DPI-C"` or `export "DPI-C"`.
2321#[moore_derive::node]
2322#[indefinite("DPI declaration")]
2323#[derive(Debug, Clone, PartialEq, Eq)]
2324pub enum DpiDecl<'a> {
2325    /// An `import`.
2326    Import {
2327        spec: Spanned<Name>,
2328        property: Option<Spanned<DpiProperty>>,
2329        cident: Option<Spanned<Name>>,
2330        #[forward]
2331        prototype: SubroutinePrototype<'a>,
2332    },
2333    /// An `export`.
2334    Export {
2335        spec: Spanned<Name>,
2336        cident: Option<Spanned<Name>>,
2337        kind: SubroutineKind,
2338        #[name]
2339        name: Spanned<Name>,
2340    },
2341}
2342
2343/// A DPI function/task property.
2344#[moore_derive::visit]
2345#[derive(Debug, Clone, PartialEq, Eq)]
2346pub enum DpiProperty {
2347    /// `context`
2348    Context,
2349    /// `pure`
2350    Pure,
2351}
2352
2353/// A data type.
2354///
2355/// From §A.2.2.1 (extended to be context-free):
2356/// ```text
2357/// data_type ::=
2358///     integer_vector_type signing? packed_dimension*
2359///     integer_atom_type signing?
2360///     non_integer_type
2361///     ("struct"|"union") ("packed" signing?)? "{" struct_union_member+ "}" packed_dimension*
2362///     "enum" enum_base_type? "{" enum_name_declaration ("," enum_name_declaration)* "}" packed_dimension*
2363///     "string"
2364///     "chandle"
2365///     path_segment ("::" path_segment)* packed_dimension*
2366///     "event"
2367///     type_reference
2368///
2369/// path_segment ::=
2370///     "$unit"
2371///     package_identifier
2372///     class_identifier (param_value_assignment)?
2373///     type_identifier
2374/// ```
2375#[moore_derive::node]
2376#[indefinite("data type")]
2377#[derive(Debug, Clone, PartialEq, Eq)]
2378pub enum DataType<'a> {
2379    /// An integer type, like `bit`, `logic signed`, `reg signed [42:0]`, `int`,
2380    /// or `int unsigned`.
2381    #[indefinite("integer type")]
2382    Int {
2383        ty: Spanned<IntType>,
2384        signing: Option<TypeSign>,
2385        packed_dims: Vec<PackedDim<'a>>,
2386    },
2387    /// A real type.
2388    #[indefinite("real type")]
2389    Real(RealType),
2390    /// A struct or union type.
2391    #[indefinite("struct/union type")]
2392    Struct {
2393        def: Struct<'a>,
2394        packed_dims: Vec<PackedDim<'a>>,
2395    },
2396    /// An enum type.
2397    #[indefinite("enum type")]
2398    Enum {
2399        def: Enum<'a>,
2400        packed_dims: Vec<PackedDim<'a>>,
2401    },
2402    /// A `string`.
2403    #[indefinite("`string` type")]
2404    String,
2405    /// A `chandle`.
2406    #[indefinite("`chandle` type")]
2407    Chandle,
2408    /// A named type.
2409    #[indefinite("named type")]
2410    Named {
2411        path: Vec<PathSegment<'a>>,
2412        packed_dims: Vec<PackedDim<'a>>,
2413    },
2414    /// An `event`.
2415    #[indefinite("`event` type")]
2416    Event,
2417    /// A type reference, like `type(<type>)` or `type(<expr>)`.
2418    #[indefinite("type reference")]
2419    TypeRef(Box<TypeOrExpr<'a>>),
2420}
2421
2422/// An integer type.
2423#[moore_derive::visit]
2424#[derive(Debug, Clone, PartialEq, Eq)]
2425pub enum IntType {
2426    /// A `bit`.
2427    Bit,
2428    /// A `logic`.
2429    Logic,
2430    /// A `reg`.
2431    Reg,
2432    /// A `byte`.
2433    Byte,
2434    /// A `shortint`.
2435    ShortInt,
2436    /// An `int`.
2437    Int,
2438    /// A `longint`.
2439    LongInt,
2440    /// An `integer`.
2441    Integer,
2442    /// A `time`.
2443    Time,
2444}
2445
2446/// A real type.
2447#[moore_derive::visit]
2448#[derive(Debug, Clone, PartialEq, Eq)]
2449pub enum RealType {
2450    /// A `shortreal`.
2451    ShortReal,
2452    /// A `real`.
2453    Real,
2454    /// A `realtime`.
2455    RealTime,
2456}
2457
2458/// An implicit data type.
2459///
2460/// From §A.2.2.1:
2461/// ```text
2462/// implicit_data_type ::=
2463///     signing? packed_dimension*
2464/// ```
2465#[moore_derive::node]
2466#[indefinite("implicit data type")]
2467#[derive(Debug, Clone, PartialEq, Eq)]
2468pub struct ImplicitDataType<'a> {
2469    pub signing: Option<TypeSign>,
2470    pub packed_dims: Vec<PackedDim<'a>>,
2471}
2472
2473/// A possible implicit data type.
2474///
2475/// From §A.2.2.1:
2476/// ```text
2477/// data_type_or_implicit ::=
2478///     data_type
2479///     implicit_data_type
2480/// ```
2481#[moore_derive::visit]
2482#[derive(Debug, Clone, PartialEq, Eq)]
2483pub enum DataTypeOrImplicit<'a> {
2484    /// An explicit data type.
2485    Explicit(DataType<'a>),
2486    /// An implicit data type.
2487    Implicit(ImplicitDataType<'a>),
2488}
2489
2490/// A variable dimension.
2491///
2492/// From §A.2.5:
2493/// ```text
2494/// unsized_dimension
2495/// unpacked_dimension
2496/// associative_dimension
2497/// queue_dimension
2498/// ```
2499#[moore_derive::node]
2500#[indefinite("variable dimension")]
2501#[derive(Debug, Clone, PartialEq, Eq)]
2502pub enum VarDim<'a> {
2503    /// An unsized dimension, like `[]`.
2504    Unsized,
2505    /// An unpacked dimension.
2506    Unpacked(UnpackedDim<'a>),
2507    /// An associative dimension, like `[<type>]` or `[*]`.
2508    Assoc(Option<Type<'a>>),
2509    /// A queue dimension, like `[$]` or `[$:42]`.
2510    Queue(Option<Expr<'a>>),
2511}
2512
2513/// A packed dimension.
2514///
2515/// From §A.2.5:
2516/// ```text
2517/// "[" constant_range "]"
2518/// unsized_dimension
2519/// ```
2520#[moore_derive::node]
2521#[indefinite("packed dimension")]
2522#[derive(Debug, Clone, PartialEq, Eq)]
2523pub enum PackedDim<'a> {
2524    /// Such as `[41:0]`.
2525    Range(Expr<'a>, Expr<'a>),
2526    /// Such as `[]`.
2527    Unsized,
2528}
2529
2530/// An unpacked dimension.
2531///
2532/// From §A.2.5:
2533/// ```text
2534/// "[" constant_range "]"
2535/// "[" constant_expression "]"
2536/// ```
2537#[moore_derive::node]
2538#[indefinite("unpacked dimension")]
2539#[derive(Debug, Clone, PartialEq, Eq)]
2540pub enum UnpackedDim<'a> {
2541    /// Such as `[41:0]`.
2542    Range(Expr<'a>, Expr<'a>),
2543    /// Such as `[42]`.
2544    Expr(Expr<'a>),
2545}
2546
2547/// A segment of a type name.
2548///
2549/// Adapted from §A.2.2.1:
2550/// ```text
2551/// path_segment ::=
2552///     "$unit"
2553///     package_identifier
2554///     class_identifier (param_value_assignment)?
2555///     type_identifier
2556///     covergroup_identifier
2557/// ```
2558#[moore_derive::node]
2559#[indefinite("type name segment")]
2560#[derive(Debug, Clone, PartialEq, Eq)]
2561pub enum PathSegment<'a> {
2562    /// A `$unit`.
2563    Unit,
2564    /// A package, type, covergroup, or class identifier.
2565    Ident(Spanned<Name>),
2566    /// A class identifier with specializations.
2567    Class(Spanned<Name>, Vec<ParamAssignment<'a>>),
2568}
2569
2570moore_derive::derive_visitor!(
2571    /// Called for every node before visiting its children.
2572    ///
2573    /// Return `false` from this function to not visit the node's children.
2574    fn pre_visit_node(&mut self, node: &'a dyn AnyNode<'a>) -> bool {
2575        true
2576    }
2577
2578    /// Called for every node after visiting its children.
2579    fn post_visit_node(&mut self, node: &'a dyn AnyNode<'a>) {}
2580);
2581moore_derive::derive_all_node!();
2582moore_derive::derive_arena!();