Skip to main content

mech_compare/
neq.rs

1use crate::*;
2use mech_core::*;
3#[cfg(feature = "matrix")]
4use mech_core::matrix::Matrix;
5
6// Not Equal ---------------------------------------------------------------
7
8macro_rules! neq_scalar_lhs_op {
9  ($lhs:expr, $rhs:expr, $out:expr) => {
10    unsafe {
11      for i in 0..(*$lhs).len() {
12        (&mut (*$out))[i] = (&(*$lhs))[i] != (*$rhs);
13      }}};}
14
15macro_rules! neq_scalar_rhs_op {
16  ($lhs:expr, $rhs:expr, $out:expr) => {
17    unsafe {
18      for i in 0..(*$rhs).len() {
19        (&mut (*$out))[i] = (*$lhs) != (&(*$rhs))[i];
20      }}};}
21
22macro_rules! neq_vec_op {
23  ($lhs:expr, $rhs:expr, $out:expr) => {
24    unsafe {
25      for i in 0..(*$lhs).len() {
26        (&mut (*$out))[i] = (&(*$lhs))[i] != (&(*$rhs))[i];
27      }}};}
28
29macro_rules! neq_op {
30  ($lhs:expr, $rhs:expr, $out:expr) => {
31    unsafe {
32      (*$out) = (*$lhs) != (*$rhs);
33    }};}
34
35macro_rules! neq_mat_vec_op {
36  ($lhs:expr, $rhs:expr, $out:expr) => {
37    unsafe {
38      let mut out_deref = &mut (*$out);
39      let lhs_deref = &(*$lhs);
40      let rhs_deref = &(*$rhs);
41      for (mut col, lhs_col) in out_deref.column_iter_mut().zip(lhs_deref.column_iter()) {
42        for i in 0..col.len() {
43          col[i] = lhs_col[i] != rhs_deref[i];
44        }
45      }
46    }
47  };}   
48      
49macro_rules! neq_vec_mat_op {
50  ($lhs:expr, $rhs:expr, $out:expr) => {
51      unsafe {
52        let mut out_deref = &mut (*$out);
53        let lhs_deref = &(*$lhs);
54        let rhs_deref = &(*$rhs);
55        for (mut col, rhs_col) in out_deref.column_iter_mut().zip(rhs_deref.column_iter()) {
56          for i in 0..col.len() {
57            col[i] = lhs_deref[i] != rhs_col[i];
58          }
59        }
60      }
61  };}
62  
63macro_rules! neq_mat_row_op {
64  ($lhs:expr, $rhs:expr, $out:expr) => {
65      unsafe {
66      let mut out_deref = &mut (*$out);
67      let lhs_deref = &(*$lhs);
68      let rhs_deref = &(*$rhs);
69      for (mut row, lhs_row) in out_deref.row_iter_mut().zip(lhs_deref.row_iter()) {
70          for i in 0..row.len() {
71          row[i] = lhs_row[i] != rhs_deref[i];
72          }
73      }
74      }
75  };}
76
77macro_rules! neq_row_mat_op {
78  ($lhs:expr, $rhs:expr, $out:expr) => {
79      unsafe {
80      let mut out_deref = &mut (*$out);
81      let lhs_deref = &(*$lhs);
82      let rhs_deref = &(*$rhs);
83      for (mut row, rhs_row) in out_deref.row_iter_mut().zip(rhs_deref.row_iter()) {
84          for i in 0..row.len() {
85          row[i] = lhs_deref[i] != rhs_row[i];
86          }
87      }
88      }
89  };}    
90
91impl_compare_fxns!(NEQ);
92
93#[cfg(feature = "atom")]
94#[derive(Debug)]
95pub struct AtomNeq {
96  pub lhs: Ref<MechAtom>,
97  pub rhs: Ref<MechAtom>,
98  pub out: Ref<bool>,
99}
100impl MechFunctionFactory for AtomNeq {
101  fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
102    match args {
103      FunctionArgs::Binary(out, arg1, arg2) => {
104        let lhs: Ref<MechAtom> = unsafe { arg1.as_unchecked() }.clone();
105        let rhs: Ref<MechAtom> = unsafe { arg2.as_unchecked() }.clone();
106        let out: Ref<bool> = unsafe { out.as_unchecked() }.clone();
107        Ok(Box::new(AtomNeq { lhs, rhs, out }))
108      }
109      _ => Err(MechError2::new(
110          IncorrectNumberOfArguments { expected: 2, found: args.len() }, 
111          None
112        ).with_compiler_loc()
113      ),
114    }
115  }
116}
117#[cfg(feature = "atom")]
118impl MechFunctionImpl for AtomNeq {
119  fn solve(&self) {
120    let lhs_ptr = self.lhs.as_ptr();
121    let rhs_ptr = self.rhs.as_ptr();
122    let mut out_ptr = self.out.as_mut_ptr();
123    unsafe {
124      *out_ptr = (*lhs_ptr) != (*rhs_ptr);
125    }
126  }
127  fn out(&self) -> Value { self.out.to_value() }
128  fn to_string(&self) -> String { format!("{:#?}", self) }
129}
130#[cfg(feature = "atom")]
131#[cfg(feature = "compiler")]
132impl MechFunctionCompiler for AtomNeq {
133  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
134    let name = format!("AtomNeq");
135    compile_binop!(name, self.out, self.lhs, self.rhs, ctx, FeatureFlag::Builtin(FeatureKind::Atom));
136  }
137}
138
139
140#[cfg(feature = "table")]
141#[derive(Debug)]
142pub struct TableNeq {
143  pub lhs: Ref<MechTable>,
144  pub rhs: Ref<MechTable>,
145  pub out: Ref<bool>,
146}
147impl MechFunctionFactory for TableNeq {
148  fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
149    match args {
150      FunctionArgs::Binary(out, arg1, arg2) => {
151        let lhs: Ref<MechTable> = unsafe { arg1.as_unchecked() }.clone();
152        let rhs: Ref<MechTable> = unsafe { arg2.as_unchecked() }.clone();
153        let out: Ref<bool> = unsafe { out.as_unchecked() }.clone();
154        Ok(Box::new(TableNeq { lhs, rhs, out }))
155      }
156      _ => Err(MechError2::new(
157          IncorrectNumberOfArguments { expected: 2, found: args.len() }, 
158          None
159        ).with_compiler_loc()
160      ),
161    }
162  }
163}
164#[cfg(feature = "table")]
165impl MechFunctionImpl for TableNeq {
166  fn solve(&self) {
167    let lhs_ptr = self.lhs.as_ptr();
168    let rhs_ptr = self.rhs.as_ptr();
169    let mut out_ptr = self.out.as_mut_ptr();
170    unsafe {
171      *out_ptr = (*lhs_ptr) != (*rhs_ptr);
172    }
173  }
174  fn out(&self) -> Value { self.out.to_value() }
175  fn to_string(&self) -> String { format!("{:#?}", self) }
176}
177#[cfg(feature = "table")]
178#[cfg(feature = "compiler")]
179impl MechFunctionCompiler for TableNeq {
180  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
181    let name = format!("TableNeq");
182    compile_binop!(name, self.out, self.lhs, self.rhs, ctx, FeatureFlag::Builtin(FeatureKind::Table));
183  }
184}
185
186fn impl_neq_fxn(lhs_value: Value, rhs_value: Value) -> MResult<Box<dyn MechFunction>> {
187  match (&lhs_value, &rhs_value) {
188    #[cfg(all(feature = "table"))]
189    (Value::Table(lhs), Value::Table(rhs)) => {
190      register_descriptor! {
191        FunctionDescriptor {
192          name: "TableNeq",
193          ptr: TableNeq::new,
194        }
195      }
196      return Ok(Box::new(TableNeq{lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new(false) }));
197    }
198    #[cfg(feature = "atom")]
199    (Value::Atom(lhs), Value::Atom(rhs)) => {
200      register_descriptor! {
201        FunctionDescriptor {
202          name: "AtomNeq",
203          ptr: AtomNeq::new,
204        }
205      }
206      return Ok(Box::new(AtomNeq{lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new(false) }));
207    }
208    _ => (),
209  }
210  impl_binop_match_arms!(
211    NEQ,
212    register_fxn_descriptor_inner,
213    (lhs_value, rhs_value),
214    Bool, bool, "bool";
215    I8,   bool, "i8";
216    I16,  bool, "i16";
217    I32,  bool, "i32";
218    I64,  bool, "i64";
219    I128, bool, "i128";
220    U8,   bool, "u8";
221    U16,  bool, "u16";
222    U32,  bool, "u32";
223    U64,  bool, "u64";
224    U128, bool, "u128";
225    F32,  bool, "f32";
226    F64,  bool, "f64";
227    String, bool, "string";
228    R64, bool, "rational";
229    C64, bool, "complex";
230  )
231}
232
233impl_mech_binop_fxn!(CompareNotEqual,impl_neq_fxn,"compare/neq");