use crate::ir::ast::{Causality, Component, Connection, Expression, Variability};
use super::FormatVisitor;
impl FormatVisitor {
pub fn component_has_individual_attrs(&self, comp: &Component) -> bool {
if !comp.modifications.is_empty() {
return true;
}
if !comp.description.is_empty() {
return true;
}
if !comp.annotation.is_empty() {
return true;
}
if comp.condition.is_some() {
return true;
}
if comp.inner || comp.outer {
return true;
}
if comp.start_is_modification && !matches!(comp.start, Expression::Empty) {
return true;
}
if !comp.start_is_modification {
if let Expression::Terminal { token, .. } = &comp.start {
if token.location.start_line > 0 {
return true;
}
} else if !matches!(comp.start, Expression::Empty)
&& comp.start.get_location().is_some_and(|l| l.start_line > 0)
{
return true;
}
}
false
}
pub fn format_component_group(&self, components: &[&Component]) -> String {
if components.is_empty() {
return String::new();
}
let first = components[0];
let mut result = String::new();
match &first.variability {
Variability::Constant(_) => result.push_str("constant "),
Variability::Parameter(_) => result.push_str("parameter "),
Variability::Discrete(_) => result.push_str("discrete "),
Variability::Empty => {}
}
match &first.causality {
Causality::Input(_) => result.push_str("input "),
Causality::Output(_) => result.push_str("output "),
Causality::Empty => {}
}
match &first.connection {
Connection::Flow(_) => result.push_str("flow "),
Connection::Stream(_) => result.push_str("stream "),
Connection::Empty => {}
}
result.push_str(&first.type_name.to_string());
result.push(' ');
let names: Vec<String> = components
.iter()
.map(|comp| {
let mut name = comp.name.clone();
if !comp.shape_expr.is_empty() {
let dims: Vec<String> = comp
.shape_expr
.iter()
.map(|s| self.format_subscript(s))
.collect();
name.push_str(&format!("[{}]", dims.join(", ")));
} else if !comp.shape.is_empty() {
let dims: Vec<String> = comp.shape.iter().map(|d| d.to_string()).collect();
name.push_str(&format!("[{}]", dims.join(", ")));
}
name
})
.collect();
result.push_str(&names.join(", "));
result.push(';');
result
}
pub fn format_component(&self, comp: &Component) -> String {
let mut result = String::new();
if comp.inner {
result.push_str("inner ");
}
if comp.outer {
result.push_str("outer ");
}
match &comp.variability {
Variability::Constant(_) => result.push_str("constant "),
Variability::Parameter(_) => result.push_str("parameter "),
Variability::Discrete(_) => result.push_str("discrete "),
Variability::Empty => {}
}
match &comp.causality {
Causality::Input(_) => result.push_str("input "),
Causality::Output(_) => result.push_str("output "),
Causality::Empty => {}
}
match &comp.connection {
Connection::Flow(_) => result.push_str("flow "),
Connection::Stream(_) => result.push_str("stream "),
Connection::Empty => {}
}
result.push_str(&comp.type_name.to_string());
result.push(' ');
result.push_str(&comp.name);
if !comp.shape_expr.is_empty() {
let dims: Vec<String> = comp
.shape_expr
.iter()
.map(|s| self.format_subscript(s))
.collect();
result.push_str(&format!("[{}]", dims.join(", ")));
} else if !comp.shape.is_empty() {
let dims: Vec<String> = comp.shape.iter().map(|d| d.to_string()).collect();
result.push_str(&format!("[{}]", dims.join(", ")));
}
let has_start_mod = comp.start_is_modification && !matches!(comp.start, Expression::Empty);
if !comp.modifications.is_empty() || has_start_mod {
let mut mods: Vec<String> = Vec::new();
if has_start_mod {
let each_prefix = if comp.start_has_each { "each " } else { "" };
mods.push(format!(
"{}start = {}",
each_prefix,
self.format_expression(&comp.start)
));
}
for (k, v) in &comp.modifications {
mods.push(format!("{} = {}", k, self.format_expression(v)));
}
result.push_str(&format!("({})", mods.join(", ")));
}
if !comp.start_is_modification {
if let Expression::Terminal { token, .. } = &comp.start {
if token.location.start_line > 0 {
result.push_str(&format!(" = {}", self.format_expression(&comp.start)));
}
} else if !matches!(comp.start, Expression::Empty) {
if comp.start.get_location().is_some_and(|l| l.start_line > 0) {
result.push_str(&format!(" = {}", self.format_expression(&comp.start)));
}
}
}
if let Some(cond) = &comp.condition {
result.push_str(&format!(" if {}", self.format_expression(cond)));
}
if !comp.description.is_empty() {
let desc: Vec<String> = comp
.description
.iter()
.map(|t| format!("\"{}\"", t.text))
.collect();
result.push_str(&format!(" {}", desc.join(" ")));
}
if !comp.annotation.is_empty() {
let args: Vec<String> = comp
.annotation
.iter()
.map(|e| self.format_expression(e))
.collect();
result.push_str(&format!(" annotation({})", args.join(", ")));
}
result.push(';');
result
}
}