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 ed25519_dalek;
28extern crate rand;
29extern crate getrandom;
30
31extern crate seahash;
32extern crate indexmap;
33use std::rc::Rc;
34use std::cell::RefCell;
35use std::fmt;
36use num_traits::*;
37use std::ops::*;
38use std::mem;
39
40pub mod value;
41pub mod matrix;
42pub mod types;
43pub mod functions;
44pub mod kind;
45pub mod error;
46pub mod nodes;
47
48pub use self::value::*;
49pub use self::matrix::*;
50pub use self::types::*;
51pub use self::functions::*;
52pub use self::kind::*;
53pub use self::error::*;
54pub use self::nodes::*;
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: Copy + 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 (Value::$lhs_type(lhs), Value::$rhs_type(rhs)) => Ok(Box::new([<$lib SS>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref($default) })),
508 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
510 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix1(rhs))) => Ok(Box::new([<$lib SM1>]{lhs, rhs, out: new_ref(Matrix1::from_element($default))})),
511 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
512 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix2(rhs))) => Ok(Box::new([<$lib SM2>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))})),
513 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
514 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix3(rhs))) => Ok(Box::new([<$lib SM3>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))})),
515 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
516 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix4(rhs))) => Ok(Box::new([<$lib SM4>]{lhs, rhs, out: new_ref(Matrix4::from_element($default))})),
517 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
518 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix2x3(rhs))) => Ok(Box::new([<$lib SM2x3>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))})),
519 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
520 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix3x2(rhs))) => Ok(Box::new([<$lib SM3x2>]{lhs, rhs, out: new_ref(Matrix3x2::from_element($default))})),
521 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
522 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::DMatrix(rhs))) => {
523 let (rows,cols) = {rhs.borrow().shape()};
524 Ok(Box::new([<$lib SMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
525 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
527 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::RowVector2(rhs))) => Ok(Box::new([<$lib SR2>]{lhs, rhs, out: new_ref(RowVector2::from_element($default))})),
528 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
529 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::RowVector3(rhs))) => Ok(Box::new([<$lib SR3>]{lhs, rhs, out: new_ref(RowVector3::from_element($default))})),
530 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
531 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::RowVector4(rhs))) => Ok(Box::new([<$lib SR4>]{lhs, rhs, out: new_ref(RowVector4::from_element($default))})),
532 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
533 (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))})),
534 #[cfg(all(feature = $value_string, feature = "Vector2"))]
536 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Vector2(rhs))) => Ok(Box::new([<$lib SV2>]{lhs, rhs, out: new_ref(Vector2::from_element($default))})),
537 #[cfg(all(feature = $value_string, feature = "Vector3"))]
538 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Vector3(rhs))) => Ok(Box::new([<$lib SV3>]{lhs, rhs, out: new_ref(Vector3::from_element($default))})),
539 #[cfg(all(feature = $value_string, feature = "Vector4"))]
540 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Vector4(rhs))) => Ok(Box::new([<$lib SV4>]{lhs, rhs, out: new_ref(Vector4::from_element($default))})),
541 #[cfg(all(feature = $value_string, feature = "VectorD"))]
542 (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))})),
543 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
545 (Value::$matrix_kind(Matrix::Matrix1(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M1S>]{lhs, rhs, out: new_ref(Matrix1::from_element($default))})),
546 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
547 (Value::$matrix_kind(Matrix::Matrix2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M2S>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))})),
548 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
549 (Value::$matrix_kind(Matrix::Matrix3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M3S>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))})),
550 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
551 (Value::$matrix_kind(Matrix::Matrix4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M4S>]{lhs, rhs, out: new_ref(Matrix4::from_element($default))})),
552 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
553 (Value::$matrix_kind(Matrix::Matrix2x3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M2x3S>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))})),
554 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
555 (Value::$matrix_kind(Matrix::Matrix3x2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M3x2S>]{lhs, rhs, out: new_ref(Matrix3x2::from_element($default))})),
556 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
557 (Value::$matrix_kind(Matrix::DMatrix(lhs)),Value::$lhs_type(rhs)) => {
558 let (rows,cols) = {lhs.borrow().shape()};
559 Ok(Box::new([<$lib MDS>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
560 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
562 (Value::$matrix_kind(Matrix::RowVector2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R2S>]{lhs, rhs, out: new_ref(RowVector2::from_element($default))})),
563 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
564 (Value::$matrix_kind(Matrix::RowVector3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R3S>]{lhs, rhs, out: new_ref(RowVector3::from_element($default))})),
565 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
566 (Value::$matrix_kind(Matrix::RowVector4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R4S>]{lhs, rhs, out: new_ref(RowVector4::from_element($default))})),
567 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
568 (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))})),
569 #[cfg(all(feature = $value_string, feature = "Vector2"))]
571 (Value::$matrix_kind(Matrix::Vector2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V2S>]{lhs, rhs, out: new_ref(Vector2::from_element($default))})),
572 #[cfg(all(feature = $value_string, feature = "Vector3"))]
573 (Value::$matrix_kind(Matrix::Vector3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V3S>]{lhs, rhs, out: new_ref(Vector3::from_element($default))})),
574 #[cfg(all(feature = $value_string, feature = "Vector4"))]
575 (Value::$matrix_kind(Matrix::Vector4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V4S>]{lhs, rhs, out: new_ref(Vector4::from_element($default))})),
576 #[cfg(all(feature = $value_string, feature = "VectorD"))]
577 (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))})),
578 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
580 (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))})),
581 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
582 (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))})),
583 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
584 (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))})),
585 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
586 (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))})),
587 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
588 (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))})),
589 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
590 (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))})),
591 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
592 (Value::$matrix_kind(Matrix::DMatrix(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => {
593 let (rows,cols) = {lhs.borrow().shape()};
594 Ok(Box::new([<$lib MDMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
595 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
597 (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)) })),
598 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
599 (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)) })),
600 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
601 (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)) })),
602 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
603 (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))})),
604 #[cfg(all(feature = $value_string, feature = "Vector2"))]
606 (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)) })),
607 #[cfg(all(feature = $value_string, feature = "Vector3"))]
608 (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)) })),
609 #[cfg(all(feature = $value_string, feature = "Vector4"))]
610 (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)) })),
611 #[cfg(all(feature = $value_string, feature = "VectorD"))]
612 (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))})),
613 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
615 (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))})),
616 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
617 (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))})),
618 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
619 (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))})),
620 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
621 (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))})),
622 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
623 (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))})),
624 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
625 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
627 (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))})),
628 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
629 (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))})),
630 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
631 (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))})),
632 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
633 (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))})),
634 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
635 (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))})),
636 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
637 (Value::$matrix_kind(Matrix::DMatrix(lhs)),Value::$matrix_kind(rhs)) => {
638 let (rows,cols) = {lhs.borrow().shape()};
639 let rhs_shape = rhs.shape();
640 match (rows,cols,rhs_shape[0],rhs_shape[1]) {
641 (n,_,m,1) if n == m => (),
643 (_,n,1,m) if n == m => (),
645 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
647 }
648 match rhs {
649 Matrix::Vector2(rhs) => Ok(Box::new([<$lib MDV2>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
650 Matrix::Vector3(rhs) => Ok(Box::new([<$lib MDV3>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
651 Matrix::Vector4(rhs) => Ok(Box::new([<$lib MDV4>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
652 Matrix::DVector(rhs) => Ok(Box::new([<$lib MDVD>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
653 Matrix::RowVector2(rhs) => Ok(Box::new([<$lib MDR2>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
654 Matrix::RowVector3(rhs) => Ok(Box::new([<$lib MDR3>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
655 Matrix::RowVector4(rhs) => Ok(Box::new([<$lib MDR4>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
656 Matrix::RowDVector(rhs) => Ok(Box::new([<$lib MDRD>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
657 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
658 }
659 },
660 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
662 (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))})),
663 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
664 (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))})),
665 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
666 (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))})),
667 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
668 (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))})),
669 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
670 (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))})),
671 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
673 (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))})),
674 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
675 (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))})),
676 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
677 (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))})),
678 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
679 (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))})),
680 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
681 (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))})),
682 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
683 (Value::$matrix_kind(lhs),Value::$matrix_kind(Matrix::DMatrix(rhs))) => {
684 let (rows,cols) = {rhs.borrow().shape()};
685 let lhs_shape = lhs.shape();
686 match (lhs_shape[0],lhs_shape[1],rows,cols) {
687 (m,1,n,_) if n == m => (),
689 (1,m,_,n) if n == m => (),
691 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
693 }
694 match lhs {
695 Matrix::Vector2(lhs) => Ok(Box::new([<$lib V2MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
696 Matrix::Vector3(lhs) => Ok(Box::new([<$lib V3MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
697 Matrix::Vector4(lhs) => Ok(Box::new([<$lib V4MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
698 Matrix::DVector(lhs) => Ok(Box::new([<$lib VDMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
699 Matrix::RowVector2(lhs) => Ok(Box::new([<$lib R2MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
700 Matrix::RowVector3(lhs) => Ok(Box::new([<$lib R3MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
701 Matrix::RowVector4(lhs) => Ok(Box::new([<$lib R4MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
702 Matrix::RowDVector(lhs) => Ok(Box::new([<$lib RDMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
703 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
704 }
705 }
706 )+
707 )+
708 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
709 }
710 }
711 }
712}
713
714#[macro_export]
715macro_rules! impl_urnop_match_arms {
716 ($lib:ident, $arg:expr, $($lhs_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
717 paste!{
718 match $arg {
719 $(
720 $(
721 (Value::$lhs_type(arg)) => Ok(Box::new([<$lib S>]{arg: arg.clone(), out: new_ref($default) })),
722 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
723 (Value::$matrix_kind(Matrix::Matrix1(arg))) => Ok(Box::new([<$lib M1>]{arg, out: new_ref(Matrix1::from_element($default))})),
724 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
725 (Value::$matrix_kind(Matrix::Matrix2(arg))) => Ok(Box::new([<$lib M2>]{arg, out: new_ref(Matrix2::from_element($default))})),
726 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
727 (Value::$matrix_kind(Matrix::Matrix3(arg))) => Ok(Box::new([<$lib M3>]{arg, out: new_ref(Matrix3::from_element($default))})),
728 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
729 (Value::$matrix_kind(Matrix::Matrix4(arg))) => Ok(Box::new([<$lib M4>]{arg, out: new_ref(Matrix4::from_element($default))})),
730 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
731 (Value::$matrix_kind(Matrix::Matrix2x3(arg))) => Ok(Box::new([<$lib M2x3>]{arg, out: new_ref(Matrix2x3::from_element($default))})),
732 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
733 (Value::$matrix_kind(Matrix::Matrix3x2(arg))) => Ok(Box::new([<$lib M3x2>]{arg, out: new_ref(Matrix3x2::from_element($default))})),
734 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
735 (Value::$matrix_kind(Matrix::RowVector2(arg))) => Ok(Box::new([<$lib R2>]{arg: arg.clone(), out: new_ref(RowVector2::from_element($default)) })),
736 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
737 (Value::$matrix_kind(Matrix::RowVector3(arg))) => Ok(Box::new([<$lib R3>]{arg: arg.clone(), out: new_ref(RowVector3::from_element($default)) })),
738 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
739 (Value::$matrix_kind(Matrix::RowVector4(arg))) => Ok(Box::new([<$lib R4>]{arg: arg.clone(), out: new_ref(RowVector4::from_element($default)) })),
740 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
741 (Value::$matrix_kind(Matrix::RowDVector(arg))) => Ok(Box::new([<$lib RD>]{arg: arg.clone(), out: new_ref(RowDVector::from_element(arg.borrow().len(),$default))})),
742 #[cfg(all(feature = $value_string, feature = "Vector2"))]
743 (Value::$matrix_kind(Matrix::Vector2(arg))) => Ok(Box::new([<$lib V2>]{arg: arg.clone(), out: new_ref(Vector2::from_element($default)) })),
744 #[cfg(all(feature = $value_string, feature = "Vector3"))]
745 (Value::$matrix_kind(Matrix::Vector3(arg))) => Ok(Box::new([<$lib V3>]{arg: arg.clone(), out: new_ref(Vector3::from_element($default)) })),
746 #[cfg(all(feature = $value_string, feature = "Vector4"))]
747 (Value::$matrix_kind(Matrix::Vector4(arg))) => Ok(Box::new([<$lib V4>]{arg: arg.clone(), out: new_ref(Vector4::from_element($default)) })),
748 #[cfg(all(feature = $value_string, feature = "VectorD"))]
749 (Value::$matrix_kind(Matrix::DVector(arg))) => Ok(Box::new([<$lib VD>]{arg: arg.clone(), out: new_ref(DVector::from_element(arg.borrow().len(),$default))})),
750 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
751 (Value::$matrix_kind(Matrix::DMatrix(arg))) => {
752 let (rows,cols) = {arg.borrow().shape()};
753 Ok(Box::new([<$lib MD>]{arg, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
754 )+
755 )+
756 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
757 }
758 }
759 }
760}
761
762#[macro_export]
763macro_rules! impl_mech_binop_fxn {
764 ($fxn_name:ident, $gen_fxn:ident) => {
765 pub struct $fxn_name {}
766 impl NativeFunctionCompiler for $fxn_name {
767 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
768 if arguments.len() != 2 {
769 return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
770 }
771 let lhs_value = arguments[0].clone();
772 let rhs_value = arguments[1].clone();
773 match $gen_fxn(lhs_value.clone(), rhs_value.clone()) {
774 Ok(fxn) => Ok(fxn),
775 Err(_) => {
776 match (lhs_value,rhs_value) {
777 (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {$gen_fxn(lhs.borrow().clone(), rhs.borrow().clone())}
778 (lhs_value,Value::MutableReference(rhs)) => { $gen_fxn(lhs_value.clone(), rhs.borrow().clone())}
779 (Value::MutableReference(lhs),rhs_value) => { $gen_fxn(lhs.borrow().clone(), rhs_value.clone()) }
780 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
781 }
782 }
783 }
784 }
785 }
786 }
787}
788
789#[macro_export]
790macro_rules! impl_mech_urnop_fxn {
791 ($fxn_name:ident, $gen_fxn:ident) => {
792 pub struct $fxn_name {}
793 impl NativeFunctionCompiler for $fxn_name {
794 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
795 if arguments.len() != 1 {
796 return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
797 }
798 let input = arguments[0].clone();
799 match $gen_fxn(input.clone()) {
800 Ok(fxn) => Ok(fxn),
801 Err(_) => {
802 match (input) {
803 (Value::MutableReference(input)) => {$gen_fxn(input.borrow().clone())}
804 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
805 }
806 }
807 }
808 }
809 }
810 }
811}