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