///|
pub(all) enum Width {
Known(Int)
Unknown
} derive(Eq, Debug)
///|
pub(all) enum DriveKind {
Continuous
Procedural
InstanceOutput
} derive(Eq, Debug)
///|
pub(all) struct Drive {
kind : DriveKind
span : @source.Span
} derive(Eq, Debug)
///|
pub(all) struct SignalInfo {
name : String
net_type : @syntax.NetType
width : Width
declaration_span : @source.Span
from_port : Bool
drivers : Array[Drive]
} derive(Debug)
///|
pub fn SignalInfo::has_driver(self : SignalInfo) -> Bool {
self.drivers.length() > 0
}
///|
pub(all) struct InstanceInfo {
module_name : String
instance_name : String
span : @source.Span
} derive(Eq, Debug)
///|
pub(all) struct ModuleInfo {
name : String
ports : Array[@syntax.Port]
signals : Array[SignalInfo]
instances : Array[InstanceInfo]
span : @source.Span
} derive(Debug)
///|
pub fn ModuleInfo::signal(self : ModuleInfo, name : String) -> SignalInfo? {
for signal in self.signals {
if signal.name == name {
return Some(signal)
}
}
None
}
///|
pub(all) struct SemanticIssue {
code : String
message : String
span : @source.Span
} derive(Eq, Debug)
///|
pub(all) struct DependencyGraph {
edge_list : Array[(String, String)]
} derive(Eq, Debug)
///|
pub fn DependencyGraph::edges(
self : DependencyGraph,
) -> Array[(String, String)] {
self.edge_list
}
///|
pub(all) struct SemanticIndex {
modules : Array[ModuleInfo]
graph : DependencyGraph
issues : Array[SemanticIssue]
syntax_modules : Array[@syntax.Module]
} derive(Debug)
///|
pub fn SemanticIndex::find_module(
self : SemanticIndex,
name : String,
) -> ModuleInfo? {
for mod in self.modules {
if mod.name == name {
return Some(mod)
}
}
None
}
///|
pub fn SemanticIndex::drivers(
self : SemanticIndex,
module_name : String,
signal_name : String,
) -> Array[Drive] {
match self.find_module(module_name) {
Some(mod) =>
match mod.signal(signal_name) {
Some(signal) => signal.drivers
None => []
}
None => []
}
}
///|
pub fn SemanticIndex::width_of(
self : SemanticIndex,
module_name : String,
signal_name : String,
) -> Width {
match self.find_module(module_name) {
Some(mod) =>
match mod.signal(signal_name) {
Some(signal) => signal.width
None => Unknown
}
None => Unknown
}
}