use sim_kernel::{
Cx, Expr, Factory, Linker, NumberBinaryOp, NumberLiteral, NumberReductionOp, NumberUnaryOp,
Symbol, Value, ValueNumberBinaryOp, ValueNumberReductionOp, ValueNumberUnaryOp,
};
pub fn number_domain_class_stub(cx: &mut Cx) -> sim_kernel::Result<sim_kernel::ClassRef> {
if let Some(value) = cx
.registry()
.class_by_symbol(&Symbol::qualified("core", "NumberDomain"))
{
return Ok(value.clone());
}
sim_kernel::DefaultFactory.class_stub(
sim_kernel::CORE_NUMBER_DOMAIN_CLASS_ID,
Symbol::qualified("core", "NumberDomain"),
)
}
use crate::domains;
pub trait ScalarLiteralMatcher {
fn matches_expr(&self, expr: &Expr) -> bool;
}
pub struct DomainLiteralMatcher {
domain: Symbol,
}
impl DomainLiteralMatcher {
pub fn new(domain: Symbol) -> Self {
Self { domain }
}
pub fn domain(&self) -> &Symbol {
&self.domain
}
}
impl ScalarLiteralMatcher for DomainLiteralMatcher {
fn matches_expr(&self, expr: &Expr) -> bool {
matches!(expr, Expr::Number(number) if number.domain == self.domain)
}
}
pub struct ScalarDomainSpec {
pub domain: Symbol,
pub numeric_family: &'static str,
pub canonical_form: &'static str,
pub parse_priority: i32,
}
impl ScalarDomainSpec {
pub fn matcher(&self) -> DomainLiteralMatcher {
DomainLiteralMatcher::new(self.domain.clone())
}
pub fn literal_class_symbol(&self) -> Symbol {
domains::literal_class(self.canonical_form)
}
pub fn literal_instance_shape_symbol(&self) -> Symbol {
Symbol::qualified(self.literal_class_symbol().to_string(), "instance-shape")
}
}
pub struct ScalarBinaryOp {
pub operator: Symbol,
pub literal_cost: u16,
pub literal_apply: fn(&mut Cx, NumberLiteral, NumberLiteral) -> sim_kernel::Result<Value>,
pub value_cost: u16,
pub value_apply: fn(&mut Cx, Value, Value) -> sim_kernel::Result<Value>,
}
pub struct ScalarUnaryOp {
pub operator: Symbol,
pub literal_cost: u16,
pub literal_apply: fn(&mut Cx, NumberLiteral) -> sim_kernel::Result<Value>,
pub value_cost: u16,
pub value_apply: fn(&mut Cx, Value) -> sim_kernel::Result<Value>,
}
pub struct ScalarReductionOp {
pub operator: Symbol,
pub literal_cost: u16,
pub literal_apply: fn(&mut Cx, Vec<NumberLiteral>) -> sim_kernel::Result<Value>,
pub value_cost: u16,
pub value_apply: fn(&mut Cx, Vec<Value>) -> sim_kernel::Result<Value>,
}
pub struct ScalarOps {
pub domain: Symbol,
pub binary: Vec<ScalarBinaryOp>,
pub unary: Vec<ScalarUnaryOp>,
pub reduction: Vec<ScalarReductionOp>,
}
pub fn install_scalar_ops(linker: &mut Linker<'_>, ops: &ScalarOps) {
for op in &ops.binary {
linker.number_binary_op(NumberBinaryOp {
operator: op.operator.clone(),
left_domain: ops.domain.clone(),
right_domain: ops.domain.clone(),
cost: op.literal_cost,
apply: op.literal_apply,
});
linker.value_number_binary_op(ValueNumberBinaryOp {
operator: op.operator.clone(),
left_domain: ops.domain.clone(),
right_domain: ops.domain.clone(),
cost: op.value_cost,
apply: op.value_apply,
});
}
for op in &ops.unary {
linker.number_unary_op(NumberUnaryOp {
operator: op.operator.clone(),
operand_domain: ops.domain.clone(),
cost: op.literal_cost,
apply: op.literal_apply,
});
linker.value_number_unary_op(ValueNumberUnaryOp {
operator: op.operator.clone(),
operand_domain: ops.domain.clone(),
cost: op.value_cost,
apply: op.value_apply,
});
}
for op in &ops.reduction {
linker.number_reduction_op(NumberReductionOp {
operator: op.operator.clone(),
operand_domain: ops.domain.clone(),
cost: op.literal_cost,
apply: op.literal_apply,
});
linker.value_number_reduction_op(ValueNumberReductionOp {
operator: op.operator.clone(),
operand_domain: ops.domain.clone(),
cost: op.value_cost,
apply: op.value_apply,
});
}
}