mod parameter_value;
mod parameter_value_list;
pub use parameter_value::ParameterValue;
pub use parameter_value_list::ParameterValueList;
use microcad_lang_base::SrcReferrer;
use crate::{eval::*, lower::ir, ty::*, value::*};
impl Eval<ParameterValue> for ir::Parameter {
fn eval(&self, context: &mut EvalContext) -> EvalResult<ParameterValue> {
use crate::lower::Identifiable;
match (&self.specified_type, &self.default_value) {
(Some(specified_type), Some(default_value)) => {
let default_value: Value = default_value.eval(context)?;
if specified_type.ty() != default_value.ty() {
context.error(
self,
EvalError::TypeMismatch {
id: self.id(),
expected: specified_type.ty(),
found: default_value.ty(),
},
)?;
Ok(ParameterValue::invalid(self.src_ref()))
} else {
Ok(ParameterValue {
specified_type: Some(specified_type.ty()),
default_value: Some(default_value),
src_ref: self.src_ref(),
})
}
}
(Some(t), None) => Ok(ParameterValue {
specified_type: Some(t.ty()),
src_ref: self.src_ref(),
..Default::default()
}),
(None, Some(expr)) => {
let default_value: Value = expr.eval(context)?;
Ok(ParameterValue {
specified_type: Some(default_value.ty().clone()),
default_value: Some(default_value),
src_ref: self.src_ref(),
})
}
(None, None) => Ok(ParameterValue::invalid(self.src_ref())),
}
}
}
impl Eval<ParameterValueList> for ir::ParameterList {
fn eval(&self, context: &mut EvalContext) -> EvalResult<ParameterValueList> {
use crate::lower::Identifiable;
let mut values = ParameterValueList::default();
for parameter in self.iter() {
values.insert(parameter.id(), parameter.eval(context)?)?;
}
Ok(values)
}
}