use crate::lower::ir;
use derive_more::{Deref, DerefMut};
use microcad_lang_base::{SrcRef, SrcReferrer};
use microcad_lang_proc_macros::SrcReferrer;
#[derive(Clone, Debug, PartialEq)]
pub enum ArrayExpressionInner {
List(ir::ListExpression),
Range(ir::RangeExpression),
}
impl Default for ArrayExpressionInner {
fn default() -> Self {
Self::List(Default::default())
}
}
impl std::fmt::Display for ArrayExpressionInner {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match &self {
ArrayExpressionInner::List(expressions) => expressions
.iter()
.map(|c| c.to_string())
.collect::<Vec<_>>()
.join(", "),
ArrayExpressionInner::Range(range_expression) => range_expression.to_string(),
}
)
}
}
impl SrcReferrer for ArrayExpressionInner {
fn src_ref(&self) -> SrcRef {
match &self {
ArrayExpressionInner::List(expressions) => SrcRef::merge(
&expressions
.first()
.map(|start| start.src_ref())
.unwrap_or_default(),
&expressions
.last()
.map(|end| end.src_ref())
.unwrap_or_default(),
),
ArrayExpressionInner::Range(range_expression) => range_expression.src_ref(),
}
}
}
#[derive(Default, Clone, Debug, Deref, DerefMut, PartialEq, SrcReferrer)]
pub struct ArrayExpression {
#[deref]
#[deref_mut]
pub inner: ArrayExpressionInner,
pub unit: ir::Unit,
pub src_ref: SrcRef,
}
impl std::fmt::Display for ArrayExpression {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "[{}]{}", self.inner, self.unit)
}
}