use super::*;
use itertools::Itertools as _;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DynamicOpExpression {
pub interface: Type,
pub target_program: Expression,
pub network: Option<Expression>,
pub kind: DynamicOpKind,
pub span: Span,
pub id: NodeID,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum DynamicOpKind {
Call { function: Identifier, arguments: Vec<Expression> },
Read { storage: Identifier },
Op { member: Identifier, op: Identifier, arguments: Vec<Expression> },
}
impl fmt::Display for DynamicOpExpression {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let target = if let Some(network) = &self.network {
format!("({}, {})", self.target_program, network)
} else {
format!("({})", self.target_program)
};
match &self.kind {
DynamicOpKind::Call { function, arguments } => {
write!(f, "{}@{}::{}({})", self.interface, target, function, arguments.iter().format(", "))
}
DynamicOpKind::Read { storage } => {
write!(f, "{}@{}::{}", self.interface, target, storage)
}
DynamicOpKind::Op { member, op, arguments } => {
write!(f, "{}@{}::{}.{}({})", self.interface, target, member, op, arguments.iter().format(", "))
}
}
}
}
impl From<DynamicOpExpression> for Expression {
fn from(value: DynamicOpExpression) -> Self {
Expression::DynamicOp(Box::new(value))
}
}
crate::simple_node_impl!(DynamicOpExpression);