microcad-lang 0.5.0

µcad language
Documentation
// Copyright © 2025-2026 The µcad authors <info@microcad.xyz>
// SPDX-License-Identifier: AGPL-3.0-or-later

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());

        // check unnamed for ambiguous types
        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(),
        ))
    }
}