///|
/// Return the referenced name when an expression is a plain name.
pub fn Expression::name_text(self : Expression) -> String? {
match self {
Name(name, _) => Some(name)
_ => None
}
}
///|
/// Return whether an expression contains a reference to a name.
pub fn Expression::contains_name(self : Expression, wanted : String) -> Bool {
match self {
Name(name, _) => name == wanted
Unary(_, operand, _) => operand.contains_name(wanted)
Binary(left, _, right, _) =>
left.contains_name(wanted) || right.contains_name(wanted)
Index(base, index, _) =>
base.contains_name(wanted) || index.contains_name(wanted)
Number(_, _) | StringLiteral(_, _) | Unknown(_) => false
}
}
///|
/// Count expression nodes in source order.
pub fn Expression::node_count(self : Expression) -> Int {
match self {
Name(_, _) | Number(_, _) | StringLiteral(_, _) | Unknown(_) => 1
Unary(_, operand, _) => 1 + operand.node_count()
Binary(left, _, right, _) => 1 + left.node_count() + right.node_count()
Index(base, index, _) => 1 + base.node_count() + index.node_count()
}
}
///|
/// Count statements recursively, including block and branch nodes.
pub fn Statement::node_count(self : Statement) -> Int {
match self {
Empty(_) | Unknown(_) => 1
Assignment(target, value, _, _) =>
1 + target.node_count() + value.node_count()
Block(statements, _) => {
let mut count = 1
for statement in statements {
count += statement.node_count()
}
count
}
If(condition, then_branch, else_branch, _) => {
let mut count = 1 + condition.node_count() + then_branch.node_count()
match else_branch {
Some(branch) => count += branch.node_count()
None => ()
}
count
}
Case(expression, arms, _) => {
let mut count = 1 + expression.node_count()
for arm in arms {
count += arm.body.node_count()
for choice in arm.choices {
count += choice.node_count()
}
}
count
}
}
}
///|
/// Find a port by name without exposing the representation to callers.
pub fn Module::find_port(self : Module, name : String) -> Port? {
for port in self.ports {
if port.name == name {
return Some(port)
}
}
None
}
///|
/// Find a declared signal by name.
pub fn Module::find_signal(self : Module, name : String) -> Signal? {
for signal in self.signals {
if signal.name == name {
return Some(signal)
}
}
None
}
///|
/// Return instance names in declaration order.
pub fn Module::instance_names(self : Module) -> Array[String] {
let names : Array[String] = []
for item in self.items {
match item {
Instance(instance) => names.push(instance.instance_name)
_ => ()
}
}
names
}
///|
/// Return module names in declaration order.
pub fn Design::module_names(self : Design) -> Array[String] {
let names : Array[String] = []
for mod in self.modules {
names.push(mod.name)
}
names
}
///|
/// Find a module in a design by name.
pub fn Design::find_module(self : Design, name : String) -> Module? {
for mod in self.modules {
if mod.name == name {
return Some(mod)
}
}
None
}
///|
/// Count module items across a design.
pub fn Design::item_count(self : Design) -> Int {
let mut count = 0
for mod in self.modules {
count += mod.items.length()
}
count
}