mech_set/relations/
subset.rs1
2use crate::*;
3
4use indexmap::set::IndexSet;
5use mech_core::set::MechSet;
6
7#[derive(Debug)]
10struct SetSubsetFxn {
11 lhs: Ref<MechSet>,
12 rhs: Ref<MechSet>,
13 out: Ref<bool>,
14}
15impl MechFunctionFactory for SetSubsetFxn {
16 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
17 match args {
18 FunctionArgs::Binary(out, arg1, arg2) => {
19 let lhs: Ref<MechSet> = unsafe { arg1.as_unchecked() }.clone();
20 let rhs: Ref<MechSet> = unsafe { arg2.as_unchecked() }.clone();
21 let out: Ref<bool> = unsafe { out.as_unchecked() }.clone();
22 Ok(Box::new(SetSubsetFxn {lhs, rhs, out }))
23 },
24 _ => Err(MechError2::new(IncorrectNumberOfArguments { expected: 2, found: args.len() }, None).with_compiler_loc()),
25 }
26 }
27}
28impl MechFunctionImpl for SetSubsetFxn {
29 fn solve(&self) {
30 unsafe {
31 let mut out_ptr: &mut bool = &mut *(self.out.as_mut_ptr());
33
34 let lhs_ptr: &MechSet = &*(self.lhs.as_ptr());
36 let rhs_ptr: &MechSet = &*(self.rhs.as_ptr());
37
38 *out_ptr = lhs_ptr.set.is_subset(&(rhs_ptr.set));
40 }
41 }
42 fn out(&self) -> Value { Value::Bool(self.out.clone()) }
43 fn to_string(&self) -> String { format!("{:#?}", self) }
44}
45#[cfg(feature = "compiler")]
46impl MechFunctionCompiler for SetSubsetFxn {
47 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
48 let name = format!("SetSubsetFxn");
49 compile_binop!(name, self.out, self.lhs, self.rhs, ctx, FeatureFlag::Builtin(FeatureKind::Subset) );
50 }
51}
52register_descriptor! {
53 FunctionDescriptor {
54 name: "SetSubsetFxn",
55 ptr: SetSubsetFxn::new,
56 }
57}
58
59fn set_subset_fxn(lhs: Value, rhs: Value) -> MResult<Box<dyn MechFunction>> {
60 match (lhs, rhs) {
61 (Value::Set(lhs), Value::Set(rhs)) => {
62 Ok(Box::new(SetSubsetFxn { lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new(false) }))
63 },
64 x => Err(MechError2::new(UnhandledFunctionArgumentKind2 {
65 arg: (x.0.kind(), x.1.kind()),
66 fxn_name: "set/subset".to_string(),
67 }, None).with_compiler_loc()),
68 }
69}
70
71pub struct SetSubset {}
72impl NativeFunctionCompiler for SetSubset {
73 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
74 if arguments.len() != 2 {
75 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 2, found: arguments.len() }, None).with_compiler_loc());
76 }
77 let lhs = arguments[0].clone();
78 let rhs = arguments[1].clone();
79 match set_subset_fxn(lhs.clone(),rhs.clone()) {
80 Ok(fxn) => Ok(fxn),
81 Err(x) => {
82 match (lhs,rhs) {
83 (Value::MutableReference(lhs),Value::MutableReference(rhs)) => { set_subset_fxn(lhs.borrow().clone(),rhs.borrow().clone()) },
84 (lhs,Value::MutableReference(rhs)) => { set_subset_fxn(lhs.clone(),rhs.borrow().clone()) },
85 (Value::MutableReference(lhs),rhs) => { set_subset_fxn(lhs.borrow().clone(),rhs.clone()) },
86 x => Err(MechError2::new(
87 UnhandledFunctionArgumentKind2 { arg: (x.0.kind(), x.1.kind()), fxn_name: "set/subset".to_string() },
88 None
89 ).with_compiler_loc()),
90 }
91 }
92 }
93 }
94}
95
96register_descriptor! {
97 FunctionCompilerDescriptor {
98 name: "set/subset",
99 ptr: &SetSubset{},
100 }
101}