1use crate::*;
2use mech_core::*;
3#[cfg(feature = "matrix")]
4use mech_core::matrix::Matrix;
5
6macro_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");