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