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}
91
92pub const WORDLIST: &[&str;256] = &[
93 "nil", "ama", "ine", "ska", "pha", "gel", "art",
94 "ona", "sas", "ist", "aus", "pen", "ust", "umn",
95 "ado", "con", "loo", "man", "eer", "lin", "ium",
96 "ack", "som", "lue", "ird", "avo", "dog", "ger",
97 "ter", "nia", "bon", "nal", "ina", "pet", "cat",
98 "ing", "lie", "ken", "fee", "ola", "old", "rad",
99 "met", "cut", "azy", "cup", "ota", "dec", "del",
100 "elt", "iet", "don", "ble", "ear", "rth", "eas",
101 "war", "eig", "tee", "ele", "emm", "ene", "qua",
102 "tst", "fan", "fif", "fil", "fin", "fis", "fiv",
103 "flo", "for", "foo", "fou", "fot", "fox", "fre",
104 "fri", "fru", "gee", "gia", "glu", "fol", "gre",
105 "ham", "hap", "har", "haw", "hel", "hig", "hot",
106 "hyd", "ida", "ill", "ind", "ini", "ink", "iwa",
107 "and", "ite", "jer", "jig", "joh", "jul", "uly",
108 "kan", "ket", "kil", "kin", "kit", "lac", "lak",
109 "lem", "ard", "lim", "lio", "lit", "lon", "lou",
110 "low", "mag", "nes", "mai", "gam", "arc", "mar",
111 "mao", "mas", "may", "mex", "mic", "mik", "ril",
112 "min", "mir", "mis", "mio", "mob", "moc", "ech",
113 "moe", "tan", "oon", "ain", "mup", "sic", "neb",
114 "une", "net", "nev", "nin", "een", "nit", "nor",
115 "nov", "nut", "oct", "ohi", "okl", "one", "ora",
116 "ges", "ore", "osc", "ove", "oxy", "pap", "par",
117 "pey", "pip", "piz", "plu", "pot", "pri", "pur",
118 "que", "uqi", "qui", "red", "riv", "rob", "roi",
119 "rug", "sad", "sal", "sat", "sep", "sev", "eve",
120 "sha", "sie", "sin", "sik", "six", "sit", "sky",
121 "soc", "sod", "sol", "sot", "tir", "ker", "spr",
122 "sta", "ste", "mam", "mer", "swe", "tab", "tag",
123 "see", "nis", "tex", "thi", "the", "tim", "tri",
124 "twe", "ent", "two", "unc", "ess", "uni", "ura",
125 "veg", "ven", "ver", "vic", "vid", "vio", "vir",
126 "was", "est", "whi", "hit", "iam", "win", "his",
127 "wis", "olf", "wyo", "ray", "ank", "yel", "zeb",
128 "ulu", "fix", "gry", "hol", "jup", "lam", "pas",
129 "rom", "sne", "ten", "uta"];
130
131#[macro_export]
136macro_rules! impl_binop {
137 ($struct_name:ident, $arg1_type:ty, $arg2_type:ty, $out_type:ty, $op:ident) => {
138 #[derive(Debug)]
139 struct $struct_name<T> {
140 lhs: Ref<$arg1_type>,
141 rhs: Ref<$arg2_type>,
142 out: Ref<$out_type>,
143 }
144 impl<T> MechFunction for $struct_name<T>
145 where
146 T: Copy + Debug + Clone + Sync + Send + 'static +
147 PartialEq + PartialOrd +
148 Add<Output = T> + AddAssign +
149 Sub<Output = T> + SubAssign +
150 Mul<Output = T> + MulAssign +
151 Div<Output = T> + DivAssign +
152 Zero + One,
153 Ref<$out_type>: ToValue
154 {
155 fn solve(&self) {
156 let lhs_ptr = self.lhs.as_ptr();
157 let rhs_ptr = self.rhs.as_ptr();
158 let out_ptr = self.out.as_ptr();
159 $op!(lhs_ptr,rhs_ptr,out_ptr);
160 }
161 fn out(&self) -> Value { self.out.to_value() }
162 fn to_string(&self) -> String { format!("{:#?}", self) }
163 }};}
164
165#[macro_export]
166macro_rules! impl_bool_binop {
167 ($struct_name:ident, $arg1_type:ty, $arg2_type:ty, $out_type:ty, $op:ident) => {
168 #[derive(Debug)]
169 struct $struct_name<T> {
170 lhs: Ref<$arg1_type>,
171 rhs: Ref<$arg2_type>,
172 out: Ref<$out_type>,
173 }
174 impl<T> MechFunction for $struct_name<T>
175 where
176 T: Copy + Debug + Clone + Sync + Send + 'static +
177 PartialEq + PartialOrd,
178 Ref<$out_type>: ToValue
179 {
180 fn solve(&self) {
181 let lhs_ptr = self.lhs.as_ptr();
182 let rhs_ptr = self.rhs.as_ptr();
183 let out_ptr = self.out.as_ptr();
184 $op!(lhs_ptr,rhs_ptr,out_ptr);
185 }
186 fn out(&self) -> Value { self.out.to_value() }
187 fn to_string(&self) -> String { format!("{:#?}", self) }
188 }};}
189
190#[macro_export]
191macro_rules! impl_bool_urop {
192 ($struct_name:ident, $arg_type:ty, $out_type:ty, $op:ident) => {
193 #[derive(Debug)]
194 struct $struct_name<T> {
195 arg: Ref<$arg_type>,
196 out: Ref<$out_type>,
197 }
198 impl<T> MechFunction for $struct_name<T>
199 where
200 T: Copy + Debug + Clone + Sync + Send + 'static +
201 PartialEq + PartialOrd,
202 Ref<$out_type>: ToValue
203 {
204 fn solve(&self) {
205 let arg_ptr = self.arg.as_ptr();
206 let out_ptr = self.out.as_ptr();
207 $op!(arg_ptr,out_ptr);
208 }
209 fn out(&self) -> Value { self.out.to_value() }
210 fn to_string(&self) -> String { format!("{:#?}", self) }
211 }};}
212
213#[macro_export]
214macro_rules! impl_urop {
215 ($struct_name:ident, $arg_type:ty, $out_type:ty, $op:ident) => {
216 #[derive(Debug)]
217 struct $struct_name {
218 arg: Ref<$arg_type>,
219 out: Ref<$out_type>,
220 }
221 impl MechFunction for $struct_name {
222 fn solve(&self) {
223 let arg_ptr = self.arg.as_ptr();
224 let out_ptr = self.out.as_ptr();
225 $op!(arg_ptr,out_ptr);
226 }
227 fn out(&self) -> Value { self.out.to_value() }
228 fn to_string(&self) -> String { format!("{:#?}", self) }
229 }};}
230
231#[macro_export]
232macro_rules! impl_fxns {
233 ($lib:ident, $in:ident, $out:ident, $op:ident) => {
234 paste!{
235 $op!([<$lib SS>], $in, $in, $out, [<$lib:lower _op>]);
237 #[cfg(feature = "Matrix1")]
239 $op!([<$lib SM1>], $in, Matrix1<$in>, Matrix1<$out>,[<$lib:lower _scalar_rhs_op>]);
240 #[cfg(feature = "Matrix2")]
241 $op!([<$lib SM2>], $in, Matrix2<$in>, Matrix2<$out>,[<$lib:lower _scalar_rhs_op>]);
242 #[cfg(feature = "Matrix3")]
243 $op!([<$lib SM3>], $in, Matrix3<$in>, Matrix3<$out>,[<$lib:lower _scalar_rhs_op>]);
244 #[cfg(feature = "Matrix4")]
245 $op!([<$lib SM4>], $in, Matrix4<$in>, Matrix4<$out>,[<$lib:lower _scalar_rhs_op>]);
246 #[cfg(feature = "Matrix2x3")]
247 $op!([<$lib SM2x3>], $in, Matrix2x3<$in>, Matrix2x3<$out>,[<$lib:lower _scalar_rhs_op>]);
248 #[cfg(feature = "Matrix3x2")]
249 $op!([<$lib SM3x2>], $in, Matrix3x2<$in>, Matrix3x2<$out>,[<$lib:lower _scalar_rhs_op>]);
250 #[cfg(feature = "MatrixD")]
251 $op!([<$lib SMD>], $in, DMatrix<$in>, DMatrix<$out>,[<$lib:lower _scalar_rhs_op>]);
252 #[cfg(feature = "RowVector2")]
254 $op!([<$lib SR2>], $in, RowVector2<$in>, RowVector2<$out>,[<$lib:lower _scalar_rhs_op>]);
255 #[cfg(feature = "RowVector3")]
256 $op!([<$lib SR3>], $in, RowVector3<$in>, RowVector3<$out>,[<$lib:lower _scalar_rhs_op>]);
257 #[cfg(feature = "RowVector4")]
258 $op!([<$lib SR4>], $in, RowVector4<$in>, RowVector4<$out>,[<$lib:lower _scalar_rhs_op>]);
259 #[cfg(feature = "RowVectorD")]
260 $op!([<$lib SRD>], $in, RowDVector<$in>, RowDVector<$out>,[<$lib:lower _scalar_rhs_op>]);
261 #[cfg(feature = "Vector2")]
263 $op!([<$lib SV2>], $in, Vector2<$in>, Vector2<$out>,[<$lib:lower _scalar_rhs_op>]);
264 #[cfg(feature = "Vector3")]
265 $op!([<$lib SV3>], $in, Vector3<$in>, Vector3<$out>,[<$lib:lower _scalar_rhs_op>]);
266 #[cfg(feature = "Vector4")]
267 $op!([<$lib SV4>], $in, Vector4<$in>, Vector4<$out>,[<$lib:lower _scalar_rhs_op>]);
268 #[cfg(feature = "VectorD")]
269 $op!([<$lib SVD>], $in, DVector<$in>, DVector<$out>,[<$lib:lower _scalar_rhs_op>]);
270 #[cfg(feature = "Matrix1")]
272 $op!([<$lib M1S>], Matrix1<$in>, $in, Matrix1<$out>,[<$lib:lower _scalar_lhs_op>]);
273 #[cfg(feature = "Matrix2")]
274 $op!([<$lib M2S>], Matrix2<$in>, $in, Matrix2<$out>,[<$lib:lower _scalar_lhs_op>]);
275 #[cfg(feature = "Matrix3")]
276 $op!([<$lib M3S>], Matrix3<$in>, $in, Matrix3<$out>,[<$lib:lower _scalar_lhs_op>]);
277 #[cfg(feature = "Matrix4")]
278 $op!([<$lib M4S>], Matrix4<$in>, $in, Matrix4<$out>,[<$lib:lower _scalar_lhs_op>]);
279 #[cfg(feature = "Matrix2x3")]
280 $op!([<$lib M2x3S>], Matrix2x3<$in>, $in, Matrix2x3<$out>,[<$lib:lower _scalar_lhs_op>]);
281 #[cfg(feature = "Matrix3x2")]
282 $op!([<$lib M3x2S>], Matrix3x2<$in>, $in, Matrix3x2<$out>,[<$lib:lower _scalar_lhs_op>]);
283 #[cfg(feature = "MatrixD")]
284 $op!([<$lib MDS>], DMatrix<$in>, $in, DMatrix<$out>,[<$lib:lower _scalar_lhs_op>]);
285 #[cfg(feature = "RowVector2")]
287 $op!([<$lib R2S>], RowVector2<$in>, $in, RowVector2<$out>,[<$lib:lower _scalar_lhs_op>]);
288 #[cfg(feature = "RowVector3")]
289 $op!([<$lib R3S>], RowVector3<$in>, $in, RowVector3<$out>,[<$lib:lower _scalar_lhs_op>]);
290 #[cfg(feature = "RowVector4")]
291 $op!([<$lib R4S>], RowVector4<$in>, $in, RowVector4<$out>,[<$lib:lower _scalar_lhs_op>]);
292 #[cfg(feature = "RowVectorD")]
293 $op!([<$lib RDS>], RowDVector<$in>, $in, RowDVector<$out>,[<$lib:lower _scalar_lhs_op>]);
294 #[cfg(feature = "Vector2")]
296 $op!([<$lib V2S>], Vector2<$in>, $in, Vector2<$out>,[<$lib:lower _scalar_lhs_op>]);
297 #[cfg(feature = "Vector3")]
298 $op!([<$lib V3S>], Vector3<$in>, $in, Vector3<$out>,[<$lib:lower _scalar_lhs_op>]);
299 #[cfg(feature = "Vector4")]
300 $op!([<$lib V4S>], Vector4<$in>, $in, Vector4<$out>,[<$lib:lower _scalar_lhs_op>]);
301 #[cfg(feature = "VectorD")]
302 $op!([<$lib VDS>], DVector<$in>, $in, DVector<$out>,[<$lib:lower _scalar_lhs_op>]);
303 #[cfg(feature = "Matrix1")]
305 $op!([<$lib M1M1>], Matrix1<$in>, Matrix1<$in>, Matrix1<$out>, [<$lib:lower _vec_op>]);
306 #[cfg(feature = "Matrix2")]
307 $op!([<$lib M2M2>], Matrix2<$in>, Matrix2<$in>, Matrix2<$out>, [<$lib:lower _vec_op>]);
308 #[cfg(feature = "Matrix3")]
309 $op!([<$lib M3M3>], Matrix3<$in>, Matrix3<$in>, Matrix3<$out>, [<$lib:lower _vec_op>]);
310 #[cfg(feature = "Matrix4")]
311 $op!([<$lib M4M4>], Matrix4<$in>, Matrix4<$in>, Matrix4<$out>, [<$lib:lower _vec_op>]);
312 #[cfg(feature = "Matrix2x3")]
313 $op!([<$lib M2x3M2x3>], Matrix2x3<$in>, Matrix2x3<$in>, Matrix2x3<$out>, [<$lib:lower _vec_op>]);
314 #[cfg(feature = "Matrix3x2")]
315 $op!([<$lib M3x2M3x2>], Matrix3x2<$in>, Matrix3x2<$in>, Matrix3x2<$out>, [<$lib:lower _vec_op>]);
316 #[cfg(feature = "MatrixD")]
317 $op!([<$lib MDMD>], DMatrix<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_op>]);
318 #[cfg(feature = "Matrix2")]
320 $op!([<$lib M2V2>], Matrix2<$in>, Vector2<$in>, Matrix2<$out>, [<$lib:lower _mat_vec_op>]);
321 #[cfg(feature = "Matrix3")]
322 $op!([<$lib M3V3>], Matrix3<$in>, Vector3<$in>, Matrix3<$out>, [<$lib:lower _mat_vec_op>]);
323 #[cfg(feature = "Matrix4")]
324 $op!([<$lib M4V4>], Matrix4<$in>, Vector4<$in>, Matrix4<$out>, [<$lib:lower _mat_vec_op>]);
325 #[cfg(feature = "Matrix2x3")]
326 $op!([<$lib M2x3V2>], Matrix2x3<$in>, Vector2<$in>, Matrix2x3<$out>, [<$lib:lower _mat_vec_op>]);
327 #[cfg(feature = "Matrix3x2")]
328 $op!([<$lib M3x2V3>], Matrix3x2<$in>, Vector3<$in>, Matrix3x2<$out>, [<$lib:lower _mat_vec_op>]);
329 #[cfg(feature = "MatrixD")]
330 $op!([<$lib MDVD>], DMatrix<$in>, DVector<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>]);
331 #[cfg(feature = "MatrixD")]
332 $op!([<$lib MDV2>], DMatrix<$in>, Vector2<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>]);
333 #[cfg(feature = "MatrixD")]
334 $op!([<$lib MDV3>], DMatrix<$in>, Vector3<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>]);
335 #[cfg(feature = "MatrixD")]
336 $op!([<$lib MDV4>], DMatrix<$in>, Vector4<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>]);
337 #[cfg(feature = "Vector2")]
339 $op!([<$lib V2M2>], Vector2<$in>, Matrix2<$in>, Matrix2<$out>, [<$lib:lower _vec_mat_op>]);
340 #[cfg(feature = "Vector3")]
341 $op!([<$lib V3M3>], Vector3<$in>, Matrix3<$in>, Matrix3<$out>, [<$lib:lower _vec_mat_op>]);
342 #[cfg(feature = "Vector4")]
343 $op!([<$lib V4M4>], Vector4<$in>, Matrix4<$in>, Matrix4<$out>, [<$lib:lower _vec_mat_op>]);
344 #[cfg(feature = "Vector2")]
345 $op!([<$lib V2M2x3>], Vector2<$in>, Matrix2x3<$in>, Matrix2x3<$out>, [<$lib:lower _vec_mat_op>]);
346 #[cfg(feature = "Vector3")]
347 $op!([<$lib V3M3x2>], Vector3<$in>, Matrix3x2<$in>, Matrix3x2<$out>, [<$lib:lower _vec_mat_op>]);
348 #[cfg(feature = "VectorD")]
349 $op!([<$lib VDMD>], DVector<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>]);
350 #[cfg(feature = "Vector2")]
351 $op!([<$lib V2MD>], Vector2<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>]);
352 #[cfg(feature = "Vector3")]
353 $op!([<$lib V3MD>], Vector3<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>]);
354 #[cfg(feature = "Vector4")]
355 $op!([<$lib V4MD>], Vector4<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>]);
356 #[cfg(feature = "Matrix2")]
358 $op!([<$lib M2R2>], Matrix2<$in>, RowVector2<$in>, Matrix2<$out>, [<$lib:lower _mat_row_op>]);
359 #[cfg(feature = "Matrix3")]
360 $op!([<$lib M3R3>], Matrix3<$in>, RowVector3<$in>, Matrix3<$out>, [<$lib:lower _mat_row_op>]);
361 #[cfg(feature = "Matrix4")]
362 $op!([<$lib M4R4>], Matrix4<$in>, RowVector4<$in>, Matrix4<$out>, [<$lib:lower _mat_row_op>]);
363 #[cfg(feature = "Matrix2x3")]
364 $op!([<$lib M2x3R3>], Matrix2x3<$in>, RowVector3<$in>, Matrix2x3<$out>, [<$lib:lower _mat_row_op>]);
365 #[cfg(feature = "Matrix3x2")]
366 $op!([<$lib M3x2R2>], Matrix3x2<$in>, RowVector2<$in>, Matrix3x2<$out>, [<$lib:lower _mat_row_op>]);
367 #[cfg(feature = "MatrixD")]
368 $op!([<$lib MDRD>], DMatrix<$in>, RowDVector<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>]);
369 #[cfg(feature = "MatrixD")]
370 $op!([<$lib MDR2>], DMatrix<$in>, RowVector2<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>]);
371 #[cfg(feature = "MatrixD")]
372 $op!([<$lib MDR3>], DMatrix<$in>, RowVector3<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>]);
373 #[cfg(feature = "MatrixD")]
374 $op!([<$lib MDR4>], DMatrix<$in>, RowVector4<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>]);
375 #[cfg(feature = "RowVector2")]
377 $op!([<$lib R2M2>], RowVector2<$in>, Matrix2<$in>, Matrix2<$out>, [<$lib:lower _row_mat_op>]);
378 #[cfg(feature = "RowVector3")]
379 $op!([<$lib R3M3>], RowVector3<$in>, Matrix3<$in>, Matrix3<$out>, [<$lib:lower _row_mat_op>]);
380 #[cfg(feature = "RowVector4")]
381 $op!([<$lib R4M4>], RowVector4<$in>, Matrix4<$in>, Matrix4<$out>, [<$lib:lower _row_mat_op>]);
382 #[cfg(feature = "RowVector3")]
383 $op!([<$lib R3M2x3>], RowVector3<$in>, Matrix2x3<$in>, Matrix2x3<$out>, [<$lib:lower _row_mat_op>]);
384 #[cfg(feature = "RowVector2")]
385 $op!([<$lib R2M3x2>], RowVector2<$in>, Matrix3x2<$in>, Matrix3x2<$out>, [<$lib:lower _row_mat_op>]);
386 #[cfg(feature = "RowVectorD")]
387 $op!([<$lib RDMD>], RowDVector<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>]);
388 #[cfg(feature = "RowVector2")]
389 $op!([<$lib R2MD>], RowVector2<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>]);
390 #[cfg(feature = "RowVector3")]
391 $op!([<$lib R3MD>], RowVector3<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>]);
392 #[cfg(feature = "RowVector4")]
393 $op!([<$lib R4MD>], RowVector4<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>]);
394 #[cfg(feature = "RowVector2")]
396 $op!([<$lib R2R2>], RowVector2<$in>, RowVector2<$in>, RowVector2<$out>, [<$lib:lower _vec_op>]);
397 #[cfg(feature = "RowVector3")]
398 $op!([<$lib R3R3>], RowVector3<$in>, RowVector3<$in>, RowVector3<$out>, [<$lib:lower _vec_op>]);
399 #[cfg(feature = "RowVector4")]
400 $op!([<$lib R4R4>], RowVector4<$in>, RowVector4<$in>, RowVector4<$out>, [<$lib:lower _vec_op>]);
401 #[cfg(feature = "RowVectorD")]
402 $op!([<$lib RDRD>], RowDVector<$in>, RowDVector<$in>, RowDVector<$out>, [<$lib:lower _vec_op>]);
403 #[cfg(feature = "Vector2")]
405 $op!([<$lib V2V2>], Vector2<$in>, Vector2<$in>, Vector2<$out>, [<$lib:lower _vec_op>]);
406 #[cfg(feature = "Vector3")]
407 $op!([<$lib V3V3>], Vector3<$in>, Vector3<$in>, Vector3<$out>, [<$lib:lower _vec_op>]);
408 #[cfg(feature = "Vector4")]
409 $op!([<$lib V4V4>], Vector4<$in>, Vector4<$in>, Vector4<$out>, [<$lib:lower _vec_op>]);
410 #[cfg(feature = "VectorD")]
411 $op!([<$lib VDVD>], DVector<$in>, DVector<$in>, DVector<$out>, [<$lib:lower _vec_op>]);
412 }
413 }}
414
415#[macro_export]
416macro_rules! impl_binop_match_arms {
417 ($lib:ident, $arg:expr, $($lhs_type:ident, $rhs_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
418 paste!{
419 match $arg {
420 $(
421 $(
422 (Value::$lhs_type(lhs), Value::$rhs_type(rhs)) => Ok(Box::new([<$lib SS>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref($default) })),
424 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
426 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix1(rhs))) => Ok(Box::new([<$lib SM1>]{lhs, rhs, out: new_ref(Matrix1::from_element($default))})),
427 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
428 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix2(rhs))) => Ok(Box::new([<$lib SM2>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))})),
429 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
430 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix3(rhs))) => Ok(Box::new([<$lib SM3>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))})),
431 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
432 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix4(rhs))) => Ok(Box::new([<$lib SM4>]{lhs, rhs, out: new_ref(Matrix4::from_element($default))})),
433 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
434 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix2x3(rhs))) => Ok(Box::new([<$lib SM2x3>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))})),
435 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
436 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Matrix3x2(rhs))) => Ok(Box::new([<$lib SM3x2>]{lhs, rhs, out: new_ref(Matrix3x2::from_element($default))})),
437 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
438 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::DMatrix(rhs))) => {
439 let (rows,cols) = {rhs.borrow().shape()};
440 Ok(Box::new([<$lib SMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
441 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
443 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::RowVector2(rhs))) => Ok(Box::new([<$lib SR2>]{lhs, rhs, out: new_ref(RowVector2::from_element($default))})),
444 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
445 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::RowVector3(rhs))) => Ok(Box::new([<$lib SR3>]{lhs, rhs, out: new_ref(RowVector3::from_element($default))})),
446 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
447 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::RowVector4(rhs))) => Ok(Box::new([<$lib SR4>]{lhs, rhs, out: new_ref(RowVector4::from_element($default))})),
448 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
449 (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))})),
450 #[cfg(all(feature = $value_string, feature = "Vector2"))]
452 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Vector2(rhs))) => Ok(Box::new([<$lib SV2>]{lhs, rhs, out: new_ref(Vector2::from_element($default))})),
453 #[cfg(all(feature = $value_string, feature = "Vector3"))]
454 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Vector3(rhs))) => Ok(Box::new([<$lib SV3>]{lhs, rhs, out: new_ref(Vector3::from_element($default))})),
455 #[cfg(all(feature = $value_string, feature = "Vector4"))]
456 (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::Vector4(rhs))) => Ok(Box::new([<$lib SV4>]{lhs, rhs, out: new_ref(Vector4::from_element($default))})),
457 #[cfg(all(feature = $value_string, feature = "VectorD"))]
458 (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))})),
459 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
461 (Value::$matrix_kind(Matrix::Matrix1(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M1S>]{lhs, rhs, out: new_ref(Matrix1::from_element($default))})),
462 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
463 (Value::$matrix_kind(Matrix::Matrix2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M2S>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))})),
464 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
465 (Value::$matrix_kind(Matrix::Matrix3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M3S>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))})),
466 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
467 (Value::$matrix_kind(Matrix::Matrix4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M4S>]{lhs, rhs, out: new_ref(Matrix4::from_element($default))})),
468 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
469 (Value::$matrix_kind(Matrix::Matrix2x3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M2x3S>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))})),
470 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
471 (Value::$matrix_kind(Matrix::Matrix3x2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M3x2S>]{lhs, rhs, out: new_ref(Matrix3x2::from_element($default))})),
472 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
473 (Value::$matrix_kind(Matrix::DMatrix(lhs)),Value::$lhs_type(rhs)) => {
474 let (rows,cols) = {lhs.borrow().shape()};
475 Ok(Box::new([<$lib MDS>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
476 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
478 (Value::$matrix_kind(Matrix::RowVector2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R2S>]{lhs, rhs, out: new_ref(RowVector2::from_element($default))})),
479 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
480 (Value::$matrix_kind(Matrix::RowVector3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R3S>]{lhs, rhs, out: new_ref(RowVector3::from_element($default))})),
481 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
482 (Value::$matrix_kind(Matrix::RowVector4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R4S>]{lhs, rhs, out: new_ref(RowVector4::from_element($default))})),
483 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
484 (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))})),
485 #[cfg(all(feature = $value_string, feature = "Vector2"))]
487 (Value::$matrix_kind(Matrix::Vector2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V2S>]{lhs, rhs, out: new_ref(Vector2::from_element($default))})),
488 #[cfg(all(feature = $value_string, feature = "Vector3"))]
489 (Value::$matrix_kind(Matrix::Vector3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V3S>]{lhs, rhs, out: new_ref(Vector3::from_element($default))})),
490 #[cfg(all(feature = $value_string, feature = "Vector4"))]
491 (Value::$matrix_kind(Matrix::Vector4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V4S>]{lhs, rhs, out: new_ref(Vector4::from_element($default))})),
492 #[cfg(all(feature = $value_string, feature = "VectorD"))]
493 (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))})),
494 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
496 (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))})),
497 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
498 (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))})),
499 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
500 (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))})),
501 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
502 (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))})),
503 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
504 (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))})),
505 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
506 (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))})),
507 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
508 (Value::$matrix_kind(Matrix::DMatrix(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => {
509 let (rows,cols) = {lhs.borrow().shape()};
510 Ok(Box::new([<$lib MDMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
511 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
513 (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)) })),
514 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
515 (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)) })),
516 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
517 (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)) })),
518 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
519 (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))})),
520 #[cfg(all(feature = $value_string, feature = "Vector2"))]
522 (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)) })),
523 #[cfg(all(feature = $value_string, feature = "Vector3"))]
524 (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)) })),
525 #[cfg(all(feature = $value_string, feature = "Vector4"))]
526 (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)) })),
527 #[cfg(all(feature = $value_string, feature = "VectorD"))]
528 (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))})),
529 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
531 (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))})),
532 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
533 (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))})),
534 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
535 (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))})),
536 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
537 (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))})),
538 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
539 (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))})),
540 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
541 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
543 (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))})),
544 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
545 (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))})),
546 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
547 (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))})),
548 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
549 (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))})),
550 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
551 (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))})),
552 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
553 (Value::$matrix_kind(Matrix::DMatrix(lhs)),Value::$matrix_kind(rhs)) => {
554 let (rows,cols) = {lhs.borrow().shape()};
555 let rhs_shape = rhs.shape();
556 match (rows,cols,rhs_shape[0],rhs_shape[1]) {
557 (n,_,m,1) if n == m => (),
559 (_,n,1,m) if n == m => (),
561 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
563 }
564 match rhs {
565 Matrix::Vector2(rhs) => Ok(Box::new([<$lib MDV2>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
566 Matrix::Vector3(rhs) => Ok(Box::new([<$lib MDV3>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
567 Matrix::Vector4(rhs) => Ok(Box::new([<$lib MDV4>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
568 Matrix::DVector(rhs) => Ok(Box::new([<$lib MDVD>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
569 Matrix::RowVector2(rhs) => Ok(Box::new([<$lib MDR2>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
570 Matrix::RowVector3(rhs) => Ok(Box::new([<$lib MDR3>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
571 Matrix::RowVector4(rhs) => Ok(Box::new([<$lib MDR4>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
572 Matrix::RowDVector(rhs) => Ok(Box::new([<$lib MDRD>]{lhs: lhs.clone(), rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
573 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
574 }
575 },
576 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
578 (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))})),
579 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
580 (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))})),
581 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
582 (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))})),
583 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
584 (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))})),
585 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
586 (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))})),
587 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
589 (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))})),
590 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
591 (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))})),
592 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
593 (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))})),
594 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
595 (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))})),
596 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
597 (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))})),
598 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
599 (Value::$matrix_kind(lhs),Value::$matrix_kind(Matrix::DMatrix(rhs))) => {
600 let (rows,cols) = {rhs.borrow().shape()};
601 let lhs_shape = lhs.shape();
602 match (lhs_shape[0],lhs_shape[1],rows,cols) {
603 (m,1,n,_) if n == m => (),
605 (1,m,_,n) if n == m => (),
607 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
609 }
610 match lhs {
611 Matrix::Vector2(lhs) => Ok(Box::new([<$lib V2MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
612 Matrix::Vector3(lhs) => Ok(Box::new([<$lib V3MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
613 Matrix::Vector4(lhs) => Ok(Box::new([<$lib V4MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
614 Matrix::DVector(lhs) => Ok(Box::new([<$lib VDMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
615 Matrix::RowVector2(lhs) => Ok(Box::new([<$lib R2MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
616 Matrix::RowVector3(lhs) => Ok(Box::new([<$lib R3MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
617 Matrix::RowVector4(lhs) => Ok(Box::new([<$lib R4MD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
618 Matrix::RowDVector(lhs) => Ok(Box::new([<$lib RDMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))})),
619 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
620 }
621 }
622 )+
623 )+
624 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
625 }
626 }
627 }
628}
629
630#[macro_export]
631macro_rules! impl_urnop_match_arms {
632 ($lib:ident, $arg:expr, $($lhs_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
633 paste!{
634 match $arg {
635 $(
636 $(
637 (Value::$lhs_type(arg)) => Ok(Box::new([<$lib S>]{arg: arg.clone(), out: new_ref($default) })),
638 #[cfg(all(feature = $value_string, feature = "Matrix1"))]
639 (Value::$matrix_kind(Matrix::Matrix1(arg))) => Ok(Box::new([<$lib M1>]{arg, out: new_ref(Matrix1::from_element($default))})),
640 #[cfg(all(feature = $value_string, feature = "Matrix2"))]
641 (Value::$matrix_kind(Matrix::Matrix2(arg))) => Ok(Box::new([<$lib M2>]{arg, out: new_ref(Matrix2::from_element($default))})),
642 #[cfg(all(feature = $value_string, feature = "Matrix3"))]
643 (Value::$matrix_kind(Matrix::Matrix3(arg))) => Ok(Box::new([<$lib M3>]{arg, out: new_ref(Matrix3::from_element($default))})),
644 #[cfg(all(feature = $value_string, feature = "Matrix4"))]
645 (Value::$matrix_kind(Matrix::Matrix4(arg))) => Ok(Box::new([<$lib M4>]{arg, out: new_ref(Matrix4::from_element($default))})),
646 #[cfg(all(feature = $value_string, feature = "Matrix2x3"))]
647 (Value::$matrix_kind(Matrix::Matrix2x3(arg))) => Ok(Box::new([<$lib M2x3>]{arg, out: new_ref(Matrix2x3::from_element($default))})),
648 #[cfg(all(feature = $value_string, feature = "Matrix3x2"))]
649 (Value::$matrix_kind(Matrix::Matrix3x2(arg))) => Ok(Box::new([<$lib M3x2>]{arg, out: new_ref(Matrix3x2::from_element($default))})),
650 #[cfg(all(feature = $value_string, feature = "RowVector2"))]
651 (Value::$matrix_kind(Matrix::RowVector2(arg))) => Ok(Box::new([<$lib R2>]{arg: arg.clone(), out: new_ref(RowVector2::from_element($default)) })),
652 #[cfg(all(feature = $value_string, feature = "RowVector3"))]
653 (Value::$matrix_kind(Matrix::RowVector3(arg))) => Ok(Box::new([<$lib R3>]{arg: arg.clone(), out: new_ref(RowVector3::from_element($default)) })),
654 #[cfg(all(feature = $value_string, feature = "RowVector4"))]
655 (Value::$matrix_kind(Matrix::RowVector4(arg))) => Ok(Box::new([<$lib R4>]{arg: arg.clone(), out: new_ref(RowVector4::from_element($default)) })),
656 #[cfg(all(feature = $value_string, feature = "RowVectorD"))]
657 (Value::$matrix_kind(Matrix::RowDVector(arg))) => Ok(Box::new([<$lib RD>]{arg: arg.clone(), out: new_ref(RowDVector::from_element(arg.borrow().len(),$default))})),
658 #[cfg(all(feature = $value_string, feature = "Vector2"))]
659 (Value::$matrix_kind(Matrix::Vector2(arg))) => Ok(Box::new([<$lib V2>]{arg: arg.clone(), out: new_ref(Vector2::from_element($default)) })),
660 #[cfg(all(feature = $value_string, feature = "Vector3"))]
661 (Value::$matrix_kind(Matrix::Vector3(arg))) => Ok(Box::new([<$lib V3>]{arg: arg.clone(), out: new_ref(Vector3::from_element($default)) })),
662 #[cfg(all(feature = $value_string, feature = "Vector4"))]
663 (Value::$matrix_kind(Matrix::Vector4(arg))) => Ok(Box::new([<$lib V4>]{arg: arg.clone(), out: new_ref(Vector4::from_element($default)) })),
664 #[cfg(all(feature = $value_string, feature = "VectorD"))]
665 (Value::$matrix_kind(Matrix::DVector(arg))) => Ok(Box::new([<$lib VD>]{arg: arg.clone(), out: new_ref(DVector::from_element(arg.borrow().len(),$default))})),
666 #[cfg(all(feature = $value_string, feature = "MatrixD"))]
667 (Value::$matrix_kind(Matrix::DMatrix(arg))) => {
668 let (rows,cols) = {arg.borrow().shape()};
669 Ok(Box::new([<$lib MD>]{arg, out: new_ref(DMatrix::from_element(rows,cols,$default))}))},
670 )+
671 )+
672 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
673 }
674 }
675 }
676}
677
678#[macro_export]
679macro_rules! impl_mech_binop_fxn {
680 ($fxn_name:ident, $gen_fxn:ident) => {
681 pub struct $fxn_name {}
682 impl NativeFunctionCompiler for $fxn_name {
683 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
684 if arguments.len() != 2 {
685 return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
686 }
687 let lhs_value = arguments[0].clone();
688 let rhs_value = arguments[1].clone();
689 match $gen_fxn(lhs_value.clone(), rhs_value.clone()) {
690 Ok(fxn) => Ok(fxn),
691 Err(_) => {
692 match (lhs_value,rhs_value) {
693 (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {$gen_fxn(lhs.borrow().clone(), rhs.borrow().clone())}
694 (lhs_value,Value::MutableReference(rhs)) => { $gen_fxn(lhs_value.clone(), rhs.borrow().clone())}
695 (Value::MutableReference(lhs),rhs_value) => { $gen_fxn(lhs.borrow().clone(), rhs_value.clone()) }
696 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
697 }
698 }
699 }
700 }
701 }
702 }
703}
704
705#[macro_export]
706macro_rules! impl_mech_urnop_fxn {
707 ($fxn_name:ident, $gen_fxn:ident) => {
708 pub struct $fxn_name {}
709 impl NativeFunctionCompiler for $fxn_name {
710 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
711 if arguments.len() != 1 {
712 return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
713 }
714 let input = arguments[0].clone();
715 match $gen_fxn(input.clone()) {
716 Ok(fxn) => Ok(fxn),
717 Err(_) => {
718 match (input) {
719 (Value::MutableReference(input)) => {$gen_fxn(input.borrow().clone())}
720 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
721 }
722 }
723 }
724 }
725 }
726 }
727}