use crate::{eval::*, lower::ir};
impl Eval for ir::TupleExpression {
fn eval(&self, context: &mut EvalContext) -> EvalResult<Value> {
let (unnamed, named): (Vec<_>, _) = Eval::<ArgumentValueList>::eval(&self.args, context)?
.iter()
.map(|(id, arg)| (id.clone(), arg.value.clone()))
.partition(|(id, _)| id.is_empty());
let mut h = microcad_core::hash::HashSet::default();
unnamed
.iter()
.map(|(_, value)| value.ty())
.try_for_each(|ty| {
if h.insert(ty.clone()) {
Ok(())
} else {
Err(Box::new(EvalError::AmbiguousType {
ty,
src_ref: self.src_ref.clone(),
}))
}
})?;
Ok(Value::Tuple(
Tuple {
named: named.into_iter().collect(),
unnamed: unnamed.into_iter().map(|(_, v)| (v.ty(), v)).collect(),
src_ref: self.src_ref.clone(),
}
.into(),
))
}
}