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