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