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