mech_set/operations/
intersection.rs1
2use crate::*;
3
4use indexmap::set::IndexSet;
5use mech_core::set::MechSet;
6
7#[derive(Debug)]
10struct SetIntersectionFxn {
11 lhs: Ref<MechSet>,
12 rhs: Ref<MechSet>,
13 out: Ref<MechSet>,
14}
15impl MechFunctionFactory for SetIntersectionFxn {
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<MechSet> = unsafe { out.as_unchecked() }.clone();
22 Ok(Box::new(SetIntersectionFxn {lhs, rhs, out }))
23 },
24 _ => Err(MechError2::new(IncorrectNumberOfArguments { expected: 2, found: args.len() }, None).with_compiler_loc()),
25 }
26 }
27}
28impl MechFunctionImpl for SetIntersectionFxn {
29 fn solve(&self) {
30 unsafe {
31 let out_ptr: &mut MechSet = &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.set.clear();
40
41 out_ptr.set = lhs_ptr.set.intersection(&(rhs_ptr.set)).cloned().collect();
43
44 out_ptr.num_elements = out_ptr.set.len();
46 out_ptr.kind = if out_ptr.set.len() > 0 {
47 out_ptr.set.iter().next().unwrap().kind()
48 } else {
49 ValueKind::Empty
50 };
51 }
52 }
53 fn out(&self) -> Value { Value::Set(self.out.clone()) }
54 fn to_string(&self) -> String { format!("{:#?}", self) }
55}
56#[cfg(feature = "compiler")]
57impl MechFunctionCompiler for SetIntersectionFxn {
58 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
59 let name = format!("SetIntersectionFxn");
60 compile_binop!(name, self.out, self.lhs, self.rhs, ctx, FeatureFlag::Builtin(FeatureKind::Intersection) );
61 }
62}
63register_descriptor! {
64 FunctionDescriptor {
65 name: "SetIntersectionFxn",
66 ptr: SetIntersectionFxn::new,
67 }
68}
69
70fn set_intersection_fxn(lhs: Value, rhs: Value) -> MResult<Box<dyn MechFunction>> {
71 match (lhs, rhs) {
72 (Value::Set(lhs), Value::Set(rhs)) => {
73 Ok(Box::new(SetIntersectionFxn { lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new(MechSet::new(lhs.borrow().kind.clone(), lhs.borrow().num_elements + rhs.borrow().num_elements)) }))
74 },
75 x => Err(MechError2::new(
76 UnhandledFunctionArgumentKind2 { arg: (x.0.kind(), x.1.kind()), fxn_name: "set/intersection".to_string() },
77 None
78 ).with_compiler_loc()),
79 }
80}
81
82pub struct SetIntersection {}
83impl NativeFunctionCompiler for SetIntersection {
84 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
85 if arguments.len() != 2 {
86 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 2, found: arguments.len() }, None).with_compiler_loc());
87 }
88 let lhs = arguments[0].clone();
89 let rhs = arguments[1].clone();
90 match set_intersection_fxn(lhs.clone(),rhs.clone()) {
91 Ok(fxn) => Ok(fxn),
92 Err(x) => {
93 match (lhs,rhs) {
94 (Value::MutableReference(lhs),Value::MutableReference(rhs)) => { set_intersection_fxn(lhs.borrow().clone(),rhs.borrow().clone()) },
95 (lhs,Value::MutableReference(rhs)) => { set_intersection_fxn(lhs.clone(),rhs.borrow().clone()) },
96 (Value::MutableReference(lhs),rhs) => { set_intersection_fxn(lhs.borrow().clone(),rhs.clone()) },
97 x => Err(MechError2::new(
98 UnhandledFunctionArgumentKind2 { arg: (x.0.kind(), x.1.kind()), fxn_name: "set/intersection".to_string() },
99 None
100 ).with_compiler_loc()),
101 }
102 }
103 }
104 }
105}
106
107register_descriptor! {
108 FunctionCompilerDescriptor {
109 name: "set/intersection",
110 ptr: &SetIntersection{},
111 }
112}