1#![feature(get_mut_unchecked)]
2#![feature(concat_idents)]
3#![allow(warnings)]
4#![feature(iter_intersperse)]
5#![feature(extract_if)]
6#![cfg_attr(feature = "no-std", no_std)]
7#![cfg_attr(feature = "no-std", alloc)]
8#![allow(dead_code)]
9#![feature(step_trait)]
10
11#[cfg(feature="no-std")] #[macro_use] extern crate alloc;
12#[cfg(not(feature = "no-std"))] extern crate core;
13extern crate nalgebra as na;
14extern crate tabled;
15extern crate libm;
16
17#[cfg(feature = "no-std")]
18extern crate alloc;
19extern crate core as rust_core;
20extern crate hashbrown;
21#[macro_use]
22extern crate serde_derive;
23extern crate serde;
24extern crate num_traits;
25extern crate seahash;
29extern crate indexmap;
30use std::rc::Rc;
31use std::cell::RefCell;
32use std::fmt;
33use num_traits::*;
34use std::ops::*;
35use std::mem;
36
37pub mod value;
38pub mod matrix;
39pub mod types;
40pub mod functions;
41pub mod kind;
42pub mod error;
43pub mod nodes;
44
45pub use self::value::*;
46pub use self::matrix::*;
47pub use self::types::*;
48pub use self::functions::*;
49pub use self::kind::*;
50pub use self::error::*;
51pub use self::nodes::*;
52
53pub fn hash_chars(input: &Vec<char>) -> u64 {
54 seahash::hash(input.iter().map(|s| String::from(*s)).collect::<String>().as_bytes()) & 0x00FFFFFFFFFFFFFF
55}
56
57pub fn hash_bytes(input: &Vec<u8>) -> u64 {
58 seahash::hash(input) & 0x00FFFFFFFFFFFFFF
59}
60
61pub fn hash_str(input: &str) -> u64 {
62 seahash::hash(input.to_string().as_bytes()) & 0x00FFFFFFFFFFFFFF
63}
64
65pub fn humanize(hash: &u64) -> String {
66 let bytes: [u8; 8] = hash.to_be_bytes();
67 let mut string = "".to_string();
68 let mut ix = 0;
69 for byte in bytes.iter() {
70 if ix % 2 == 0 {
71 ix += 1;
72 continue;
73 }
74 string.push_str(&WORDLIST[*byte as usize]);
75 if ix < 7 {
76 string.push_str("-");
77 }
78 ix += 1;
79 }
80 string
81}
82
83#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
84pub enum MechSourceCode {
85 String(String),
86 Tree(Program),
87 Html(String),
88}
89
90impl MechSourceCode {
91
92 pub fn to_string(&self) -> String {
93 match self {
94 MechSourceCode::String(s) => s.clone(),
95 MechSourceCode::Tree(p) => todo!("Print the tree!"),
96 MechSourceCode::Html(h) => h.clone(),
97 }
98 }
99
100}
101
102#[derive(Clone, Debug, PartialEq, Eq)]
103pub struct IndexedString {
104 pub data: Vec<char>,
105 pub index_map: Vec<Vec<usize>>,
106 pub rows: usize,
107 pub cols: usize,
108}
109
110impl IndexedString {
111
112 fn new(input: &str) -> Self {
113 let mut data = Vec::new();
114 let mut index_map = Vec::new();
115 let mut current_row = 0;
116 let mut current_col = 0;
117 index_map.push(Vec::new());
118 for c in input.chars() {
119 data.push(c);
120 if c == '\n' {
121 index_map.push(Vec::new());
122 current_row += 1;
123 current_col = 0;
124 } else {
125 index_map[current_row].push(data.len() - 1);
126 current_col += 1;
127 }
128 }
129 let rows = index_map.len();
130 let cols = if rows > 0 { index_map[0].len() } else { 0 };
131 IndexedString {
132 data,
133 index_map,
134 rows,
135 cols,
136 }
137 }
138
139 fn to_string(&self) -> String {
140 self.data.iter().collect()
141 }
142
143 fn get(&self, row: usize, col: usize) -> Option<char> {
144 if row < self.rows {
145 let rowz = &self.index_map[row];
146 if col < rowz.len() {
147 let index = self.index_map[row][col];
148 Some(self.data[index])
149 } else {
150 None
151 }
152 } else {
153 None
154 }
155 }
156
157 fn set(&mut self, row: usize, col: usize, new_char: char) -> Result<(), String> {
158 if row < self.rows {
159 let row_indices = &mut self.index_map[row];
160 if col < row_indices.len() {
161 let index = row_indices[col];
162 self.data[index] = new_char;
163 Ok(())
164 } else {
165 Err("Column index out of bounds".to_string())
166 }
167 } else {
168 Err("Row index out of bounds".to_string())
169 }
170 }
171}
172
173pub const WORDLIST: &[&str;256] = &[
174 "nil", "ama", "ine", "ska", "pha", "gel", "art",
175 "ona", "sas", "ist", "aus", "pen", "ust", "umn",
176 "ado", "con", "loo", "man", "eer", "lin", "ium",
177 "ack", "som", "lue", "ird", "avo", "dog", "ger",
178 "ter", "nia", "bon", "nal", "ina", "pet", "cat",
179 "ing", "lie", "ken", "fee", "ola", "old", "rad",
180 "met", "cut", "azy", "cup", "ota", "dec", "del",
181 "elt", "iet", "don", "ble", "ear", "rth", "eas",
182 "war", "eig", "tee", "ele", "emm", "ene", "qua",
183 "tst", "fan", "fif", "fil", "fin", "fis", "fiv",
184 "flo", "for", "foo", "fou", "fot", "fox", "fre",
185 "fri", "fru", "gee", "gia", "glu", "fol", "gre",
186 "ham", "hap", "har", "haw", "hel", "hig", "hot",
187 "hyd", "ida", "ill", "ind", "ini", "ink", "iwa",
188 "and", "ite", "jer", "jig", "joh", "jul", "uly",
189 "kan", "ket", "kil", "kin", "kit", "lac", "lak",
190 "lem", "ard", "lim", "lio", "lit", "lon", "lou",
191 "low", "mag", "nes", "mai", "gam", "arc", "mar",
192 "mao", "mas", "may", "mex", "mic", "mik", "ril",
193 "min", "mir", "mis", "mio", "mob", "moc", "ech",
194 "moe", "tan", "oon", "ain", "mup", "sic", "neb",
195 "une", "net", "nev", "nin", "een", "nit", "nor",
196 "nov", "nut", "oct", "ohi", "okl", "one", "ora",
197 "ges", "ore", "osc", "ove", "oxy", "pap", "par",
198 "pey", "pip", "piz", "plu", "pot", "pri", "pur",
199 "que", "uqi", "qui", "red", "riv", "rob", "roi",
200 "rug", "sad", "sal", "sat", "sep", "sev", "eve",
201 "sha", "sie", "sin", "sik", "six", "sit", "sky",
202 "soc", "sod", "sol", "sot", "tir", "ker", "spr",
203 "sta", "ste", "mam", "mer", "swe", "tab", "tag",
204 "see", "nis", "tex", "thi", "the", "tim", "tri",
205 "twe", "ent", "two", "unc", "ess", "uni", "ura",
206 "veg", "ven", "ver", "vic", "vid", "vio", "vir",
207 "was", "est", "whi", "hit", "iam", "win", "his",
208 "wis", "olf", "wyo", "ray", "ank", "yel", "zeb",
209 "ulu", "fix", "gry", "hol", "jup", "lam", "pas",
210 "rom", "sne", "ten", "uta"];
211
212#[macro_export]
217macro_rules! impl_binop {
218 ($struct_name:ident, $arg1_type:ty, $arg2_type:ty, $out_type:ty, $op:ident) => {
219 #[derive(Debug)]
220 struct $struct_name<T> {
221 lhs: Ref<$arg1_type>,
222 rhs: Ref<$arg2_type>,
223 out: Ref<$out_type>,
224 }
225 impl<T> MechFunction for $struct_name<T>
226 where
227 T: Copy + Debug + Clone + Sync + Send + 'static +
228 PartialEq + PartialOrd +
229 Add<Output = T> + AddAssign +
230 Sub<Output = T> + SubAssign +
231 Mul<Output = T> + MulAssign +
232 Div<Output = T> + DivAssign +
233 Zero + One,
234 Ref<$out_type>: ToValue
235 {
236 fn solve(&self) {
237 let lhs_ptr = self.lhs.as_ptr();
238 let rhs_ptr = self.rhs.as_ptr();
239 let out_ptr = self.out.as_ptr();
240 $op!(lhs_ptr,rhs_ptr,out_ptr);
241 }
242 fn out(&self) -> Value { self.out.to_value() }
243 fn to_string(&self) -> String { format!("{:#?}", self) }
244 }};}
245
246#[macro_export]
247macro_rules! impl_bool_binop {
248 ($struct_name:ident, $arg1_type:ty, $arg2_type:ty, $out_type:ty, $op:ident) => {
249 #[derive(Debug)]
250 struct $struct_name<T> {
251 lhs: Ref<$arg1_type>,
252 rhs: Ref<$arg2_type>,
253 out: Ref<$out_type>,
254 }
255 impl<T> MechFunction for $struct_name<T>
256 where
257 T: Copy + Debug + Clone + Sync + Send + 'static +
258 PartialEq + PartialOrd,
259 Ref<$out_type>: ToValue
260 {
261 fn solve(&self) {
262 let lhs_ptr = self.lhs.as_ptr();
263 let rhs_ptr = self.rhs.as_ptr();
264 let out_ptr = self.out.as_ptr();
265 $op!(lhs_ptr,rhs_ptr,out_ptr);
266 }
267 fn out(&self) -> Value { self.out.to_value() }
268 fn to_string(&self) -> String { format!("{:#?}", self) }
269 }};}
270
271#[macro_export]
272macro_rules! impl_bool_urop {
273 ($struct_name:ident, $arg_type:ty, $out_type:ty, $op:ident) => {
274 #[derive(Debug)]
275 struct $struct_name<T> {
276 arg: Ref<$arg_type>,
277 out: Ref<$out_type>,
278 }
279 impl<T> MechFunction for $struct_name<T>
280 where
281 T: Debug + Clone + Sync + Send + 'static +
282 PartialEq + PartialOrd,
283 Ref<$out_type>: ToValue
284 {
285 fn solve(&self) {
286 let arg_ptr = self.arg.as_ptr();
287 let out_ptr = self.out.as_ptr();
288 $op!(arg_ptr,out_ptr);
289 }
290 fn out(&self) -> Value { self.out.to_value() }
291 fn to_string(&self) -> String { format!("{:#?}", self) }
292 }};}
293
294#[macro_export]
295macro_rules! impl_urop {
296 ($struct_name:ident, $arg_type:ty, $out_type:ty, $op:ident) => {
297 #[derive(Debug)]
298 struct $struct_name {
299 arg: Ref<$arg_type>,
300 out: Ref<$out_type>,
301 }
302 impl MechFunction for $struct_name {
303 fn solve(&self) {
304 let arg_ptr = self.arg.as_ptr();
305 let out_ptr = self.out.as_ptr();
306 $op!(arg_ptr,out_ptr);
307 }
308 fn out(&self) -> Value { self.out.to_value() }
309 fn to_string(&self) -> String { format!("{:#?}", self) }
310 }};}
311
312#[macro_export]
313macro_rules! impl_fxns {
314 ($lib:ident, $in:ident, $out:ident, $op:ident) => {
315 paste!{
316 $op!([<$lib SS>], $in, $in, $out, [<$lib:lower _op>]);
318 #[cfg(feature = "Matrix1")]
320 $op!([<$lib SM1>], $in, Matrix1<$in>, Matrix1<$out>,[<$lib:lower _scalar_rhs_op>]);
321 #[cfg(feature = "Matrix2")]
322 $op!([<$lib SM2>], $in, Matrix2<$in>, Matrix2<$out>,[<$lib:lower _scalar_rhs_op>]);
323 #[cfg(feature = "Matrix3")]
324 $op!([<$lib SM3>], $in, Matrix3<$in>, Matrix3<$out>,[<$lib:lower _scalar_rhs_op>]);
325 #[cfg(feature = "Matrix4")]
326 $op!([<$lib SM4>], $in, Matrix4<$in>, Matrix4<$out>,[<$lib:lower _scalar_rhs_op>]);
327 #[cfg(feature = "Matrix2x3")]
328 $op!([<$lib SM2x3>], $in, Matrix2x3<$in>, Matrix2x3<$out>,[<$lib:lower _scalar_rhs_op>]);
329 #[cfg(feature = "Matrix3x2")]
330 $op!([<$lib SM3x2>], $in, Matrix3x2<$in>, Matrix3x2<$out>,[<$lib:lower _scalar_rhs_op>]);
331 #[cfg(feature = "MatrixD")]
332 $op!([<$lib SMD>], $in, DMatrix<$in>, DMatrix<$out>,[<$lib:lower _scalar_rhs_op>]);
333 #[cfg(feature = "RowVector2")]
335 $op!([<$lib SR2>], $in, RowVector2<$in>, RowVector2<$out>,[<$lib:lower _scalar_rhs_op>]);
336 #[cfg(feature = "RowVector3")]
337 $op!([<$lib SR3>], $in, RowVector3<$in>, RowVector3<$out>,[<$lib:lower _scalar_rhs_op>]);
338 #[cfg(feature = "RowVector4")]
339 $op!([<$lib SR4>], $in, RowVector4<$in>, RowVector4<$out>,[<$lib:lower _scalar_rhs_op>]);
340 #[cfg(feature = "RowVectorD")]
341 $op!([<$lib SRD>], $in, RowDVector<$in>, RowDVector<$out>,[<$lib:lower _scalar_rhs_op>]);
342 #[cfg(feature = "Vector2")]
344 $op!([<$lib SV2>], $in, Vector2<$in>, Vector2<$out>,[<$lib:lower _scalar_rhs_op>]);
345 #[cfg(feature = "Vector3")]
346 $op!([<$lib SV3>], $in, Vector3<$in>, Vector3<$out>,[<$lib:lower _scalar_rhs_op>]);
347 #[cfg(feature = "Vector4")]
348 $op!([<$lib SV4>], $in, Vector4<$in>, Vector4<$out>,[<$lib:lower _scalar_rhs_op>]);
349 #[cfg(feature = "VectorD")]
350 $op!([<$lib SVD>], $in, DVector<$in>, DVector<$out>,[<$lib:lower _scalar_rhs_op>]);
351 #[cfg(feature = "Matrix1")]
353 $op!([<$lib M1S>], Matrix1<$in>, $in, Matrix1<$out>,[<$lib:lower _scalar_lhs_op>]);
354 #[cfg(feature = "Matrix2")]
355 $op!([<$lib M2S>], Matrix2<$in>, $in, Matrix2<$out>,[<$lib:lower _scalar_lhs_op>]);
356 #[cfg(feature = "Matrix3")]
357 $op!([<$lib M3S>], Matrix3<$in>, $in, Matrix3<$out>,[<$lib:lower _scalar_lhs_op>]);
358 #[cfg(feature = "Matrix4")]
359 $op!([<$lib M4S>], Matrix4<$in>, $in, Matrix4<$out>,[<$lib:lower _scalar_lhs_op>]);
360 #[cfg(feature = "Matrix2x3")]
361 $op!([<$lib M2x3S>], Matrix2x3<$in>, $in, Matrix2x3<$out>,[<$lib:lower _scalar_lhs_op>]);
362 #[cfg(feature = "Matrix3x2")]
363 $op!([<$lib M3x2S>], Matrix3x2<$in>, $in, Matrix3x2<$out>,[<$lib:lower _scalar_lhs_op>]);
364 #[cfg(feature = "MatrixD")]
365 $op!([<$lib MDS>], DMatrix<$in>, $in, DMatrix<$out>,[<$lib:lower _scalar_lhs_op>]);
366 #[cfg(feature = "RowVector2")]
368 $op!([<$lib R2S>], RowVector2<$in>, $in, RowVector2<$out>,[<$lib:lower _scalar_lhs_op>]);
369 #[cfg(feature = "RowVector3")]
370 $op!([<$lib R3S>], RowVector3<$in>, $in, RowVector3<$out>,[<$lib:lower _scalar_lhs_op>]);
371 #[cfg(feature = "RowVector4")]
372 $op!([<$lib R4S>], RowVector4<$in>, $in, RowVector4<$out>,[<$lib:lower _scalar_lhs_op>]);
373 #[cfg(feature = "RowVectorD")]
374 $op!([<$lib RDS>], RowDVector<$in>, $in, RowDVector<$out>,[<$lib:lower _scalar_lhs_op>]);
375 #[cfg(feature = "Vector2")]
377 $op!([<$lib V2S>], Vector2<$in>, $in, Vector2<$out>,[<$lib:lower _scalar_lhs_op>]);
378 #[cfg(feature = "Vector3")]
379 $op!([<$lib V3S>], Vector3<$in>, $in, Vector3<$out>,[<$lib:lower _scalar_lhs_op>]);
380 #[cfg(feature = "Vector4")]
381 $op!([<$lib V4S>], Vector4<$in>, $in, Vector4<$out>,[<$lib:lower _scalar_lhs_op>]);
382 #[cfg(feature = "VectorD")]
383 $op!([<$lib VDS>], DVector<$in>, $in, DVector<$out>,[<$lib:lower _scalar_lhs_op>]);
384 #[cfg(feature = "Matrix1")]
386 $op!([<$lib M1M1>], Matrix1<$in>, Matrix1<$in>, Matrix1<$out>, [<$lib:lower _vec_op>]);
387 #[cfg(feature = "Matrix2")]
388 $op!([<$lib M2M2>], Matrix2<$in>, Matrix2<$in>, Matrix2<$out>, [<$lib:lower _vec_op>]);
389 #[cfg(feature = "Matrix3")]
390 $op!([<$lib M3M3>], Matrix3<$in>, Matrix3<$in>, Matrix3<$out>, [<$lib:lower _vec_op>]);
391 #[cfg(feature = "Matrix4")]
392 $op!([<$lib M4M4>], Matrix4<$in>, Matrix4<$in>, Matrix4<$out>, [<$lib:lower _vec_op>]);
393 #[cfg(feature = "Matrix2x3")]
394 $op!([<$lib M2x3M2x3>], Matrix2x3<$in>, Matrix2x3<$in>, Matrix2x3<$out>, [<$lib:lower _vec_op>]);
395 #[cfg(feature = "Matrix3x2")]
396 $op!([<$lib M3x2M3x2>], Matrix3x2<$in>, Matrix3x2<$in>, Matrix3x2<$out>, [<$lib:lower _vec_op>]);
397 #[cfg(feature = "MatrixD")]
398 $op!([<$lib MDMD>], DMatrix<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_op>]);
399 #[cfg(feature = "Matrix2")]
401 $op!([<$lib M2V2>], Matrix2<$in>, Vector2<$in>, Matrix2<$out>, [<$lib:lower _mat_vec_op>]);
402 #[cfg(feature = "Matrix3")]
403 $op!([<$lib M3V3>], Matrix3<$in>, Vector3<$in>, Matrix3<$out>, [<$lib:lower _mat_vec_op>]);
404 #[cfg(feature = "Matrix4")]
405 $op!([<$lib M4V4>], Matrix4<$in>, Vector4<$in>, Matrix4<$out>, [<$lib:lower _mat_vec_op>]);
406 #[cfg(feature = "Matrix2x3")]
407 $op!([<$lib M2x3V2>], Matrix2x3<$in>, Vector2<$in>, Matrix2x3<$out>, [<$lib:lower _mat_vec_op>]);
408 #[cfg(feature = "Matrix3x2")]
409 $op!([<$lib M3x2V3>], Matrix3x2<$in>, Vector3<$in>, Matrix3x2<$out>, [<$lib:lower _mat_vec_op>]);
410 #[cfg(feature = "MatrixD")]
411 $op!([<$lib MDVD>], DMatrix<$in>, DVector<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>]);
412 #[cfg(feature = "MatrixD")]
413 $op!([<$lib MDV2>], DMatrix<$in>, Vector2<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>]);
414 #[cfg(feature = "MatrixD")]
415 $op!([<$lib MDV3>], DMatrix<$in>, Vector3<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>]);
416 #[cfg(feature = "MatrixD")]
417 $op!([<$lib MDV4>], DMatrix<$in>, Vector4<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>]);
418 #[cfg(feature = "Vector2")]
420 $op!([<$lib V2M2>], Vector2<$in>, Matrix2<$in>, Matrix2<$out>, [<$lib:lower _vec_mat_op>]);
421 #[cfg(feature = "Vector3")]
422 $op!([<$lib V3M3>], Vector3<$in>, Matrix3<$in>, Matrix3<$out>, [<$lib:lower _vec_mat_op>]);
423 #[cfg(feature = "Vector4")]
424 $op!([<$lib V4M4>], Vector4<$in>, Matrix4<$in>, Matrix4<$out>, [<$lib:lower _vec_mat_op>]);
425 #[cfg(feature = "Vector2")]
426 $op!([<$lib V2M2x3>], Vector2<$in>, Matrix2x3<$in>, Matrix2x3<$out>, [<$lib:lower _vec_mat_op>]);
427 #[cfg(feature = "Vector3")]
428 $op!([<$lib V3M3x2>], Vector3<$in>, Matrix3x2<$in>, Matrix3x2<$out>, [<$lib:lower _vec_mat_op>]);
429 #[cfg(feature = "VectorD")]
430 $op!([<$lib VDMD>], DVector<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>]);
431 #[cfg(feature = "Vector2")]
432 $op!([<$lib V2MD>], Vector2<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>]);
433 #[cfg(feature = "Vector3")]
434 $op!([<$lib V3MD>], Vector3<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>]);
435 #[cfg(feature = "Vector4")]
436 $op!([<$lib V4MD>], Vector4<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>]);
437 #[cfg(feature = "Matrix2")]
439 $op!([<$lib M2R2>], Matrix2<$in>, RowVector2<$in>, Matrix2<$out>, [<$lib:lower _mat_row_op>]);
440 #[cfg(feature = "Matrix3")]
441 $op!([<$lib M3R3>], Matrix3<$in>, RowVector3<$in>, Matrix3<$out>, [<$lib:lower _mat_row_op>]);
442 #[cfg(feature = "Matrix4")]
443 $op!([<$lib M4R4>], Matrix4<$in>, RowVector4<$in>, Matrix4<$out>, [<$lib:lower _mat_row_op>]);
444 #[cfg(feature = "Matrix2x3")]
445 $op!([<$lib M2x3R3>], Matrix2x3<$in>, RowVector3<$in>, Matrix2x3<$out>, [<$lib:lower _mat_row_op>]);
446 #[cfg(feature = "Matrix3x2")]
447 $op!([<$lib M3x2R2>], Matrix3x2<$in>, RowVector2<$in>, Matrix3x2<$out>, [<$lib:lower _mat_row_op>]);
448 #[cfg(feature = "MatrixD")]
449 $op!([<$lib MDRD>], DMatrix<$in>, RowDVector<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>]);
450 #[cfg(feature = "MatrixD")]
451 $op!([<$lib MDR2>], DMatrix<$in>, RowVector2<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>]);
452 #[cfg(feature = "MatrixD")]
453 $op!([<$lib MDR3>], DMatrix<$in>, RowVector3<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>]);
454 #[cfg(feature = "MatrixD")]
455 $op!([<$lib MDR4>], DMatrix<$in>, RowVector4<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>]);
456 #[cfg(feature = "RowVector2")]
458 $op!([<$lib R2M2>], RowVector2<$in>, Matrix2<$in>, Matrix2<$out>, [<$lib:lower _row_mat_op>]);
459 #[cfg(feature = "RowVector3")]
460 $op!([<$lib R3M3>], RowVector3<$in>, Matrix3<$in>, Matrix3<$out>, [<$lib:lower _row_mat_op>]);
461 #[cfg(feature = "RowVector4")]
462 $op!([<$lib R4M4>], RowVector4<$in>, Matrix4<$in>, Matrix4<$out>, [<$lib:lower _row_mat_op>]);
463 #[cfg(feature = "RowVector3")]
464 $op!([<$lib R3M2x3>], RowVector3<$in>, Matrix2x3<$in>, Matrix2x3<$out>, [<$lib:lower _row_mat_op>]);
465 #[cfg(feature = "RowVector2")]
466 $op!([<$lib R2M3x2>], RowVector2<$in>, Matrix3x2<$in>, Matrix3x2<$out>, [<$lib:lower _row_mat_op>]);
467 #[cfg(feature = "RowVectorD")]
468 $op!([<$lib RDMD>], RowDVector<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>]);
469 #[cfg(feature = "RowVector2")]
470 $op!([<$lib R2MD>], RowVector2<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>]);
471 #[cfg(feature = "RowVector3")]
472 $op!([<$lib R3MD>], RowVector3<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>]);
473 #[cfg(feature = "RowVector4")]
474 $op!([<$lib R4MD>], RowVector4<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>]);
475 #[cfg(feature = "RowVector2")]
477 $op!([<$lib R2R2>], RowVector2<$in>, RowVector2<$in>, RowVector2<$out>, [<$lib:lower _vec_op>]);
478 #[cfg(feature = "RowVector3")]
479 $op!([<$lib R3R3>], RowVector3<$in>, RowVector3<$in>, RowVector3<$out>, [<$lib:lower _vec_op>]);
480 #[cfg(feature = "RowVector4")]
481 $op!([<$lib R4R4>], RowVector4<$in>, RowVector4<$in>, RowVector4<$out>, [<$lib:lower _vec_op>]);
482 #[cfg(feature = "RowVectorD")]
483 $op!([<$lib RDRD>], RowDVector<$in>, RowDVector<$in>, RowDVector<$out>, [<$lib:lower _vec_op>]);
484 #[cfg(feature = "Vector2")]
486 $op!([<$lib V2V2>], Vector2<$in>, Vector2<$in>, Vector2<$out>, [<$lib:lower _vec_op>]);
487 #[cfg(feature = "Vector3")]
488 $op!([<$lib V3V3>], Vector3<$in>, Vector3<$in>, Vector3<$out>, [<$lib:lower _vec_op>]);
489 #[cfg(feature = "Vector4")]
490 $op!([<$lib V4V4>], Vector4<$in>, Vector4<$in>, Vector4<$out>, [<$lib:lower _vec_op>]);
491 #[cfg(feature = "VectorD")]
492 $op!([<$lib VDVD>], DVector<$in>, DVector<$in>, DVector<$out>, [<$lib:lower _vec_op>]);
493 }
494 }}
495
496#[macro_export]
497macro_rules! impl_binop_match_arms {
498 ($lib:ident, $arg:expr, $($lhs_type:ident, $rhs_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
499 paste!{
500 match $arg {
501 $(
502 $(
503 (Value::$lhs_type(lhs), Value::$rhs_type(rhs)) => Ok(Box::new([<$lib SS>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref($default) })),
505 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
507 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix1(rhs))) => Ok(Box::new([<$lib SM1>]{lhs, rhs, out: new_ref(Matrix1::from_element($default))})),
508 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
509 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix2(rhs))) => Ok(Box::new([<$lib SM2>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))})),
510 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
511 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix3(rhs))) => Ok(Box::new([<$lib SM3>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))})),
512 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
513 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix4(rhs))) => Ok(Box::new([<$lib SM4>]{lhs, rhs, out: new_ref(Matrix4::from_element($default))})),
514 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
515 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix2x3(rhs))) => Ok(Box::new([<$lib SM2x3>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))})),
516 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
517 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix3x2(rhs))) => Ok(Box::new([<$lib SM3x2>]{lhs, rhs, out: new_ref(Matrix3x2::from_element($default))})),
518 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
519 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::DMatrix(rhs))) => {
520 let (rows,cols) = {rhs.borrow().shape()};
521 Ok(Box::new([<$lib SMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
522 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
524 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::RowVector2(rhs))) => Ok(Box::new([<$lib SR2>]{lhs, rhs, out: new_ref(RowVector2::from_element($default))})),
525 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
526 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::RowVector3(rhs))) => Ok(Box::new([<$lib SR3>]{lhs, rhs, out: new_ref(RowVector3::from_element($default))})),
527 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
528 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::RowVector4(rhs))) => Ok(Box::new([<$lib SR4>]{lhs, rhs, out: new_ref(RowVector4::from_element($default))})),
529 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
530 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::RowDVector(rhs))) => Ok(Box::new([<$lib SRD>]{lhs, rhs: rhs.clone(), out: new_ref(RowDVector::from_element(rhs.borrow().len(),$default))})),
531 #[cfg(all(feature = $value_string, feature = "Vector2"))]
533 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Vector2(rhs))) => Ok(Box::new([<$lib SV2>]{lhs, rhs, out: new_ref(Vector2::from_element($default))})),
534 #[cfg(all(feature = $value_string, feature = "Vector3"))]
535 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Vector3(rhs))) => Ok(Box::new([<$lib SV3>]{lhs, rhs, out: new_ref(Vector3::from_element($default))})),
536 #[cfg(all(feature = $value_string, feature = "Vector4"))]
537 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Vector4(rhs))) => Ok(Box::new([<$lib SV4>]{lhs, rhs, out: new_ref(Vector4::from_element($default))})),
538 #[cfg(all(feature = $value_string, feature = "VectorD"))]
539 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::DVector(rhs))) => Ok(Box::new([<$lib SVD>]{lhs, rhs: rhs.clone(), out: new_ref(DVector::from_element(rhs.borrow().len(),$default))})),
540 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
542 (Value::$matrix_kind(Matrix::Matrix1(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M1S>]{lhs, rhs, out: new_ref(Matrix1::from_element($default))})),
543 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
544 (Value::$matrix_kind(Matrix::Matrix2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M2S>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))})),
545 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
546 (Value::$matrix_kind(Matrix::Matrix3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M3S>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))})),
547 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
548 (Value::$matrix_kind(Matrix::Matrix4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M4S>]{lhs, rhs, out: new_ref(Matrix4::from_element($default))})),
549 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
550 (Value::$matrix_kind(Matrix::Matrix2x3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M2x3S>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))})),
551 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
552 (Value::$matrix_kind(Matrix::Matrix3x2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M3x2S>]{lhs, rhs, out: new_ref(Matrix3x2::from_element($default))})),
553 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
554 (Value::$matrix_kind(Matrix::DMatrix(lhs)),Value::$lhs_type(rhs)) => {
555 let (rows,cols) = {lhs.borrow().shape()};
556 Ok(Box::new([<$lib MDS>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
557 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
559 (Value::$matrix_kind(Matrix::RowVector2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R2S>]{lhs, rhs, out: new_ref(RowVector2::from_element($default))})),
560 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
561 (Value::$matrix_kind(Matrix::RowVector3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R3S>]{lhs, rhs, out: new_ref(RowVector3::from_element($default))})),
562 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
563 (Value::$matrix_kind(Matrix::RowVector4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R4S>]{lhs, rhs, out: new_ref(RowVector4::from_element($default))})),
564 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
565 (Value::$matrix_kind(Matrix::RowDVector(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib RDS>]{lhs: lhs.clone(), rhs, out: new_ref(RowDVector::from_element(lhs.borrow().len(),$default))})),
566 #[cfg(all(feature = $value_string, feature = "Vector2"))]
568 (Value::$matrix_kind(Matrix::Vector2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V2S>]{lhs, rhs, out: new_ref(Vector2::from_element($default))})),
569 #[cfg(all(feature = $value_string, feature = "Vector3"))]
570 (Value::$matrix_kind(Matrix::Vector3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V3S>]{lhs, rhs, out: new_ref(Vector3::from_element($default))})),
571 #[cfg(all(feature = $value_string, feature = "Vector4"))]
572 (Value::$matrix_kind(Matrix::Vector4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V4S>]{lhs, rhs, out: new_ref(Vector4::from_element($default))})),
573 #[cfg(all(feature = $value_string, feature = "VectorD"))]
574 (Value::$matrix_kind(Matrix::DVector(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib VDS>]{lhs: lhs.clone(), rhs, out: new_ref(DVector::from_element(lhs.borrow().len(),$default))})),
575 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
577 (Value::$matrix_kind(Matrix::Matrix1(lhs)), Value::$matrix_kind(Matrix::Matrix1(rhs))) => Ok(Box::new([<$lib M1M1>]{lhs, rhs, out: new_ref(Matrix1::from_element($default))})),
578 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
579 (Value::$matrix_kind(Matrix::Matrix2(lhs)), Value::$matrix_kind(Matrix::Matrix2(rhs))) => Ok(Box::new([<$lib M2M2>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))})),
580 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
581 (Value::$matrix_kind(Matrix::Matrix3(lhs)), Value::$matrix_kind(Matrix::Matrix3(rhs))) => Ok(Box::new([<$lib M3M3>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))})),
582 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
583 (Value::$matrix_kind(Matrix::Matrix4(lhs)), Value::$matrix_kind(Matrix::Matrix4(rhs))) => Ok(Box::new([<$lib M4M4>]{lhs, rhs, out: new_ref(Matrix4::from_element($default))})),
584 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
585 (Value::$matrix_kind(Matrix::Matrix2x3(lhs)), Value::$matrix_kind(Matrix::Matrix2x3(rhs))) => Ok(Box::new([<$lib M2x3M2x3>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))})),
586 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
587 (Value::$matrix_kind(Matrix::Matrix3x2(lhs)), Value::$matrix_kind(Matrix::Matrix3x2(rhs))) => Ok(Box::new([<$lib M3x2M3x2>]{lhs, rhs, out: new_ref(Matrix3x2::from_element($default))})),
588 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
589 (Value::$matrix_kind(Matrix::DMatrix(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => {
590 let (rows,cols) = {lhs.borrow().shape()};
591 Ok(Box::new([<$lib MDMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
592 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
594 (Value::$matrix_kind(Matrix::RowVector2(lhs)), Value::$matrix_kind(Matrix::RowVector2(rhs))) => Ok(Box::new([<$lib R2R2>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector2::from_element($default)) })),
595 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
596 (Value::$matrix_kind(Matrix::RowVector3(lhs)), Value::$matrix_kind(Matrix::RowVector3(rhs))) => Ok(Box::new([<$lib R3R3>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector3::from_element($default)) })),
597 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
598 (Value::$matrix_kind(Matrix::RowVector4(lhs)), Value::$matrix_kind(Matrix::RowVector4(rhs))) => Ok(Box::new([<$lib R4R4>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector4::from_element($default)) })),
599 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
600 (Value::$matrix_kind(Matrix::RowDVector(lhs)), Value::$matrix_kind(Matrix::RowDVector(rhs))) => Ok(Box::new([<$lib RDRD>]{lhs: lhs.clone(), rhs, out: new_ref(RowDVector::from_element(lhs.borrow().len(),$default))})),
601 #[cfg(all(feature = $value_string, feature = "Vector2"))]
603 (Value::$matrix_kind(Matrix::Vector2(lhs)), Value::$matrix_kind(Matrix::Vector2(rhs))) => Ok(Box::new([<$lib V2V2>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Vector2::from_element($default)) })),
604 #[cfg(all(feature = $value_string, feature = "Vector3"))]
605 (Value::$matrix_kind(Matrix::Vector3(lhs)), Value::$matrix_kind(Matrix::Vector3(rhs))) => Ok(Box::new([<$lib V3V3>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Vector3::from_element($default)) })),
606 #[cfg(all(feature = $value_string, feature = "Vector4"))]
607 (Value::$matrix_kind(Matrix::Vector4(lhs)), Value::$matrix_kind(Matrix::Vector4(rhs))) => Ok(Box::new([<$lib V4V4>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Vector4::from_element($default)) })),
608 #[cfg(all(feature = $value_string, feature = "VectorD"))]
609 (Value::$matrix_kind(Matrix::DVector(lhs)), Value::$matrix_kind(Matrix::DVector(rhs))) => Ok(Box::new([<$lib VDVD>]{lhs: lhs.clone(), rhs, out: new_ref(DVector::from_element(lhs.borrow().len(),$default))})),
610 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
612 (Value::$matrix_kind(Matrix::Matrix2(lhs)),Value::$matrix_kind(Matrix::Vector2(rhs))) => Ok(Box::new([<$lib M2V2>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))})),
613 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
614 (Value::$matrix_kind(Matrix::Matrix3(lhs)),Value::$matrix_kind(Matrix::Vector3(rhs))) => Ok(Box::new([<$lib M3V3>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))})),
615 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
616 (Value::$matrix_kind(Matrix::Matrix2x3(lhs)),Value::$matrix_kind(Matrix::Vector2(rhs))) => Ok(Box::new([<$lib M2x3V2>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))})),
617 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
618 (Value::$matrix_kind(Matrix::Matrix3x2(lhs)),Value::$matrix_kind(Matrix::Vector3(rhs))) => Ok(Box::new([<$lib M3x2V3>]{lhs, rhs, out: new_ref(Matrix3x2::from_element($default))})),
619 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
620 (Value::$matrix_kind(Matrix::Matrix4(lhs)),Value::$matrix_kind(Matrix::Vector4(rhs))) => Ok(Box::new([<$lib M4V4>]{lhs, rhs, out: new_ref(Matrix4::from_element($default))})),
621 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
622 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
624 (Value::$matrix_kind(Matrix::Matrix2(lhs)),Value::$matrix_kind(Matrix::RowVector2(rhs))) => Ok(Box::new([<$lib M2R2>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))})),
625 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
626 (Value::$matrix_kind(Matrix::Matrix3(lhs)),Value::$matrix_kind(Matrix::RowVector3(rhs))) => Ok(Box::new([<$lib M3R3>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))})),
627 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
628 (Value::$matrix_kind(Matrix::Matrix2x3(lhs)),Value::$matrix_kind(Matrix::RowVector3(rhs))) => Ok(Box::new([<$lib M2x3R3>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))})),
629 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
630 (Value::$matrix_kind(Matrix::Matrix3x2(lhs)),Value::$matrix_kind(Matrix::RowVector2(rhs))) => Ok(Box::new([<$lib M3x2R2>]{lhs, rhs, out: new_ref(Matrix3x2::from_element($default))})),
631 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
632 (Value::$matrix_kind(Matrix::Matrix4(lhs)),Value::$matrix_kind(Matrix::RowVector4(rhs))) => Ok(Box::new([<$lib M4R4>]{lhs, rhs, out: new_ref(Matrix4::from_element($default))})),
633 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
634 (Value::$matrix_kind(Matrix::DMatrix(lhs)),Value::$matrix_kind(rhs)) => {
635 let (rows,cols) = {lhs.borrow().shape()};
636 let rhs_shape = rhs.shape();
637 match (rows,cols,rhs_shape[0],rhs_shape[1]) {
638 (n,_,m,1) if n == m => (),
640 (_,n,1,m) if n == m => (),
642 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
644 }
645 match rhs {
646 Matrix::Vector2(rhs) => Ok(Box::new([<$lib MDV2>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
647 Matrix::Vector3(rhs) => Ok(Box::new([<$lib MDV3>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
648 Matrix::Vector4(rhs) => Ok(Box::new([<$lib MDV4>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
649 Matrix::DVector(rhs) => Ok(Box::new([<$lib MDVD>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
650 Matrix::RowVector2(rhs) => Ok(Box::new([<$lib MDR2>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
651 Matrix::RowVector3(rhs) => Ok(Box::new([<$lib MDR3>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
652 Matrix::RowVector4(rhs) => Ok(Box::new([<$lib MDR4>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
653 Matrix::RowDVector(rhs) => Ok(Box::new([<$lib MDRD>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
654 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
655 }
656 },
657 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
659 (Value::$matrix_kind(Matrix::Vector2(lhs)), Value::$matrix_kind(Matrix::Matrix2(rhs))) => Ok(Box::new([<$lib V2M2>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))})),
660 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
661 (Value::$matrix_kind(Matrix::Vector3(lhs)), Value::$matrix_kind(Matrix::Matrix3(rhs))) => Ok(Box::new([<$lib V3M3>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))})),
662 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
663 (Value::$matrix_kind(Matrix::Vector2(lhs)), Value::$matrix_kind(Matrix::Matrix2x3(rhs))) => Ok(Box::new([<$lib V2M2x3>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))})),
664 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
665 (Value::$matrix_kind(Matrix::Vector3(lhs)), Value::$matrix_kind(Matrix::Matrix3x2(rhs))) => Ok(Box::new([<$lib V3M3x2>]{lhs, rhs, out: new_ref(Matrix3x2::from_element($default))})),
666 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
667 (Value::$matrix_kind(Matrix::Vector4(lhs)), Value::$matrix_kind(Matrix::Matrix4(rhs))) => Ok(Box::new([<$lib V4M4>]{lhs, rhs, out: new_ref(Matrix4::from_element($default))})),
668 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
670 (Value::$matrix_kind(Matrix::RowVector2(lhs)), Value::$matrix_kind(Matrix::Matrix2(rhs))) => Ok(Box::new([<$lib R2M2>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))})),
671 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
672 (Value::$matrix_kind(Matrix::RowVector3(lhs)), Value::$matrix_kind(Matrix::Matrix3(rhs))) => Ok(Box::new([<$lib R3M3>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))})),
673 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
674 (Value::$matrix_kind(Matrix::RowVector3(lhs)), Value::$matrix_kind(Matrix::Matrix2x3(rhs))) => Ok(Box::new([<$lib R3M2x3>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))})),
675 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
676 (Value::$matrix_kind(Matrix::RowVector2(lhs)), Value::$matrix_kind(Matrix::Matrix3x2(rhs))) => Ok(Box::new([<$lib R2M3x2>]{lhs, rhs, out: new_ref(Matrix3x2::from_element($default))})),
677 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
678 (Value::$matrix_kind(Matrix::RowVector4(lhs)), Value::$matrix_kind(Matrix::Matrix4(rhs))) => Ok(Box::new([<$lib R4M4>]{lhs, rhs, out: new_ref(Matrix4::from_element($default))})),
679 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
680 (Value::$matrix_kind(lhs),Value::$matrix_kind(Matrix::DMatrix(rhs))) => {
681 let (rows,cols) = {rhs.borrow().shape()};
682 let lhs_shape = lhs.shape();
683 match (lhs_shape[0],lhs_shape[1],rows,cols) {
684 (m,1,n,_) if n == m => (),
686 (1,m,_,n) if n == m => (),
688 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
690 }
691 match lhs {
692 Matrix::Vector2(lhs) => Ok(Box::new([<$lib V2MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
693 Matrix::Vector3(lhs) => Ok(Box::new([<$lib V3MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
694 Matrix::Vector4(lhs) => Ok(Box::new([<$lib V4MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
695 Matrix::DVector(lhs) => Ok(Box::new([<$lib VDMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
696 Matrix::RowVector2(lhs) => Ok(Box::new([<$lib R2MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
697 Matrix::RowVector3(lhs) => Ok(Box::new([<$lib R3MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
698 Matrix::RowVector4(lhs) => Ok(Box::new([<$lib R4MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
699 Matrix::RowDVector(lhs) => Ok(Box::new([<$lib RDMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
700 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
701 }
702 }
703 )+
704 )+
705 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
706 }
707 }
708 }
709}
710
711#[macro_export]
712macro_rules! impl_urnop_match_arms {
713 ($lib:ident, $arg:expr, $($lhs_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
714 paste!{
715 match $arg {
716 $(
717 $(
718 (Value::$lhs_type(arg)) => Ok(Box::new([<$lib S>]{arg: arg.clone(), out: new_ref($default) })),
719 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
720 (Value::$matrix_kind(Matrix::Matrix1(arg))) => Ok(Box::new([<$lib M1>]{arg, out: new_ref(Matrix1::from_element($default))})),
721 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
722 (Value::$matrix_kind(Matrix::Matrix2(arg))) => Ok(Box::new([<$lib M2>]{arg, out: new_ref(Matrix2::from_element($default))})),
723 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
724 (Value::$matrix_kind(Matrix::Matrix3(arg))) => Ok(Box::new([<$lib M3>]{arg, out: new_ref(Matrix3::from_element($default))})),
725 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
726 (Value::$matrix_kind(Matrix::Matrix4(arg))) => Ok(Box::new([<$lib M4>]{arg, out: new_ref(Matrix4::from_element($default))})),
727 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
728 (Value::$matrix_kind(Matrix::Matrix2x3(arg))) => Ok(Box::new([<$lib M2x3>]{arg, out: new_ref(Matrix2x3::from_element($default))})),
729 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
730 (Value::$matrix_kind(Matrix::Matrix3x2(arg))) => Ok(Box::new([<$lib M3x2>]{arg, out: new_ref(Matrix3x2::from_element($default))})),
731 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
732 (Value::$matrix_kind(Matrix::RowVector2(arg))) => Ok(Box::new([<$lib R2>]{arg: arg.clone(), out: new_ref(RowVector2::from_element($default)) })),
733 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
734 (Value::$matrix_kind(Matrix::RowVector3(arg))) => Ok(Box::new([<$lib R3>]{arg: arg.clone(), out: new_ref(RowVector3::from_element($default)) })),
735 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
736 (Value::$matrix_kind(Matrix::RowVector4(arg))) => Ok(Box::new([<$lib R4>]{arg: arg.clone(), out: new_ref(RowVector4::from_element($default)) })),
737 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
738 (Value::$matrix_kind(Matrix::RowDVector(arg))) => Ok(Box::new([<$lib RD>]{arg: arg.clone(), out: new_ref(RowDVector::from_element(arg.borrow().len(),$default))})),
739 #[cfg(all(feature = $value_string, feature = "Vector2"))]
740 (Value::$matrix_kind(Matrix::Vector2(arg))) => Ok(Box::new([<$lib V2>]{arg: arg.clone(), out: new_ref(Vector2::from_element($default)) })),
741 #[cfg(all(feature = $value_string, feature = "Vector3"))]
742 (Value::$matrix_kind(Matrix::Vector3(arg))) => Ok(Box::new([<$lib V3>]{arg: arg.clone(), out: new_ref(Vector3::from_element($default)) })),
743 #[cfg(all(feature = $value_string, feature = "Vector4"))]
744 (Value::$matrix_kind(Matrix::Vector4(arg))) => Ok(Box::new([<$lib V4>]{arg: arg.clone(), out: new_ref(Vector4::from_element($default)) })),
745 #[cfg(all(feature = $value_string, feature = "VectorD"))]
746 (Value::$matrix_kind(Matrix::DVector(arg))) => Ok(Box::new([<$lib VD>]{arg: arg.clone(), out: new_ref(DVector::from_element(arg.borrow().len(),$default))})),
747 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
748 (Value::$matrix_kind(Matrix::DMatrix(arg))) => {
749 let (rows,cols) = {arg.borrow().shape()};
750 Ok(Box::new([<$lib MD>]{arg, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
751 )+
752 )+
753 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
754 }
755 }
756 }
757}
758
759#[macro_export]
760macro_rules! impl_mech_binop_fxn {
761 ($fxn_name:ident, $gen_fxn:ident) => {
762 pub struct $fxn_name {}
763 impl NativeFunctionCompiler for $fxn_name {
764 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
765 if arguments.len() != 2 {
766 return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
767 }
768 let lhs_value = arguments[0].clone();
769 let rhs_value = arguments[1].clone();
770 match $gen_fxn(lhs_value.clone(), rhs_value.clone()) {
771 Ok(fxn) => Ok(fxn),
772 Err(_) => {
773 match (lhs_value,rhs_value) {
774 (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {$gen_fxn(lhs.borrow().clone(), rhs.borrow().clone())}
775 (lhs_value,Value::MutableReference(rhs)) => { $gen_fxn(lhs_value.clone(), rhs.borrow().clone())}
776 (Value::MutableReference(lhs),rhs_value) => { $gen_fxn(lhs.borrow().clone(), rhs_value.clone()) }
777 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
778 }
779 }
780 }
781 }
782 }
783 }
784}
785
786#[macro_export]
787macro_rules! impl_mech_urnop_fxn {
788 ($fxn_name:ident, $gen_fxn:ident) => {
789 pub struct $fxn_name {}
790 impl NativeFunctionCompiler for $fxn_name {
791 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
792 if arguments.len() != 1 {
793 return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
794 }
795 let input = arguments[0].clone();
796 match $gen_fxn(input.clone()) {
797 Ok(fxn) => Ok(fxn),
798 Err(_) => {
799 match (input) {
800 (Value::MutableReference(input)) => {$gen_fxn(input.borrow().clone())}
801 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
802 }
803 }
804 }
805 }
806 }
807 }
808}