#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EventLevel {
Info,
Advisory,
Warning,
}
#[derive(Debug, Clone)]
pub enum CompileEvent {
Parsed { statements: usize },
BindingResolved { name: String, node_type: String },
ModuleInlined { name: String, nodes_added: usize },
LegacyTranslated { name: String, gk_expr: String },
TypeAdapterInserted { from_node: String, to_node: String, adapter: String },
ConstantFolded { node: String, value: String },
FusionApplied { pattern: String, nodes_replaced: usize },
OutputDeclared { name: String },
CompileLevelSelected { node: String, level: String },
ParamInjected { name: String, value: String },
ConfigWireCycleWarning { node: String, port: String },
TypeWidening { from: &'static str, to: &'static str, context: String },
Warning { message: String },
Summary { nodes: usize, outputs: usize, constants_folded: usize },
PragmaAcknowledged { name: String, line: usize },
UnknownPragma { name: String, line: usize },
AssertionInserted {
from_node: String,
to_node: String,
kind: String,
},
AssertionSkipped {
from_node: String,
to_node: String,
reason: String,
},
}
impl CompileEvent {
pub fn level(&self) -> EventLevel {
match self {
CompileEvent::Parsed { .. } => EventLevel::Info,
CompileEvent::BindingResolved { .. } => EventLevel::Info,
CompileEvent::ModuleInlined { .. } => EventLevel::Info,
CompileEvent::OutputDeclared { .. } => EventLevel::Info,
CompileEvent::CompileLevelSelected { .. } => EventLevel::Info,
CompileEvent::ParamInjected { .. } => EventLevel::Info,
CompileEvent::ConstantFolded { .. } => EventLevel::Info,
CompileEvent::FusionApplied { .. } => EventLevel::Info,
CompileEvent::Summary { .. } => EventLevel::Info,
CompileEvent::TypeAdapterInserted { .. } => EventLevel::Advisory,
CompileEvent::TypeWidening { .. } => EventLevel::Advisory,
CompileEvent::LegacyTranslated { .. } => EventLevel::Advisory,
CompileEvent::PragmaAcknowledged { .. } => EventLevel::Advisory,
CompileEvent::AssertionInserted { .. } => EventLevel::Advisory,
CompileEvent::AssertionSkipped { .. } => EventLevel::Advisory,
CompileEvent::ConfigWireCycleWarning { .. } => EventLevel::Warning,
CompileEvent::Warning { .. } => EventLevel::Warning,
CompileEvent::UnknownPragma { .. } => EventLevel::Warning,
}
}
}
#[derive(Debug, Default)]
pub struct CompileEventLog {
events: Vec<CompileEvent>,
}
impl CompileEventLog {
pub fn new() -> Self {
Self { events: Vec::new() }
}
pub fn push(&mut self, event: CompileEvent) {
self.events.push(event);
}
pub fn events(&self) -> &[CompileEvent] {
&self.events
}
pub fn is_empty(&self) -> bool {
self.events.is_empty()
}
pub fn advisories(&self) -> Vec<&CompileEvent> {
self.events.iter().filter(|e| e.level() == EventLevel::Advisory).collect()
}
pub fn warnings(&self) -> Vec<&CompileEvent> {
self.events.iter().filter(|e| e.level() == EventLevel::Warning).collect()
}
pub fn format(&self) -> String {
self.events.iter().map(|e| {
let tag = match e.level() {
EventLevel::Info => "info",
EventLevel::Advisory => "advisory",
EventLevel::Warning => "warning",
};
let msg = match e {
CompileEvent::Parsed { statements } =>
format!("parsed {statements} statement(s)"),
CompileEvent::BindingResolved { name, node_type } =>
format!("resolved '{name}' → {node_type}"),
CompileEvent::ModuleInlined { name, nodes_added } =>
format!("module '{name}' inlined ({nodes_added} nodes)"),
CompileEvent::LegacyTranslated { name, gk_expr } =>
format!("legacy '{name}' → {gk_expr}"),
CompileEvent::TypeAdapterInserted { from_node, to_node, adapter } =>
format!("type adapter {adapter}: {from_node} → {to_node}"),
CompileEvent::ConstantFolded { node, value } =>
format!("constant folded: {node} → {value}"),
CompileEvent::FusionApplied { pattern, nodes_replaced } =>
format!("fusion: {pattern} ({nodes_replaced} nodes replaced)"),
CompileEvent::OutputDeclared { name } =>
format!("output '{name}'"),
CompileEvent::CompileLevelSelected { node, level } =>
format!("{node} → {level}"),
CompileEvent::ParamInjected { name, value } =>
format!("param '{name}' = {value}"),
CompileEvent::ConfigWireCycleWarning { node, port } =>
format!("config wire '{port}' on '{node}' connected to cycle-time source"),
CompileEvent::TypeWidening { from, to, context } =>
format!("widening {from} → {to} in {context}"),
CompileEvent::Warning { message } =>
format!("{message}"),
CompileEvent::Summary { nodes, outputs, constants_folded } =>
format!("{nodes} nodes, {outputs} outputs, {constants_folded} constant(s) folded"),
CompileEvent::PragmaAcknowledged { name, line } =>
format!("pragma '{name}' acknowledged (line {line})"),
CompileEvent::UnknownPragma { name, line } =>
format!("unknown pragma '{name}' at line {line}; ignored"),
CompileEvent::AssertionInserted { from_node, to_node, kind } =>
format!("assertion inserted: {from_node} → {to_node} ({kind})"),
CompileEvent::AssertionSkipped { from_node, to_node, reason } =>
format!("assertion skipped: {from_node} → {to_node} ({reason})"),
};
format!("gk[{tag}]: {msg}")
}).collect::<Vec<_>>().join("\n")
}
}