mech_core/
value.rs

1use crate::*;
2use crate::nodes::Matrix as Mat;
3#[cfg(feature = "matrix")]
4use crate::matrix::Matrix;
5#[cfg(feature = "complex")]
6use crate::types::complex_numbers::C64;
7#[cfg(feature = "rational")]
8use num_rational::Rational64;
9
10#[cfg(feature = "no_std")]
11use core::mem;
12#[cfg(not(feature = "no_std"))]
13use std::mem;
14
15#[cfg(feature = "matrix")]
16use nalgebra::DVector;
17
18macro_rules! impl_as_type {
19  ($target_type:ty) => {
20    paste!{
21      pub fn [<as_ $target_type>](&self) -> MResult<Ref<$target_type>> {
22        match self {
23          #[cfg(feature = "u8")]
24          Value::U8(v) => Ok(Ref::new(*v.borrow() as $target_type)),
25          #[cfg(feature = "u16")]
26          Value::U16(v) => Ok(Ref::new(*v.borrow() as $target_type)),
27          #[cfg(feature = "u32")]
28          Value::U32(v) => Ok(Ref::new(*v.borrow() as $target_type)),
29          #[cfg(feature = "u64")]
30          Value::U64(v) => Ok(Ref::new(*v.borrow() as $target_type)),
31          #[cfg(feature = "u128")]
32          Value::U128(v) => Ok(Ref::new(*v.borrow() as $target_type)),
33          #[cfg(feature = "i8")]
34          Value::I8(v) => Ok(Ref::new(*v.borrow() as $target_type)),
35          #[cfg(feature = "i16")]
36          Value::I16(v) => Ok(Ref::new(*v.borrow() as $target_type)),
37          #[cfg(feature = "i32")]
38          Value::I32(v) => Ok(Ref::new(*v.borrow() as $target_type)),
39          #[cfg(feature = "i64")]
40          Value::I64(v) => Ok(Ref::new(*v.borrow() as $target_type)),
41          #[cfg(feature = "i128")]
42          Value::I128(v) => Ok(Ref::new(*v.borrow() as $target_type)),
43          #[cfg(feature = "f32")]
44          Value::F32(v) => Ok(Ref::new((*v.borrow()).0 as $target_type)),
45          #[cfg(feature = "f64")]
46          Value::F64(v) => Ok(Ref::new((*v.borrow()).0 as $target_type)),
47          Value::Id(v) => Ok(Ref::new(*v as $target_type)),
48          Value::MutableReference(val) => val.borrow().[<as_ $target_type>](),
49          _ => Err(MechError {
50            file: file!().to_string(),
51            tokens: vec![],
52            msg: format!("Cannot convert to {}", stringify!($target_type)),
53            id: line!(),
54            kind: MechErrorKind::UnhandledFunctionArgumentKind,
55          }),
56        }
57      }
58    }
59  };
60}
61
62// Value Kind
63// ----------------------------------------------------------------------------
64
65#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
66#[derive(Clone, Debug, Eq, PartialEq, Hash)]
67pub enum ValueKind {
68  U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, C64, R64,
69  String, Bool, Id, Index, Empty, Any, 
70  Matrix(Box<ValueKind>,Vec<usize>),  Enum(u64),                  Record(Vec<(String,ValueKind)>),
71  Map(Box<ValueKind>,Box<ValueKind>), Atom(u64),                  Table(Vec<(String,ValueKind)>, usize), 
72  Tuple(Vec<ValueKind>),              Reference(Box<ValueKind>),  Set(Box<ValueKind>, Option<usize>), 
73  Option(Box<ValueKind>),
74}
75
76impl Display for ValueKind {
77  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78    match self {
79      ValueKind::R64 => write!(f, "r64"),
80      ValueKind::C64 => write!(f, "c64"),
81      ValueKind::U8 => write!(f, "u8"),
82      ValueKind::U16 => write!(f, "u16"),
83      ValueKind::U32 => write!(f, "u32"),
84      ValueKind::U64 => write!(f, "u64"),
85      ValueKind::U128 => write!(f, "u128"),
86      ValueKind::I8 => write!(f, "i8"),
87      ValueKind::I16 => write!(f, "i16"),
88      ValueKind::I32 => write!(f, "i32"),
89      ValueKind::I64 => write!(f, "i64"),
90      ValueKind::I128 => write!(f, "i128"),
91      ValueKind::F32 => write!(f, "f32"),
92      ValueKind::F64 => write!(f, "f64"),
93      ValueKind::String => write!(f, "string"),
94      ValueKind::Bool => write!(f, "bool"),
95      ValueKind::Matrix(x,s) => write!(f, "[{}]:{}", x, s.iter().map(|s| s.to_string()).collect::<Vec<String>>().join(",")),
96      ValueKind::Enum(x) => write!(f, "{}",x),
97      ValueKind::Set(x,el) => write!(f, "{{{}}}{}", x, el.map_or("".to_string(), |e| format!(":{}", e))),
98      ValueKind::Map(x,y) => write!(f, "{{{}:{}}}",x,y),
99      ValueKind::Record(x) => write!(f, "{{{}}}",x.iter().map(|(i,k)| format!("{}<{}>",i.to_string(),k)).collect::<Vec<String>>().join(" ")),
100      ValueKind::Table(x,y) => {
101        let size_str = if y > &0 { format!(":{}", y) } else { "".to_string() };
102        write!(f, "|{}|{}",x.iter().map(|(i,k)| format!("{}<{}>",i.to_string(),k)).collect::<Vec<String>>().join(" "),size_str)
103      }
104      ValueKind::Tuple(x) => write!(f, "({})",x.iter().map(|x| format!("{}",x)).collect::<Vec<String>>().join(",")),
105      ValueKind::Id => write!(f, "id"),
106      ValueKind::Index => write!(f, "ix"),
107      ValueKind::Reference(x) => write!(f, "{}",x),
108      ValueKind::Atom(x) => write!(f, "`{}",x),
109      ValueKind::Empty => write!(f, "_"),
110      ValueKind::Any => write!(f, "*"),
111      ValueKind::Option(x) => write!(f, "{}?", x),
112    }
113  }
114}
115
116impl ValueKind {
117
118  #[cfg(feature = "compiler")]
119  pub fn to_feature_kind(&self) -> FeatureKind {
120    match self {
121      #[cfg(feature = "i8")]
122      ValueKind::I8 => FeatureKind::I8,
123      #[cfg(feature = "i16")]
124      ValueKind::I16 => FeatureKind::I16,
125      #[cfg(feature = "i32")]
126      ValueKind::I32 => FeatureKind::I32,
127      #[cfg(feature = "i64")]
128      ValueKind::I64 => FeatureKind::I64,
129      #[cfg(feature = "i128")]
130      ValueKind::I128 => FeatureKind::I128,
131      #[cfg(feature = "u8")] 
132      ValueKind::U8 => FeatureKind::U8,
133      #[cfg(feature = "u16")]
134      ValueKind::U16 => FeatureKind::U16,
135      #[cfg(feature = "u32")]
136      ValueKind::U32 => FeatureKind::U32,
137      #[cfg(feature = "u64")]
138      ValueKind::U64 => FeatureKind::U64,
139      #[cfg(feature = "u128")]
140      ValueKind::U128 => FeatureKind::U128,
141      #[cfg(feature = "f32")]
142      ValueKind::F32 => FeatureKind::F32, 
143      #[cfg(feature = "f64")]
144      ValueKind::F64 => FeatureKind::F64,
145      #[cfg(any(feature = "string", feature = "variable_define"))]
146      ValueKind::String => FeatureKind::String,
147      #[cfg(any(feature = "bool", feature = "variable_define"))]
148      ValueKind::Bool => FeatureKind::Bool,
149      #[cfg(feature = "table")]
150      ValueKind::Table(_,_) => FeatureKind::Table,
151      #[cfg(feature = "set")]
152      ValueKind::Set(_,_) => FeatureKind::Set,
153      #[cfg(feature = "map")]
154      ValueKind::Map(_,_) => FeatureKind::Map,
155      #[cfg(feature = "record")]
156      ValueKind::Record(_) => FeatureKind::Record,
157      #[cfg(feature = "tuple")] 
158      ValueKind::Tuple(_) => FeatureKind::Tuple,
159      #[cfg(feature = "enum")]
160      ValueKind::Enum(_) => FeatureKind::Enum,
161      #[cfg(feature = "matrix")]
162      ValueKind::Matrix(_,shape) => {
163        match shape[..] {
164          #[cfg(feature = "matrix1")]
165          [1,1] => FeatureKind::Matrix1,
166          #[cfg(feature = "matrix2")]
167          [2,2] => FeatureKind::Matrix2,
168          #[cfg(feature = "matrix3")]
169          [3,3] => FeatureKind::Matrix3,
170          #[cfg(feature = "matrix4")]
171          [4,4] => FeatureKind::Matrix4,
172          #[cfg(feature = "matrix2x3")]
173          [2,3] => FeatureKind::Matrix2x3,
174          #[cfg(feature = "matrix3x2")]
175          [3,2] => FeatureKind::Matrix3x2,
176          #[cfg(feature = "row_vector2")]
177          [1,2] => FeatureKind::RowVector2,
178          #[cfg(feature = "row_vector3")]
179          [1,3] => FeatureKind::RowVector3,
180          #[cfg(feature = "row_vector4")]
181          [1,4] => FeatureKind::RowVector4,
182          #[cfg(feature = "vector2")]
183          [2,1] => FeatureKind::Vector2,
184          #[cfg(feature = "vector3")]
185          [3,1] => FeatureKind::Vector3,
186          #[cfg(feature = "vector4")]
187          [4,1] => FeatureKind::Vector4,
188          #[cfg(feature = "row_vectord")]
189          [1,n] => FeatureKind::RowVectorD,
190          #[cfg(feature = "vectord")]
191          [n,1] => FeatureKind::VectorD,
192          #[cfg(feature = "matrixd")]
193          [n,m] => FeatureKind::MatrixD,
194          _ => panic!("Unsupported matrix shape for feature kind: {}", self),
195        }
196      }
197      #[cfg(feature = "complex")]
198      ValueKind::C64 => FeatureKind::C64,
199      #[cfg(feature = "rational")]
200      ValueKind::R64 => FeatureKind::R64,
201      ValueKind::Atom(_) => FeatureKind::Atom,
202      ValueKind::Index => FeatureKind::Index,
203      _ => panic!("Unsupported feature kind for value kind: {}", self),
204    }
205  }
206
207  pub fn collection_kind(&self) -> Option<ValueKind> {
208    match self {
209      ValueKind::Matrix(x,_) => Some(*x.clone()),
210      ValueKind::Set(x,_) => Some(*x.clone()),
211      _ => None,
212    }
213  }
214
215  pub fn deref_kind(&self) -> ValueKind {
216    match self {
217      ValueKind::Reference(x) => *x.clone(),
218      _ => self.clone(),
219    }
220  }
221
222  pub fn is_convertible_to(&self, other: &ValueKind) -> bool {
223    use ValueKind::*;
224    match (self, other) {
225      // Unsigned widening
226      (U8, U16) | (U8, U32) | (U8, U64) | (U8, U128) |
227      (U16, U32) | (U16, U64) | (U16, U128) |
228      (U32, U64) | (U32, U128) |
229      (U64, U128) => true,
230
231      // Signed widening
232      (I8, I16) | (I8, I32) | (I8, I64) | (I8, I128) |
233      (I16, I32) | (I16, I64) | (I16, I128) |
234      (I32, I64) | (I32, I128) |
235      (I64, I128) => true,
236
237      // Unsigned -> signed widening
238      (U8, I16) | (U8, I32) | (U8, I64) | (U8, I128) |
239      (U16, I32) | (U16, I64) | (U16, I128) |
240      (U32, I64) | (U32, I128) |
241      (U64, I128) => true,
242
243      // Signed -> unsigned widening (runtime safety not enforced here)
244      (I8, U16) | (I8, U32) | (I8, U64) | (I8, U128) |
245      (I16, U32) | (I16, U64) | (I16, U128) |
246      (I32, U64) | (I32, U128) |
247      (I64, U128) => true,
248
249      // Integer -> float
250      (U8, F32) | (U8, F64) |
251      (U16, F32) | (U16, F64) |
252      (U32, F32) | (U32, F64) |
253      (U64, F32) | (U64, F64) |
254      (U128, F32) | (U128, F64) |
255      (I8, F32) | (I8, F64) |
256      (I16, F32) | (I16, F64) |
257      (I32, F32) | (I32, F64) |
258      (I64, F32) | (I64, F64) |
259      (I128, F32) | (I128, F64) => true,
260
261      // Float widening + narrowing
262      (F32, F64) | (F64, F32) => true,
263
264      // Float -> integer (allowed, but lossy)
265      (F32, I8) | (F32, I16) | (F32, I32) | (F32, I64) | (F32, I128) |
266      (F32, U8) | (F32, U16) | (F32, U32) | (F32, U64) | (F32, U128) |
267      (F64, I8) | (F64, I16) | (F64, I32) | (F64, I64) | (F64, I128) |
268      (F64, U8) | (F64, U16) | (F64, U32) | (F64, U64) | (F64, U128) => true,
269
270      // Index conversions (both ways)
271      (Index, U8) | (Index, U16) | (Index, U32) | (Index, U64) | (Index, U128) |
272      (Index, I8) | (Index, I16) | (Index, I32) | (Index, I64) | (Index, I128) |
273      (Index, F32) | (Index, F64) |
274      (U8, Index) | (U16, Index) | (U32, Index) | (U64, Index) | (U128, Index) |
275      (I8, Index) | (I16, Index) | (I32, Index) | (I64, Index) | (I128, Index) => true,
276
277      // Matrix: element type convertible and shape matches
278      (Matrix(box a, ashape), Matrix(box b, bshape)) if ashape.into_iter().product::<usize>() == bshape.into_iter().product::<usize>() && a.is_convertible_to(b) => true,
279
280      // Option conversions
281      (Option(box a), Option(box b)) if a.is_convertible_to(b) => true,
282
283      // Reference conversions
284      (Reference(box a), Reference(box b)) if a.is_convertible_to(b) => true,
285
286      // Tuple conversions (element-wise)
287      (Tuple(a), Tuple(b)) if a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| x.is_convertible_to(y)) => true,
288
289      // Set conversions
290      (Set(box a, _), Set(box b, _)) if a.is_convertible_to(b) => true,
291
292      // Map conversions
293      (Map(box ak, box av), Map(box bk, box bv)) if ak.is_convertible_to(bk) && av.is_convertible_to(bv) => true,
294
295      // Table conversions: allow source to have extra columns
296      (Table(acols, _), Table(bcols, _)) if bcols.iter().all(|(bk, bv)| 
297        acols.iter().any(|(ak, av)| ak == bk && av.is_convertible_to(bv))
298      ) => true,
299
300      // Record conversions: allow source to have extra fields
301      (Record(afields), Record(bfields)) if bfields.iter().all(|(bk, bv)| 
302        afields.iter().any(|(ak, av)| ak == bk && av.is_convertible_to(bv))
303      ) => true,
304
305      // Direct match
306      _ => self == other,
307    }
308  }
309
310  pub fn is_compatible(k1: ValueKind, k2: ValueKind) -> bool {
311    match k1 {
312      ValueKind::Reference(x) => {
313        ValueKind::is_compatible(*x,k2)
314      }
315      ValueKind::Matrix(x,_) => {
316        *x == k2
317      }
318      x => x == k2,
319    }
320  }
321
322  pub fn align(&self) -> usize {
323    // pointer alignment (platform word size) for pointer-like kinds
324    let ptr_align = mem::align_of::<usize>();
325
326    match self {
327      // unsigned integers
328      ValueKind::U8   => 1,
329      ValueKind::U16  => 2,
330      ValueKind::U32  => 4,
331      ValueKind::U64  => 8,
332      ValueKind::U128 => 16,
333
334      // signed integers
335      ValueKind::I8   => 1,
336      ValueKind::I16  => 2,
337      ValueKind::I32  => 4,
338      ValueKind::I64  => 8,
339      ValueKind::I128 => 16,
340
341      // floats
342      ValueKind::F32  => 4,
343      ValueKind::F64  => 8,
344
345      // complex / rational (assume composed of f64 parts)
346      ValueKind::C64 => 8,
347      ValueKind::R64 => 8,
348
349      // small simple payloads
350      ValueKind::Bool => 1,
351      ValueKind::String => 1, // strings are length+bytes; bytes are packed
352      ValueKind::Id | ValueKind::Index => 8, // id/index -> likely machine word (u64)
353      ValueKind::Empty => 1,
354      ValueKind::Any => ptr_align,
355
356      // compound types
357      ValueKind::Matrix(elem_ty, _dims) => {
358        // matrix alignment = alignment of element type
359        elem_ty.align()
360      }
361
362      ValueKind::Enum(_space) => 8, // enum tag stored in u64
363      ValueKind::Atom(_id) => 8,
364
365      ValueKind::Record(fields) => {
366        // record alignment = max alignment of fields (or 1 if empty)
367        fields.iter()
368            .map(|(_, ty)| ty.align())
369            .max()
370            .unwrap_or(1)
371      }
372
373      ValueKind::Map(_, _) => ptr_align,   // typically pointer-based representation
374      ValueKind::Table(cols, _pk) => {
375        // table: use max column alignment or pointer-align if empty
376        cols.iter()
377            .map(|(_, ty)| ty.align())
378            .max()
379            .unwrap_or(ptr_align)
380      }
381
382      ValueKind::Tuple(elems) => {
383        elems.iter().map(|ty| ty.align()).max().unwrap_or(1)
384      }
385
386      ValueKind::Reference(inner) => ptr_align, // references are pointers at runtime
387
388      ValueKind::Set(elem, _) => {
389        // set alignment equals element alignment (or ptr_align fallback)
390        match elem.as_ref() {
391          v => v.align()
392        }
393      }
394      ValueKind::Option(inner) => inner.align(),
395    }
396  }
397}
398
399pub trait AsNaKind {
400  fn as_na_kind() -> String;
401}
402
403macro_rules! impl_as_na_kind {
404  ($type:ty, $kind:expr) => {
405    impl<T> AsNaKind for $type {
406      fn as_na_kind() -> String { $kind.to_string() }
407    }
408  };
409}
410
411#[cfg(feature = "row_vector2")]
412impl_as_na_kind!(RowVector2<T>, "RowVector2");
413#[cfg(feature = "row_vector3")]
414impl_as_na_kind!(RowVector3<T>, "RowVector3");
415#[cfg(feature = "row_vector4")]
416impl_as_na_kind!(RowVector4<T>, "RowVector4");
417#[cfg(feature = "row_vectord")]
418impl_as_na_kind!(RowDVector<T>, "RowDVector");
419#[cfg(feature = "vector2")]
420impl_as_na_kind!(Vector2<T>, "Vector2");
421#[cfg(feature = "vector3")]
422impl_as_na_kind!(Vector3<T>, "Vector3");
423#[cfg(feature = "vector4")]
424impl_as_na_kind!(Vector4<T>, "Vector4");
425#[cfg(feature = "vectord")]
426impl_as_na_kind!(DVector<T>, "DVector");
427#[cfg(feature = "matrix1")]
428impl_as_na_kind!(Matrix1<T>, "Matrix1");
429#[cfg(feature = "matrix2")]
430impl_as_na_kind!(Matrix2<T>, "Matrix2");
431#[cfg(feature = "matrix3")]
432impl_as_na_kind!(Matrix3<T>, "Matrix3");
433#[cfg(feature = "matrix4")]
434impl_as_na_kind!(Matrix4<T>, "Matrix4");
435#[cfg(feature = "matrix2x3")]
436impl_as_na_kind!(Matrix2x3<T>, "Matrix2x3");
437#[cfg(feature = "matrix3x2")]
438impl_as_na_kind!(Matrix3x2<T>, "Matrix3x2");
439#[cfg(feature = "matrixd")]
440impl_as_na_kind!(DMatrix<T>, "DMatrix");
441
442pub trait AsValueKind {
443  fn as_value_kind() -> ValueKind;
444}
445
446macro_rules! impl_as_value_kind {
447  ($type:ty, $value_kind:expr) => {
448    impl AsValueKind for $type {
449      fn as_value_kind() -> ValueKind { $value_kind }
450    }
451  };
452}
453
454impl_as_value_kind!(usize, ValueKind::Index);
455
456#[cfg(feature = "i8")]
457impl_as_value_kind!(i8, ValueKind::I8);
458#[cfg(feature = "i16")]
459impl_as_value_kind!(i16, ValueKind::I16);
460#[cfg(feature = "i32")]
461impl_as_value_kind!(i32, ValueKind::I32);
462#[cfg(feature = "i64")]
463impl_as_value_kind!(i64, ValueKind::I64);
464#[cfg(feature = "i128")]
465impl_as_value_kind!(i128, ValueKind::I128);
466#[cfg(feature = "u8")]
467impl_as_value_kind!(u8, ValueKind::U8);
468#[cfg(feature = "u16")]
469impl_as_value_kind!(u16, ValueKind::U16);
470#[cfg(feature = "u32")]
471impl_as_value_kind!(u32, ValueKind::U32);
472#[cfg(feature = "u64")]
473impl_as_value_kind!(u64, ValueKind::U64);
474#[cfg(feature = "u128")]
475impl_as_value_kind!(u128, ValueKind::U128);
476#[cfg(feature = "f32")]
477impl_as_value_kind!(F32, ValueKind::F32);
478#[cfg(feature = "f64")]
479impl_as_value_kind!(F64, ValueKind::F64);
480#[cfg(any(feature = "bool", feature = "variable_define"))]
481impl_as_value_kind!(bool, ValueKind::Bool);
482#[cfg(any(feature = "string", feature = "variable_define"))]
483impl_as_value_kind!(String, ValueKind::String);
484#[cfg(feature = "rational")]
485impl_as_value_kind!(R64, ValueKind::R64);
486#[cfg(feature = "complex")]
487impl_as_value_kind!(C64, ValueKind::C64);
488
489
490macro_rules! impl_as_value_kind_for_matrix {
491  ($type:ty, $dims:expr) => {
492    impl<T: AsValueKind> AsValueKind for $type {
493      fn as_value_kind() -> ValueKind {
494        ValueKind::Matrix(Box::new(T::as_value_kind()), $dims)
495      }
496    }
497  };
498}
499
500#[cfg(feature = "row_vectord")]
501impl_as_value_kind_for_matrix!(RowDVector<T>, vec![1, 0]);
502#[cfg(feature = "row_vector2")]
503impl_as_value_kind_for_matrix!(RowVector2<T>, vec![1, 2]);
504#[cfg(feature = "row_vector3")]
505impl_as_value_kind_for_matrix!(RowVector3<T>, vec![1, 3]);
506#[cfg(feature = "row_vector4")]
507impl_as_value_kind_for_matrix!(RowVector4<T>, vec![1, 4]);
508#[cfg(feature = "vectord")]
509impl_as_value_kind_for_matrix!(DVector<T>, vec![0, 1]);
510#[cfg(feature = "vector2")]
511impl_as_value_kind_for_matrix!(Vector2<T>, vec![2, 1]);
512#[cfg(feature = "vector3")]
513impl_as_value_kind_for_matrix!(Vector3<T>, vec![3, 1]);
514#[cfg(feature = "vector4")]
515impl_as_value_kind_for_matrix!(Vector4<T>, vec![4, 1]);
516#[cfg(feature = "matrix1")]
517impl_as_value_kind_for_matrix!(Matrix1<T>, vec![1, 1]);
518#[cfg(feature = "matrix2")]
519impl_as_value_kind_for_matrix!(Matrix2<T>, vec![2, 2]);
520#[cfg(feature = "matrix3")]
521impl_as_value_kind_for_matrix!(Matrix3<T>, vec![3, 3]);
522#[cfg(feature = "matrix4")]
523impl_as_value_kind_for_matrix!(Matrix4<T>, vec![4, 4]);
524#[cfg(feature = "matrix2x3")]
525impl_as_value_kind_for_matrix!(Matrix2x3<T>, vec![2, 3]);
526#[cfg(feature = "matrix3x2")]
527impl_as_value_kind_for_matrix!(Matrix3x2<T>, vec![3, 2]);
528#[cfg(feature = "matrixd")]
529impl_as_value_kind_for_matrix!(DMatrix<T>, vec![0, 0]);
530
531impl AsValueKind for Value {
532  fn as_value_kind() -> ValueKind {
533    ValueKind::Any
534  }
535}
536
537
538// Value
539// ----------------------------------------------------------------------------
540
541#[derive(Clone, Debug, PartialEq, Eq)]
542pub enum Value {
543  #[cfg(feature = "u8")]
544  U8(Ref<u8>),
545  #[cfg(feature = "u16")]
546  U16(Ref<u16>),
547  #[cfg(feature = "u32")]
548  U32(Ref<u32>),
549  #[cfg(feature = "u64")]
550  U64(Ref<u64>),
551  #[cfg(feature = "u128")]
552  U128(Ref<u128>),
553  #[cfg(feature = "i8")]
554  I8(Ref<i8>),
555  #[cfg(feature = "i16")]
556  I16(Ref<i16>),
557  #[cfg(feature = "i32")]
558  I32(Ref<i32>),
559  #[cfg(feature = "i64")]
560  I64(Ref<i64>),
561  #[cfg(feature = "i128")]
562  I128(Ref<i128>),
563  #[cfg(feature = "f32")]
564  F32(Ref<F32>),
565  #[cfg(feature = "f64")]
566  F64(Ref<F64>),
567  #[cfg(any(feature = "string", feature = "variable_define"))]
568  String(Ref<String>),
569  #[cfg(any(feature = "bool", feature = "variable_define"))]
570  Bool(Ref<bool>),
571  #[cfg(feature = "atom")]
572  Atom(Ref<MechAtom>),
573  #[cfg(feature = "matrix")]
574  MatrixIndex(Matrix<usize>),
575  #[cfg(all(feature = "matrix", feature = "bool"))]
576  MatrixBool(Matrix<bool>),
577  #[cfg(all(feature = "matrix", feature = "u8"))]
578  MatrixU8(Matrix<u8>),
579  #[cfg(all(feature = "matrix", feature = "u16"))]
580  MatrixU16(Matrix<u16>),
581  #[cfg(all(feature = "matrix", feature = "u32"))]
582  MatrixU32(Matrix<u32>),
583  #[cfg(all(feature = "matrix", feature = "u64"))]
584  MatrixU64(Matrix<u64>),
585  #[cfg(all(feature = "matrix", feature = "u128"))]
586  MatrixU128(Matrix<u128>),
587  #[cfg(all(feature = "matrix", feature = "i8"))]
588  MatrixI8(Matrix<i8>),
589  #[cfg(all(feature = "matrix", feature = "i16"))]
590  MatrixI16(Matrix<i16>),
591  #[cfg(all(feature = "matrix", feature = "i32"))]
592  MatrixI32(Matrix<i32>),
593  #[cfg(all(feature = "matrix", feature = "i64"))]
594  MatrixI64(Matrix<i64>),
595  #[cfg(all(feature = "matrix", feature = "i128"))]
596  MatrixI128(Matrix<i128>),
597  #[cfg(all(feature = "matrix", feature = "f32"))]
598  MatrixF32(Matrix<F32>),
599  #[cfg(all(feature = "matrix", feature = "f64"))]
600  MatrixF64(Matrix<F64>),
601  #[cfg(all(feature = "matrix", feature = "string"))]
602  MatrixString(Matrix<String>),
603  #[cfg(all(feature = "matrix", feature = "rational"))]
604  MatrixR64(Matrix<R64>),
605  #[cfg(all(feature = "matrix", feature = "complex"))]
606  MatrixC64(Matrix<C64>),
607  #[cfg(feature = "matrix")]
608  MatrixValue(Matrix<Value>),
609  #[cfg(feature = "complex")]
610  C64(Ref<C64>),
611  #[cfg(feature = "rational")]
612  R64(Ref<R64>),
613  #[cfg(feature = "set")]
614  Set(Ref<MechSet>),
615  #[cfg(feature = "map")]
616  Map(Ref<MechMap>),
617  #[cfg(feature = "record")]
618  Record(Ref<MechRecord>),
619  #[cfg(feature = "table")]
620  Table(Ref<MechTable>),
621  #[cfg(feature = "tuple")]
622  Tuple(Ref<MechTuple>),
623  #[cfg(feature = "enum")]
624  Enum(Ref<MechEnum>),
625  Id(u64),
626  Index(Ref<usize>),
627  MutableReference(MutableReference),
628  Kind(ValueKind),
629  IndexAll,
630  Empty
631}
632
633impl fmt::Display for Value {
634  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
635    if cfg!(feature = "pretty_print") {
636      #[cfg(feature = "pretty_print")]
637      return fmt::Display::fmt(&self.pretty_print(), f);
638      fmt::Display::fmt(&"".to_string(), f) // kind of a hack to assuage the compiler
639    } else {
640      write!(f, "{:?}", self)
641    }
642  }
643}
644
645impl Hash for Value {
646  fn hash<H: Hasher>(&self, state: &mut H) {
647    match self {
648      #[cfg(feature = "rational")]
649      Value::R64(x) => x.borrow().hash(state),
650      #[cfg(feature = "u8")]
651      Value::U8(x)   => x.borrow().hash(state),
652      #[cfg(feature = "u16")]
653      Value::U16(x)  => x.borrow().hash(state),
654      #[cfg(feature = "u32")]
655      Value::U32(x)  => x.borrow().hash(state),
656      #[cfg(feature = "u64")]
657      Value::U64(x)  => x.borrow().hash(state),
658      #[cfg(feature = "u128")]
659      Value::U128(x) => x.borrow().hash(state),
660      #[cfg(feature = "i8")]
661      Value::I8(x)   => x.borrow().hash(state),
662      #[cfg(feature = "i16")]
663      Value::I16(x)  => x.borrow().hash(state),
664      #[cfg(feature = "i32")]
665      Value::I32(x)  => x.borrow().hash(state),
666      #[cfg(feature = "i64")]
667      Value::I64(x)  => x.borrow().hash(state),
668      #[cfg(feature = "i128")]
669      Value::I128(x) => x.borrow().hash(state),
670      #[cfg(feature = "f32")]
671      Value::F32(x)  => x.borrow().hash(state),
672      #[cfg(feature = "f64")]
673      Value::F64(x)  => x.borrow().hash(state),
674      #[cfg(feature = "complex")]
675      Value::C64(x) => x.borrow().hash(state),
676      #[cfg(any(feature = "bool", feature = "variable_define"))]
677      Value::Bool(x) => x.borrow().hash(state),
678      #[cfg(feature = "atom")]
679      Value::Atom(x) => x.borrow().hash(state),
680      #[cfg(feature = "set")]
681      Value::Set(x)  => x.borrow().hash(state),
682      #[cfg(feature = "map")]
683      Value::Map(x)  => x.borrow().hash(state),
684      #[cfg(feature = "table")]
685      Value::Table(x) => x.borrow().hash(state),
686      #[cfg(feature = "tuple")]
687      Value::Tuple(x) => x.borrow().hash(state),
688      #[cfg(feature = "record")]
689      Value::Record(x) => x.borrow().hash(state),
690      #[cfg(feature = "enum")]
691      Value::Enum(x) => x.borrow().hash(state),
692      #[cfg(any(feature = "string", feature = "variable_define"))]
693      Value::String(x) => x.borrow().hash(state),
694      #[cfg(all(feature = "matrix", feature = "bool"))]
695      Value::MatrixBool(x) => x.hash(state),
696      #[cfg(feature = "matrix")]
697      Value::MatrixIndex(x) => x.hash(state),
698      #[cfg(all(feature = "matrix", feature = "u8"))]
699      Value::MatrixU8(x)   => x.hash(state),
700      #[cfg(all(feature = "matrix", feature = "u16"))]
701      Value::MatrixU16(x)  => x.hash(state),
702      #[cfg(all(feature = "matrix", feature = "u32"))]
703      Value::MatrixU32(x)  => x.hash(state),
704      #[cfg(all(feature = "matrix", feature = "u64"))]
705      Value::MatrixU64(x)  => x.hash(state),
706      #[cfg(all(feature = "matrix", feature = "u128"))]
707      Value::MatrixU128(x) => x.hash(state),
708      #[cfg(all(feature = "matrix", feature = "i8"))]
709      Value::MatrixI8(x)   => x.hash(state),
710      #[cfg(all(feature = "matrix", feature = "i16"))]
711      Value::MatrixI16(x)  => x.hash(state),
712      #[cfg(all(feature = "matrix", feature = "i32"))]
713      Value::MatrixI32(x)  => x.hash(state),
714      #[cfg(all(feature = "matrix", feature = "i64"))]
715      Value::MatrixI64(x)  => x.hash(state),
716      #[cfg(all(feature = "matrix", feature = "i128"))]
717      Value::MatrixI128(x) => x.hash(state),
718      #[cfg(all(feature = "matrix", feature = "f32"))]
719      Value::MatrixF32(x)  => x.hash(state),
720      #[cfg(all(feature = "matrix", feature = "f64"))]
721      Value::MatrixF64(x)  => x.hash(state),
722      #[cfg(all(feature = "matrix", feature = "string"))]
723      Value::MatrixString(x) => x.hash(state),
724      #[cfg(feature = "matrix")]
725      Value::MatrixValue(x)  => x.hash(state),
726      #[cfg(all(feature = "matrix", feature = "rational"))]
727      Value::MatrixR64(x) => x.hash(state),
728      #[cfg(all(feature = "matrix", feature = "complex"))]
729      Value::MatrixC64(x) => x.hash(state),
730      Value::Id(x)   => x.hash(state),
731      Value::Kind(x) => x.hash(state),
732      Value::Index(x)=> x.borrow().hash(state),
733      Value::MutableReference(x) => x.borrow().hash(state),
734      Value::Empty => Value::Empty.hash(state),
735      Value::IndexAll => Value::IndexAll.hash(state),
736    }
737  }
738}
739impl Value {
740
741  #[cfg(feature = "matrix")]
742  pub unsafe fn get_copyable_matrix_unchecked<T>(&self) -> Box<dyn CopyMat<T>> 
743  where T: AsValueKind + 'static
744  {
745    match (T::as_value_kind(), self) {
746      #[cfg(all(feature = "matrix", feature = "bool"))]
747      (ValueKind::Bool, Value::MatrixBool(m)) => {
748        let b: Box<dyn CopyMat<bool>> = m.get_copyable_matrix();
749        std::mem::transmute::<Box<dyn CopyMat<bool>>, Box<dyn CopyMat<T>>>(b)
750      }
751      #[cfg(all(feature = "matrix", feature = "u8"))]
752      (ValueKind::U8, Value::MatrixU8(m)) => {
753        let b: Box<dyn CopyMat<u8>> = m.get_copyable_matrix();
754        std::mem::transmute::<Box<dyn CopyMat<u8>>, Box<dyn CopyMat<T>>>(b)
755      }
756      #[cfg(all(feature = "matrix", feature = "u16"))]
757      (ValueKind::U16, Value::MatrixU16(m)) => {
758        let b: Box<dyn CopyMat<u16>> = m.get_copyable_matrix();
759        std::mem::transmute::<Box<dyn CopyMat<u16>>, Box<dyn CopyMat<T>>>(b)
760      }
761      #[cfg(all(feature = "matrix", feature = "u32"))]
762      (ValueKind::U32, Value::MatrixU32(m)) => {
763        let b: Box<dyn CopyMat<u32>> = m.get_copyable_matrix();
764        std::mem::transmute::<Box<dyn CopyMat<u32>>, Box<dyn CopyMat<T>>>(b)
765      }
766      #[cfg(all(feature = "matrix", feature = "u64"))]
767      (ValueKind::U64, Value::MatrixU64(m)) => {
768        let b: Box<dyn CopyMat<u64>> = m.get_copyable_matrix();
769        std::mem::transmute::<Box<dyn CopyMat<u64>>, Box<dyn CopyMat<T>>>(b)
770      }
771      #[cfg(all(feature = "matrix", feature = "u128"))]
772      (ValueKind::U128, Value::MatrixU128(m)) => {
773        let b: Box<dyn CopyMat<u128>> = m.get_copyable_matrix();
774        std::mem::transmute::<Box<dyn CopyMat<u128>>, Box<dyn CopyMat<T>>>(b)
775      }
776      #[cfg(all(feature = "matrix", feature = "i8"))]
777      (ValueKind::I8, Value::MatrixI8(m)) => {
778        let b: Box<dyn CopyMat<i8>> = m.get_copyable_matrix();
779        std::mem::transmute::<Box<dyn CopyMat<i8>>, Box<dyn CopyMat<T>>>(b)
780      }
781      #[cfg(all(feature = "matrix", feature = "i16"))]
782      (ValueKind::I16, Value::MatrixI16(m)) => {
783        let b: Box<dyn CopyMat<i16>> = m.get_copyable_matrix();
784        std::mem::transmute::<Box<dyn CopyMat<i16>>, Box<dyn CopyMat<T>>>(b)
785      }
786      #[cfg(all(feature = "matrix", feature = "i32"))]
787      (ValueKind::I32, Value::MatrixI32(m)) => {
788        let b: Box<dyn CopyMat<i32>> = m.get_copyable_matrix();
789        std::mem::transmute::<Box<dyn CopyMat<i32>>, Box<dyn CopyMat<T>>>(b)
790      }
791      #[cfg(all(feature = "matrix", feature = "i64"))]
792      (ValueKind::I64, Value::MatrixI64(m)) => {
793        let b: Box<dyn CopyMat<i64>> = m.get_copyable_matrix();
794        std::mem::transmute::<Box<dyn CopyMat<i64>>, Box<dyn CopyMat<T>>>(b)
795      }
796      #[cfg(all(feature = "matrix", feature = "i128"))]
797      (ValueKind::I128, Value::MatrixI128(m)) => {
798        let b: Box<dyn CopyMat<i128>> = m.get_copyable_matrix();
799        std::mem::transmute::<Box<dyn CopyMat<i128>>, Box<dyn CopyMat<T>>>(b)
800      }
801      #[cfg(all(feature = "matrix", feature = "f32"))]
802      (ValueKind::F32, Value::MatrixF32(m)) => {
803        let b: Box<dyn CopyMat<F32>> = m.get_copyable_matrix();
804        std::mem::transmute::<Box<dyn CopyMat<F32>>, Box<dyn CopyMat<T>>>(b)
805      }
806      #[cfg(all(feature = "matrix", feature = "f64"))]
807      (ValueKind::F64, Value::MatrixF64(m)) => {
808        let b: Box<dyn CopyMat<F64>> = m.get_copyable_matrix();
809        std::mem::transmute::<Box<dyn CopyMat<F64>>, Box<dyn CopyMat<T>>>(b)
810      }
811      #[cfg(all(feature = "matrix", feature = "string"))]
812      (ValueKind::String, Value::MatrixString(m)) => {
813        let b: Box<dyn CopyMat<String>> = m.get_copyable_matrix();
814        std::mem::transmute::<Box<dyn CopyMat<String>>, Box<dyn CopyMat<T>>>(b)
815      }
816      _ => panic!("Unsupported type for get_copyable_matrix_unchecked"),
817    }
818  }
819
820  pub unsafe fn as_unchecked<T>(&self) -> &Ref<T> {
821    match self {
822      #[cfg(feature = "u8")]
823      Value::U8(r) => &*(r as *const Ref<u8> as *const Ref<T>),
824      #[cfg(feature = "u16")]
825      Value::U16(r) => &*(r as *const Ref<u16> as *const Ref<T>),
826      #[cfg(feature = "u32")]
827      Value::U32(r) => &*(r as *const Ref<u32> as *const Ref<T>),
828      #[cfg(feature = "u64")]
829      Value::U64(r) => &*(r as *const Ref<u64> as *const Ref<T>),
830      #[cfg(feature = "u128")]
831      Value::U128(r) => &*(r as *const Ref<u128> as *const Ref<T>),
832      #[cfg(feature = "i8")]
833      Value::I8(r) => &*(r as *const Ref<i8> as *const Ref<T>),
834      #[cfg(feature = "i16")]
835      Value::I16(r) => &*(r as *const Ref<i16> as *const Ref<T>),
836      #[cfg(feature = "i32")]
837      Value::I32(r) => &*(r as *const Ref<i32> as *const Ref<T>),
838      #[cfg(feature = "i64")]
839      Value::I64(r) => &*(r as *const Ref<i64> as *const Ref<T>),
840      #[cfg(feature = "i128")]
841      Value::I128(r) => &*(r as *const Ref<i128> as *const Ref<T>),
842      #[cfg(feature = "f32")]
843      Value::F32(r) => &*(r as *const Ref<F32> as *const Ref<T>),
844      #[cfg(feature = "f64")]
845      Value::F64(r) => &*(r as *const Ref<F64> as *const Ref<T>),
846      #[cfg(any(feature = "string", feature = "variable_define"))]
847      Value::String(r) => &*(r as *const Ref<String> as *const Ref<T>),
848      #[cfg(any(feature = "bool", feature = "variable_define"))]
849      Value::Bool(r) => &*(r as *const Ref<bool> as *const Ref<T>),
850      #[cfg(feature = "rational")]
851      Value::R64(r) => &*(r as *const Ref<R64> as *const Ref<T>),
852      #[cfg(feature = "complex")]
853      Value::C64(r) => &*(r as *const Ref<C64> as *const Ref<T>),
854      #[cfg(all(feature = "f64", feature = "matrix"))]
855      Value::MatrixF64(r) => r.as_unchecked(),
856      #[cfg(all(feature = "f32", feature = "matrix"))]
857      Value::MatrixF32(r) => r.as_unchecked(),
858      #[cfg(all(feature = "i8", feature = "matrix"))]
859      Value::MatrixI8(r) => r.as_unchecked(),
860      #[cfg(all(feature = "i16", feature = "matrix"))]
861      Value::MatrixI16(r) => r.as_unchecked(),
862      #[cfg(all(feature = "i32", feature = "matrix"))]
863      Value::MatrixI32(r) => r.as_unchecked(),
864      #[cfg(all(feature = "i64", feature = "matrix"))]
865      Value::MatrixI64(r) => r.as_unchecked(),
866      #[cfg(all(feature = "i128", feature = "matrix"))]
867      Value::MatrixI128(r) => r.as_unchecked(),
868      #[cfg(all(feature = "u8", feature = "matrix"))]
869      Value::MatrixU8(r) => r.as_unchecked(),
870      #[cfg(all(feature = "u16", feature = "matrix"))]
871      Value::MatrixU16(r) => r.as_unchecked(),
872      #[cfg(all(feature = "u32", feature = "matrix"))]
873      Value::MatrixU32(r) => r.as_unchecked(),
874      #[cfg(all(feature = "u64", feature = "matrix"))]
875      Value::MatrixU64(r) => r.as_unchecked(),
876      #[cfg(all(feature = "u128", feature = "matrix"))]
877      Value::MatrixU128(r) => r.as_unchecked(),
878      #[cfg(all(feature = "bool", feature = "matrix"))]
879      Value::MatrixBool(r) => r.as_unchecked(),
880      #[cfg(all(feature = "string", feature = "matrix"))]
881      Value::MatrixString(r) => r.as_unchecked(),
882      #[cfg(all(feature = "rational", feature = "matrix"))]
883      Value::MatrixR64(r) => r.as_unchecked(),
884      #[cfg(all(feature = "complex", feature = "matrix"))]
885      Value::MatrixC64(r) => r.as_unchecked(),
886      #[cfg(feature = "matrix")]
887      Value::MatrixIndex(r) => r.as_unchecked(),
888      Value::Index(r) => &*(r as *const Ref<usize> as *const Ref<T>),
889      #[cfg(feature = "enum")]
890      Value::Enum(r) => &*(r as *const Ref<MechEnum> as *const Ref<T>),
891      #[cfg(feature = "set")]
892      Value::Set(r) => &*(r as *const Ref<MechSet> as *const Ref<T>),
893      #[cfg(feature = "table")]
894      Value::Table(r) => &*(r as *const Ref<MechTable> as *const Ref<T>),
895      x => panic!("Unsupported type for as_unchecked: {:?}.", x),
896    }
897  }
898
899  pub fn addr(&self) -> usize {
900    match self {
901      #[cfg(feature = "u8")]
902      Value::U8(v) => v.addr(),
903      #[cfg(feature = "u16")]
904      Value::U16(v) => v.addr(),
905      #[cfg(feature = "u32")]
906      Value::U32(v) => v.addr(),
907      #[cfg(feature = "u64")]
908      Value::U64(v) => v.addr(),
909      #[cfg(feature = "u128")]
910      Value::U128(v) => v.addr(),
911      #[cfg(feature = "i8")]
912      Value::I8(v) => v.addr(),
913      #[cfg(feature = "i16")]
914      Value::I16(v) => v.addr(),
915      #[cfg(feature = "i32")]
916      Value::I32(v) => v.addr(),
917      #[cfg(feature = "i64")]
918      Value::I64(v) => v.addr(),
919      #[cfg(feature = "i128")]
920      Value::I128(v) => v.addr(),
921      #[cfg(feature = "f32")]
922      Value::F32(v) => v.addr(),
923      #[cfg(feature = "f64")]
924      Value::F64(v) => v.addr(),
925      #[cfg(any(feature = "string", feature = "variable_define"))]
926      Value::String(v) => v.addr(),
927      #[cfg(any(feature = "bool", feature = "variable_define"))]
928      Value::Bool(v) => v.addr(),
929      #[cfg(feature = "complex")]
930      Value::C64(v) => v.addr(),
931      #[cfg(feature = "rational")]
932      Value::R64(v) => v.addr(),
933      #[cfg(feature = "record")]
934      Value::Record(v) => v.addr(),
935      #[cfg(feature = "table")]
936      Value::Table(v) => v.addr(),
937      #[cfg(feature = "map")]
938      Value::Map(v) => v.addr(),
939      #[cfg(feature = "tuple")]
940      Value::Tuple(v) => v.addr(),
941      #[cfg(feature = "set")]
942      Value::Set(v) => v.addr(),
943      #[cfg(feature = "enum")]
944      Value::Enum(v) => v.addr(),
945      #[cfg(feature = "atom")]
946      Value::Atom(v) => v.addr(),
947      #[cfg(feature = "matrix")]
948      Value::MatrixIndex(v) => v.addr(),
949      Value::Index(v) => v.addr(),
950      Value::MutableReference(v) => v.addr(),
951      _ => todo!(),
952    }
953  }
954
955  pub fn convert_to(&self, other: &ValueKind) -> Option<Value> {
956
957    if self.kind() == *other {
958        return Some(self.clone());
959    }
960
961    if !self.kind().is_convertible_to(other) {
962        return None;
963    }
964
965    match (self, other) {
966    // ==== Unsigned widening and narrowing ====
967    #[cfg(all(feature = "u8", feature = "u16"))]
968    (Value::U8(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
969    #[cfg(all(feature = "u8", feature = "u32"))]
970    (Value::U8(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
971    #[cfg(all(feature = "u8", feature = "u64"))]
972    (Value::U8(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
973    #[cfg(all(feature = "u8", feature = "u128"))]
974    (Value::U8(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
975    #[cfg(all(feature = "u8", feature = "i16"))]
976    (Value::U8(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
977    #[cfg(all(feature = "u8", feature = "i32"))]
978    (Value::U8(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
979    #[cfg(all(feature = "u8", feature = "i64"))]
980    (Value::U8(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
981    #[cfg(all(feature = "u8", feature = "i128"))]
982    (Value::U8(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
983    #[cfg(all(feature = "u8", feature = "f32"))]
984    (Value::U8(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
985    #[cfg(all(feature = "u8", feature = "f64"))]
986    (Value::U8(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
987
988    #[cfg(all(feature = "u16", feature = "u8"))]
989    (Value::U16(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
990    #[cfg(all(feature = "u16", feature = "u32"))]
991    (Value::U16(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
992    #[cfg(all(feature = "u16", feature = "u64"))]
993    (Value::U16(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
994    #[cfg(all(feature = "u16", feature = "u128"))]
995    (Value::U16(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
996    #[cfg(all(feature = "u16", feature = "i8"))]
997    (Value::U16(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
998    #[cfg(all(feature = "u16", feature = "i32"))]
999    (Value::U16(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1000    #[cfg(all(feature = "u16", feature = "i64"))]
1001    (Value::U16(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1002    #[cfg(all(feature = "u16", feature = "i128"))]
1003    (Value::U16(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1004    #[cfg(all(feature = "u16", feature = "f32"))]
1005    (Value::U16(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1006    #[cfg(all(feature = "u16", feature = "f64"))]
1007    (Value::U16(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1008
1009    #[cfg(all(feature = "u32", feature = "u8"))]
1010    (Value::U32(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1011    #[cfg(all(feature = "u32", feature = "u16"))]
1012    (Value::U32(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1013    #[cfg(all(feature = "u32", feature = "u64"))]
1014    (Value::U32(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1015    #[cfg(all(feature = "u32", feature = "u128"))]
1016    (Value::U32(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1017    #[cfg(all(feature = "u32", feature = "i8"))]
1018    (Value::U32(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1019    #[cfg(all(feature = "u32", feature = "i16"))]
1020    (Value::U32(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1021    #[cfg(all(feature = "u32", feature = "i64"))]
1022    (Value::U32(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1023    #[cfg(all(feature = "u32", feature = "i128"))]
1024    (Value::U32(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1025    #[cfg(all(feature = "u32", feature = "f32"))]
1026    (Value::U32(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1027    #[cfg(all(feature = "u32", feature = "f64"))]
1028    (Value::U32(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1029
1030    #[cfg(all(feature = "u64", feature = "u8"))]
1031    (Value::U64(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1032    #[cfg(all(feature = "u64", feature = "u16"))]
1033    (Value::U64(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1034    #[cfg(all(feature = "u64", feature = "u32"))]
1035    (Value::U64(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1036    #[cfg(all(feature = "u64", feature = "u128"))]
1037    (Value::U64(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1038    #[cfg(all(feature = "u64", feature = "i8"))]
1039    (Value::U64(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1040    #[cfg(all(feature = "u64", feature = "i16"))]
1041    (Value::U64(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1042    #[cfg(all(feature = "u64", feature = "i32"))]
1043    (Value::U64(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1044    #[cfg(all(feature = "u64", feature = "i128"))]
1045    (Value::U64(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1046    #[cfg(all(feature = "u64", feature = "f32"))]
1047    (Value::U64(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1048    #[cfg(all(feature = "u64", feature = "f64"))]
1049    (Value::U64(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1050
1051    #[cfg(all(feature = "u128", feature = "u8"))]
1052    (Value::U128(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1053    #[cfg(all(feature = "u128", feature = "u16"))]
1054    (Value::U128(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1055    #[cfg(all(feature = "u128", feature = "u32"))]
1056    (Value::U128(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1057    #[cfg(all(feature = "u128", feature = "u64"))]
1058    (Value::U128(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1059    #[cfg(all(feature = "u128", feature = "i8"))]
1060    (Value::U128(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1061    #[cfg(all(feature = "u128", feature = "i16"))]
1062    (Value::U128(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1063    #[cfg(all(feature = "u128", feature = "i32"))]
1064    (Value::U128(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1065    #[cfg(all(feature = "u128", feature = "i64"))]
1066    (Value::U128(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1067    #[cfg(all(feature = "u128", feature = "f32"))]
1068    (Value::U128(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1069    #[cfg(all(feature = "u128", feature = "f64"))]
1070    (Value::U128(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1071
1072    // ==== Signed widening and narrowing ====
1073    #[cfg(all(feature = "i8", feature = "i16"))]
1074    (Value::I8(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1075    #[cfg(all(feature = "i8", feature = "i32"))]
1076    (Value::I8(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1077    #[cfg(all(feature = "i8", feature = "i64"))]
1078    (Value::I8(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1079    #[cfg(all(feature = "i8", feature = "i128"))]
1080    (Value::I8(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1081    #[cfg(all(feature = "i8", feature = "u16"))]
1082    (Value::I8(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1083    #[cfg(all(feature = "i8", feature = "u32"))]
1084    (Value::I8(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1085    #[cfg(all(feature = "i8", feature = "u64"))]
1086    (Value::I8(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1087    #[cfg(all(feature = "i8", feature = "u128"))]
1088    (Value::I8(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1089    #[cfg(all(feature = "i8", feature = "f32"))]
1090    (Value::I8(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1091    #[cfg(all(feature = "i8", feature = "f64"))]
1092    (Value::I8(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1093
1094    #[cfg(all(feature = "i16", feature = "i8"))]
1095    (Value::I16(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1096    #[cfg(all(feature = "i16", feature = "i32"))]
1097    (Value::I16(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1098    #[cfg(all(feature = "i16", feature = "i64"))]
1099    (Value::I16(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1100    #[cfg(all(feature = "i16", feature = "i128"))]
1101    (Value::I16(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1102    #[cfg(all(feature = "i16", feature = "u8"))]
1103    (Value::I16(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1104    #[cfg(all(feature = "i16", feature = "u32"))]
1105    (Value::I16(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1106    #[cfg(all(feature = "i16", feature = "u64"))]
1107    (Value::I16(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1108    #[cfg(all(feature = "i16", feature = "u128"))]
1109    (Value::I16(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1110    #[cfg(all(feature = "i16", feature = "f32"))]
1111    (Value::I16(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1112    #[cfg(all(feature = "i16", feature = "f64"))]
1113    (Value::I16(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1114
1115    #[cfg(all(feature = "i32", feature = "i8"))]
1116    (Value::I32(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1117    #[cfg(all(feature = "i32", feature = "i16"))]
1118    (Value::I32(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1119    #[cfg(all(feature = "i32", feature = "i64"))]
1120    (Value::I32(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1121    #[cfg(all(feature = "i32", feature = "i128"))]
1122    (Value::I32(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1123    #[cfg(all(feature = "i32", feature = "u8"))]
1124    (Value::I32(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1125    #[cfg(all(feature = "i32", feature = "u16"))]
1126    (Value::I32(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1127    #[cfg(all(feature = "i32", feature = "u64"))]
1128    (Value::I32(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1129    #[cfg(all(feature = "i32", feature = "u128"))]
1130    (Value::I32(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1131    #[cfg(all(feature = "i32", feature = "f32"))]
1132    (Value::I32(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1133    #[cfg(all(feature = "i32", feature = "f64"))]
1134    (Value::I32(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1135
1136    #[cfg(all(feature = "i64", feature = "i8"))]
1137    (Value::I64(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1138    #[cfg(all(feature = "i64", feature = "i16"))]
1139    (Value::I64(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1140    #[cfg(all(feature = "i64", feature = "i32"))]
1141    (Value::I64(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1142    #[cfg(all(feature = "i64", feature = "i128"))]
1143    (Value::I64(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1144    #[cfg(all(feature = "i64", feature = "u8"))]
1145    (Value::I64(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1146    #[cfg(all(feature = "i64", feature = "u16"))]
1147    (Value::I64(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1148    #[cfg(all(feature = "i64", feature = "u32"))]
1149    (Value::I64(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1150    #[cfg(all(feature = "i64", feature = "u128"))]
1151    (Value::I64(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1152    #[cfg(all(feature = "i64", feature = "f32"))]
1153    (Value::I64(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1154    #[cfg(all(feature = "i64", feature = "f64"))]
1155    (Value::I64(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1156
1157    #[cfg(all(feature = "i128", feature = "i8"))]
1158    (Value::I128(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1159    #[cfg(all(feature = "i128", feature = "i16"))]
1160    (Value::I128(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1161    #[cfg(all(feature = "i128", feature = "i32"))]
1162    (Value::I128(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1163    #[cfg(all(feature = "i128", feature = "i64"))]
1164    (Value::I128(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1165    #[cfg(all(feature = "i128", feature = "u8"))]
1166    (Value::I128(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1167    #[cfg(all(feature = "i128", feature = "u16"))]
1168    (Value::I128(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1169    #[cfg(all(feature = "i128", feature = "u32"))]
1170    (Value::I128(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1171    #[cfg(all(feature = "i128", feature = "u64"))]
1172    (Value::I128(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1173    #[cfg(all(feature = "i128", feature = "f32"))]
1174    (Value::I128(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1175    #[cfg(all(feature = "i128", feature = "f64"))]
1176    (Value::I128(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1177
1178    // ==== Float widening and narrowing ====
1179    #[cfg(all(feature = "f32", feature = "f64"))]
1180    (Value::F32(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(v.borrow().0 as f64)))),
1181    #[cfg(all(feature = "f32", feature = "f64"))]
1182    (Value::F64(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(v.borrow().0 as f32)))),
1183
1184    // ==== Float to integer conversions (truncate) ====
1185    #[cfg(all(feature = "f32", feature = "i8"))]
1186    (Value::F32(v), ValueKind::I8) => Some(Value::I8(Ref::new(v.borrow().0 as i8))),
1187    #[cfg(all(feature = "f32", feature = "i16"))]
1188    (Value::F32(v), ValueKind::I16) => Some(Value::I16(Ref::new(v.borrow().0 as i16))),
1189    #[cfg(all(feature = "f32", feature = "i32"))]
1190    (Value::F32(v), ValueKind::I32) => Some(Value::I32(Ref::new(v.borrow().0 as i32))),
1191    #[cfg(all(feature = "f32", feature = "i64"))]
1192    (Value::F32(v), ValueKind::I64) => Some(Value::I64(Ref::new(v.borrow().0 as i64))),
1193    #[cfg(all(feature = "f32", feature = "i128"))]
1194    (Value::F32(v), ValueKind::I128) => Some(Value::I128(Ref::new(v.borrow().0 as i128))),
1195    #[cfg(all(feature = "f32", feature = "u8"))]
1196    (Value::F32(v), ValueKind::U8) => Some(Value::U8(Ref::new(v.borrow().0 as u8))),
1197    #[cfg(all(feature = "f32", feature = "u16"))]
1198    (Value::F32(v), ValueKind::U16) => Some(Value::U16(Ref::new(v.borrow().0 as u16))),
1199    #[cfg(all(feature = "f32", feature = "u32"))]
1200    (Value::F32(v), ValueKind::U32) => Some(Value::U32(Ref::new(v.borrow().0 as u32))),
1201    #[cfg(all(feature = "f32", feature = "u64"))]
1202    (Value::F32(v), ValueKind::U64) => Some(Value::U64(Ref::new(v.borrow().0 as u64))),
1203    #[cfg(all(feature = "f32", feature = "u128"))]
1204    (Value::F32(v), ValueKind::U128) => Some(Value::U128(Ref::new(v.borrow().0 as u128))),
1205
1206    #[cfg(all(feature = "f64", feature = "i8"))]
1207    (Value::F64(v), ValueKind::I8) => Some(Value::I8(Ref::new(v.borrow().0 as i8))),
1208    #[cfg(all(feature = "f64", feature = "i16"))]
1209    (Value::F64(v), ValueKind::I16) => Some(Value::I16(Ref::new(v.borrow().0 as i16))),
1210    #[cfg(all(feature = "f64", feature = "i32"))]
1211    (Value::F64(v), ValueKind::I32) => Some(Value::I32(Ref::new(v.borrow().0 as i32))),
1212    #[cfg(all(feature = "f64", feature = "i64"))]
1213    (Value::F64(v), ValueKind::I64) => Some(Value::I64(Ref::new(v.borrow().0 as i64))),
1214    #[cfg(all(feature = "f64", feature = "i128"))]
1215    (Value::F64(v), ValueKind::I128) => Some(Value::I128(Ref::new(v.borrow().0 as i128))),
1216    #[cfg(all(feature = "f64", feature = "u8"))]
1217    (Value::F64(v), ValueKind::U8) => Some(Value::U8(Ref::new(v.borrow().0 as u8))),
1218    #[cfg(all(feature = "f64", feature = "u16"))]
1219    (Value::F64(v), ValueKind::U16) => Some(Value::U16(Ref::new(v.borrow().0 as u16))),
1220    #[cfg(all(feature = "f64", feature = "u32"))]
1221    (Value::F64(v), ValueKind::U32) => Some(Value::U32(Ref::new(v.borrow().0 as u32))),
1222    #[cfg(all(feature = "f64", feature = "u64"))]
1223    (Value::F64(v), ValueKind::U64) => Some(Value::U64(Ref::new(v.borrow().0 as u64))),
1224    #[cfg(all(feature = "f64", feature = "u128"))]
1225    (Value::F64(v), ValueKind::U128) => Some(Value::U128(Ref::new(v.borrow().0 as u128))),
1226
1227      /*
1228      // ==== INDEX conversions ====
1229      (Value::Index(i), U32) => Some(Value::U32(Ref::new((*i.borrow()) as u32))),
1230      (Value::U32(v), Index) => Some(Value::Index(Ref::new((*v.borrow()) as usize))),
1231
1232
1233      // ==== MATRIX conversions (element-wise) ====
1234      (Value::MatrixU8(m), MatrixU16) => Some(Value::MatrixU16(m.map(|x| *x as u16))),
1235      (Value::MatrixI32(m), MatrixF64) => Some(Value::MatrixF64(m.map(|x| (*x) as f64))),
1236      // You can expand other matrix conversions similarly...
1237
1238      // ==== COMPLEX TYPES (stubs) ====
1239      (Value::Set(set), Set(_)) => Some(Value::Set(set.clone())), // TODO: element-wise convert
1240      (Value::Map(map), Map(_)) => Some(Value::Map(map.clone())), // TODO: key/value convert
1241      (Value::Record(r), Record(_)) => Some(Value::Record(r.clone())), // TODO: field convert
1242      (Value::Table(t), Table(_)) => Some(Value::Table(t.clone())), // TODO: column convert
1243
1244      // ==== ENUM, KIND ====
1245      (Value::Enum(e), Enum(_)) => Some(Value::Enum(e.clone())),
1246      (Value::Kind(k), Kind(_)) => Some(Value::Kind(k.clone())),
1247
1248      // ==== SPECIAL CASES ====
1249      (Value::IndexAll, IndexAll) => Some(Value::IndexAll),
1250      (Value::Empty, Empty) => Some(Value::Empty),
1251      */
1252      // ==== FALLBACK ====
1253      _ => None,
1254    }
1255  }
1256
1257  pub fn size_of(&self) -> usize {
1258    match self {
1259      #[cfg(feature = "rational")]
1260      Value::R64(x) => 16,
1261      #[cfg(feature = "u8")]
1262      Value::U8(x) => 1,
1263      #[cfg(feature = "u16")]
1264      Value::U16(x) => 2,
1265      #[cfg(feature = "u32")]
1266      Value::U32(x) => 4,
1267      #[cfg(feature = "u64")]
1268      Value::U64(x) => 8,
1269      #[cfg(feature = "u128")]
1270      Value::U128(x) => 16,
1271      #[cfg(feature = "i8")]
1272      Value::I8(x) => 1,
1273      #[cfg(feature = "i16")]
1274      Value::I16(x) => 2,
1275      #[cfg(feature = "i32")]
1276      Value::I32(x) => 4,
1277      #[cfg(feature = "i64")]
1278      Value::I64(x) => 8,
1279      #[cfg(feature = "i128")]
1280      Value::I128(x) => 16,
1281      #[cfg(feature = "f32")]
1282      Value::F32(x) => 4,
1283      #[cfg(feature = "f64")]
1284      Value::F64(x) => 8,
1285      #[cfg(any(feature = "bool", feature = "variable_define"))]
1286      Value::Bool(x) => 1,
1287      #[cfg(feature = "complex")]
1288      Value::C64(x) => 16,
1289      #[cfg(all(feature = "matrix"))]
1290      Value::MatrixIndex(x) => x.size_of(),
1291      #[cfg(all(feature = "matrix", feature = "bool"))]
1292      Value::MatrixBool(x) => x.size_of(),
1293      #[cfg(all(feature = "matrix", feature = "u8"))]
1294      Value::MatrixU8(x)   => x.size_of(),
1295      #[cfg(all(feature = "matrix", feature = "u16"))]
1296      Value::MatrixU16(x)  => x.size_of(),
1297      #[cfg(all(feature = "matrix", feature = "u32"))]
1298      Value::MatrixU32(x)  => x.size_of(),
1299      #[cfg(all(feature = "matrix", feature = "u64"))]
1300      Value::MatrixU64(x)  => x.size_of(),
1301      #[cfg(all(feature = "matrix", feature = "u128"))]
1302      Value::MatrixU128(x) => x.size_of(),
1303      #[cfg(all(feature = "matrix", feature = "i8"))]
1304      Value::MatrixI8(x)   => x.size_of(),
1305      #[cfg(all(feature = "matrix", feature = "i16"))]
1306      Value::MatrixI16(x)  => x.size_of(),
1307      #[cfg(all(feature = "matrix", feature = "i32"))]
1308      Value::MatrixI32(x)  => x.size_of(),
1309      #[cfg(all(feature = "matrix", feature = "i64"))]
1310      Value::MatrixI64(x)  => x.size_of(),
1311      #[cfg(all(feature = "matrix", feature = "i128"))]
1312      Value::MatrixI128(x) => x.size_of(),
1313      #[cfg(all(feature = "matrix", feature = "f32"))]
1314      Value::MatrixF32(x)  => x.size_of(),
1315      #[cfg(all(feature = "matrix", feature = "f64"))]
1316      Value::MatrixF64(x)  => x.size_of(),
1317      #[cfg(feature = "matrix")]
1318      Value::MatrixValue(x)  => x.size_of(),
1319      #[cfg(all(feature = "matrix", feature = "string"))]
1320      Value::MatrixString(x) => x.size_of(),
1321      #[cfg(all(feature = "matrix", feature = "rational"))]
1322      Value::MatrixR64(x) => x.size_of(),
1323      #[cfg(all(feature = "matrix", feature = "complex"))]
1324      Value::MatrixC64(x) => x.size_of(),
1325      #[cfg(any(feature = "string", feature = "variable_define"))]
1326      Value::String(x) => x.borrow().len(),
1327      #[cfg(feature = "atom")]
1328      Value::Atom(x) => 8,
1329      #[cfg(feature = "set")]
1330      Value::Set(x) => x.borrow().size_of(),
1331      #[cfg(feature = "map")]
1332      Value::Map(x) => x.borrow().size_of(),
1333      #[cfg(feature = "table")]
1334      Value::Table(x) => x.borrow().size_of(),
1335      #[cfg(feature = "record")]
1336      Value::Record(x) => x.borrow().size_of(),
1337      #[cfg(feature = "tuple")]
1338      Value::Tuple(x) => x.borrow().size_of(),
1339      #[cfg(feature = "enum")]
1340      Value::Enum(x) => x.borrow().size_of(),
1341      Value::MutableReference(x) => x.borrow().size_of(),
1342      Value::Id(_) => 8,
1343      Value::Index(x) => 8,
1344      Value::Kind(_) => 0, // Kind is not a value, so it has no size
1345      Value::Empty => 0,
1346      Value::IndexAll => 0, // IndexAll is a special value, so it has no size
1347    }
1348  }
1349
1350  #[cfg(feature = "pretty_print")]
1351  pub fn to_html(&self) -> String {
1352    match self {
1353      #[cfg(feature = "u8")]
1354      Value::U8(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1355      #[cfg(feature = "u16")]
1356      Value::U16(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1357      #[cfg(feature = "u32")]
1358      Value::U32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1359      #[cfg(feature = "u64")]
1360      Value::U64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1361      #[cfg(feature = "i8")]
1362      Value::I8(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1363      #[cfg(feature = "i128")]
1364      Value::I128(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1365      #[cfg(feature = "i16")]
1366      Value::I16(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1367      #[cfg(feature = "i32")]
1368      Value::I32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1369      #[cfg(feature = "i64")]
1370      Value::I64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1371      #[cfg(feature = "i128")]
1372      Value::I128(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1373      #[cfg(feature = "f32")]
1374      Value::F32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1375      #[cfg(feature = "f64")]
1376      Value::F64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1377      #[cfg(any(feature = "string", feature = "variable_define"))]
1378      Value::String(s) => format!("<span class='mech-string'>\"{}\"</span>", s.borrow()),
1379      #[cfg(any(feature = "bool", feature = "variable_define"))]
1380      Value::Bool(b) => format!("<span class='mech-boolean'>{}</span>", b.borrow()),
1381      #[cfg(feature = "complex")]
1382      Value::C64(c) => c.borrow().to_html(),
1383      #[cfg(all(feature = "matrix", feature = "u8"))]
1384      Value::MatrixU8(m) => m.to_html(),
1385      #[cfg(all(feature = "matrix", feature = "u16"))]
1386      Value::MatrixU16(m) => m.to_html(),
1387      #[cfg(all(feature = "matrix", feature = "u32"))]
1388      Value::MatrixU32(m) => m.to_html(),
1389      #[cfg(all(feature = "matrix", feature = "u64"))]
1390      Value::MatrixU64(m) => m.to_html(),
1391      #[cfg(all(feature = "matrix", feature = "u128"))]
1392      Value::MatrixU128(m) => m.to_html(),
1393      #[cfg(all(feature = "matrix", feature = "i8"))]
1394      Value::MatrixI8(m) => m.to_html(),
1395      #[cfg(all(feature = "matrix", feature = "i16"))]
1396      Value::MatrixI16(m) => m.to_html(),
1397      #[cfg(all(feature = "matrix", feature = "i32"))]
1398      Value::MatrixI32(m) => m.to_html(),
1399      #[cfg(all(feature = "matrix", feature = "i64"))]
1400      Value::MatrixI64(m) => m.to_html(),
1401      #[cfg(all(feature = "matrix", feature = "i128"))]
1402      Value::MatrixI128(m) => m.to_html(),
1403      #[cfg(all(feature = "matrix", feature = "f64"))]
1404      Value::MatrixF64(m) => m.to_html(),
1405      #[cfg(all(feature = "matrix", feature = "f32"))]
1406      Value::MatrixF32(m) => m.to_html(),
1407      #[cfg(feature = "matrix")]
1408      Value::MatrixIndex(m) => m.to_html(),
1409      #[cfg(all(feature = "matrix", feature = "bool"))]
1410      Value::MatrixBool(m) => m.to_html(),
1411      #[cfg(all(feature = "matrix", feature = "string"))]
1412      Value::MatrixString(m) => m.to_html(),
1413      #[cfg(feature = "matrix")]
1414      Value::MatrixValue(m) => m.to_html(),
1415      #[cfg(all(feature = "matrix", feature = "rational"))]
1416      Value::MatrixR64(m) => m.to_html(),
1417      #[cfg(all(feature = "matrix", feature = "complex"))]
1418      Value::MatrixC64(m) => m.to_html(),
1419      #[cfg(feature = "atom")]
1420      Value::Atom(a) => format!("<span class=\"mech-atom\"><span class=\"mech-atom-grave\">`</span><span class=\"mech-atom-name\">{}</span></span>",a.borrow()),
1421      #[cfg(feature = "set")]
1422      Value::Set(s) => s.borrow().to_html(),
1423      #[cfg(feature = "map")]
1424      Value::Map(m) => m.borrow().to_html(),
1425      #[cfg(feature = "table")]
1426      Value::Table(t) => t.borrow().to_html(),
1427      #[cfg(feature = "record")]
1428      Value::Record(r) => r.borrow().to_html(),
1429      #[cfg(feature = "tuple")]
1430      Value::Tuple(t) => t.borrow().to_html(),
1431      #[cfg(feature = "enum")]
1432      Value::Enum(e) => e.borrow().to_html(),
1433      Value::MutableReference(m) => {
1434        let inner = m.borrow();
1435        format!("<span class='mech-reference'>{}</span>", inner.to_html())
1436      },
1437      _ => "???".to_string(),
1438    }
1439  }
1440
1441  pub fn shape(&self) -> Vec<usize> {
1442    match self {
1443      #[cfg(feature = "rational")]
1444      Value::R64(x) => vec![1,1],
1445      #[cfg(feature = "complex")]
1446      Value::C64(x) => vec![1,1],
1447      #[cfg(feature = "u8")]
1448      Value::U8(x) => vec![1,1],
1449      #[cfg(feature = "u16")]
1450      Value::U16(x) => vec![1,1],
1451      #[cfg(feature = "u32")]
1452      Value::U32(x) => vec![1,1],
1453      #[cfg(feature = "u64")]
1454      Value::U64(x) => vec![1,1],
1455      #[cfg(feature = "u128")]
1456      Value::U128(x) => vec![1,1],
1457      #[cfg(feature = "i8")]
1458      Value::I8(x) => vec![1,1],
1459      #[cfg(feature = "i16")]
1460      Value::I16(x) => vec![1,1],
1461      #[cfg(feature = "i32")]
1462      Value::I32(x) => vec![1,1],
1463      #[cfg(feature = "i64")]
1464      Value::I64(x) => vec![1,1],
1465      #[cfg(feature = "i128")]
1466      Value::I128(x) => vec![1,1],
1467      #[cfg(feature = "f32")]
1468      Value::F32(x) => vec![1,1],
1469      #[cfg(feature = "f64")]
1470      Value::F64(x) => vec![1,1],
1471      #[cfg(any(feature = "string", feature = "variable_define"))]
1472      Value::String(x) => vec![1,1],
1473      #[cfg(any(feature = "bool", feature = "variable_define"))]
1474      Value::Bool(x) => vec![1,1],
1475      #[cfg(feature = "atom")]
1476      Value::Atom(x) => vec![1,1],
1477      #[cfg(feature = "matrix")]
1478      Value::MatrixIndex(x) => x.shape(),
1479      #[cfg(all(feature = "matrix", feature = "bool"))]
1480      Value::MatrixBool(x) => x.shape(),
1481      #[cfg(all(feature = "matrix", feature = "u8"))]
1482      Value::MatrixU8(x) => x.shape(),
1483      #[cfg(all(feature = "matrix", feature = "u16"))]
1484      Value::MatrixU16(x) => x.shape(),
1485      #[cfg(all(feature = "matrix", feature = "u32"))]
1486      Value::MatrixU32(x) => x.shape(),
1487      #[cfg(all(feature = "matrix", feature = "u64"))]
1488      Value::MatrixU64(x) => x.shape(),
1489      #[cfg(all(feature = "matrix", feature = "u128"))]
1490      Value::MatrixU128(x) => x.shape(),
1491      #[cfg(all(feature = "matrix", feature = "i8"))]
1492      Value::MatrixI8(x) => x.shape(),
1493      #[cfg(all(feature = "matrix", feature = "i16"))]
1494      Value::MatrixI16(x) => x.shape(),
1495      #[cfg(all(feature = "matrix", feature = "i32"))]
1496      Value::MatrixI32(x) => x.shape(),
1497      #[cfg(all(feature = "matrix", feature = "i64"))]
1498      Value::MatrixI64(x) => x.shape(),
1499      #[cfg(all(feature = "matrix", feature = "i128"))]
1500      Value::MatrixI128(x) => x.shape(),
1501      #[cfg(all(feature = "matrix", feature = "f32"))]
1502      Value::MatrixF32(x) => x.shape(),
1503      #[cfg(all(feature = "matrix", feature = "f64"))]
1504      Value::MatrixF64(x) => x.shape(),
1505      #[cfg(all(feature = "matrix", feature = "string"))]
1506      Value::MatrixString(x) => x.shape(),
1507      #[cfg(feature = "matrix")]
1508      Value::MatrixValue(x) => x.shape(),
1509      #[cfg(all(feature = "matrix", feature = "rational"))]
1510      Value::MatrixR64(x) => x.shape(),
1511      #[cfg(all(feature = "matrix", feature = "complex"))]
1512      Value::MatrixC64(x) => x.shape(),
1513      #[cfg(feature = "enum")]
1514      Value::Enum(x) => vec![1,1],
1515      #[cfg(feature = "table")]
1516      Value::Table(x) => x.borrow().shape(),
1517      #[cfg(feature = "set")]
1518      Value::Set(x) => vec![1,x.borrow().set.len()],
1519      #[cfg(feature = "map")]
1520      Value::Map(x) => vec![1,x.borrow().map.len()],
1521      #[cfg(feature = "record")]
1522      Value::Record(x) => x.borrow().shape(),
1523      #[cfg(feature = "tuple")]
1524      Value::Tuple(x) => vec![1,x.borrow().size()],
1525      Value::Index(x) => vec![1,1],
1526      Value::MutableReference(x) => x.borrow().shape(),
1527      Value::Empty => vec![0,0],
1528      Value::IndexAll => vec![0,0],
1529      Value::Kind(_) => vec![0,0],
1530      Value::Id(x) => vec![0,0],
1531    }
1532  }
1533
1534  pub fn deref_kind(&self) -> ValueKind {
1535    match self {
1536      Value::MutableReference(x) => x.borrow().kind(),
1537      x => x.kind(),
1538    }
1539  }
1540
1541  pub fn kind(&self) -> ValueKind {
1542    match self {
1543      #[cfg(feature = "complex")]
1544      Value::C64(_) => ValueKind::C64,
1545      #[cfg(feature = "rational")]
1546      Value::R64(_) => ValueKind::R64,
1547      #[cfg(feature = "u8")]
1548      Value::U8(_) => ValueKind::U8,
1549      #[cfg(feature = "u16")]
1550      Value::U16(_) => ValueKind::U16,
1551      #[cfg(feature = "u32")]
1552      Value::U32(_) => ValueKind::U32,
1553      #[cfg(feature = "u64")]
1554      Value::U64(_) => ValueKind::U64,
1555      #[cfg(feature = "u128")]
1556      Value::U128(_) => ValueKind::U128,
1557      #[cfg(feature = "i8")]
1558      Value::I8(_) => ValueKind::I8,
1559      #[cfg(feature = "i16")]
1560      Value::I16(_) => ValueKind::I16,
1561      #[cfg(feature = "i32")]
1562      Value::I32(_) => ValueKind::I32,
1563      #[cfg(feature = "i64")]
1564      Value::I64(_) => ValueKind::I64,
1565      #[cfg(feature = "i128")]
1566      Value::I128(_) => ValueKind::I128,
1567      #[cfg(feature = "f32")]
1568      Value::F32(_) => ValueKind::F32,
1569      #[cfg(feature = "f64")]
1570      Value::F64(_) => ValueKind::F64,
1571      #[cfg(any(feature = "string", feature = "variable_define"))]
1572      Value::String(_) => ValueKind::String,
1573      #[cfg(any(feature = "bool", feature = "variable_define"))]
1574      Value::Bool(_) => ValueKind::Bool,
1575      #[cfg(feature = "atom")]
1576      Value::Atom(x) => ValueKind::Atom((x.borrow().0)),
1577      #[cfg(feature = "matrix")]
1578      Value::MatrixValue(x) => ValueKind::Matrix(Box::new(ValueKind::Any),x.shape()),
1579      #[cfg(feature = "matrix")]
1580      Value::MatrixIndex(x) => ValueKind::Matrix(Box::new(ValueKind::Index),x.shape()),
1581      #[cfg(all(feature = "matrix", feature = "bool"))]
1582      Value::MatrixBool(x) => ValueKind::Matrix(Box::new(ValueKind::Bool), x.shape()),
1583      #[cfg(all(feature = "matrix", feature = "u8"))]
1584      Value::MatrixU8(x) => ValueKind::Matrix(Box::new(ValueKind::U8), x.shape()),
1585      #[cfg(all(feature = "matrix", feature = "u16"))]
1586      Value::MatrixU16(x) => ValueKind::Matrix(Box::new(ValueKind::U16), x.shape()),
1587      #[cfg(all(feature = "matrix", feature = "u32"))]
1588      Value::MatrixU32(x) => ValueKind::Matrix(Box::new(ValueKind::U32), x.shape()),
1589      #[cfg(all(feature = "matrix", feature = "u64"))]
1590      Value::MatrixU64(x) => ValueKind::Matrix(Box::new(ValueKind::U64), x.shape()),
1591      #[cfg(all(feature = "matrix", feature = "u128"))]
1592      Value::MatrixU128(x) => ValueKind::Matrix(Box::new(ValueKind::U128), x.shape()),
1593      #[cfg(all(feature = "matrix", feature = "i8"))]
1594      Value::MatrixI8(x) => ValueKind::Matrix(Box::new(ValueKind::I8), x.shape()),
1595      #[cfg(all(feature = "matrix", feature = "i16"))]
1596      Value::MatrixI16(x) => ValueKind::Matrix(Box::new(ValueKind::I16), x.shape()),
1597      #[cfg(all(feature = "matrix", feature = "i32"))]
1598      Value::MatrixI32(x) => ValueKind::Matrix(Box::new(ValueKind::I32), x.shape()),
1599      #[cfg(all(feature = "matrix", feature = "i64"))]
1600      Value::MatrixI64(x) => ValueKind::Matrix(Box::new(ValueKind::I64), x.shape()),
1601      #[cfg(all(feature = "matrix", feature = "i128"))]
1602      Value::MatrixI128(x) => ValueKind::Matrix(Box::new(ValueKind::I128), x.shape()),
1603      #[cfg(all(feature = "matrix", feature = "f32"))]
1604      Value::MatrixF32(x) => ValueKind::Matrix(Box::new(ValueKind::F32), x.shape()),
1605      #[cfg(all(feature = "matrix", feature = "f64"))]
1606      Value::MatrixF64(x) => ValueKind::Matrix(Box::new(ValueKind::F64), x.shape()),
1607      #[cfg(all(feature = "matrix", feature = "string"))]
1608      Value::MatrixString(x) => ValueKind::Matrix(Box::new(ValueKind::String), x.shape()),
1609      #[cfg(all(feature = "matrix", feature = "rational"))]
1610      Value::MatrixR64(x) => ValueKind::Matrix(Box::new(ValueKind::R64), x.shape()),
1611      #[cfg(all(feature = "matrix", feature = "complex"))]
1612      Value::MatrixC64(x) => ValueKind::Matrix(Box::new(ValueKind::C64), x.shape()),
1613      #[cfg(feature = "table")]
1614      Value::Table(x) => x.borrow().kind(),
1615      #[cfg(feature = "set")]
1616      Value::Set(x) => x.borrow().kind(),
1617      #[cfg(feature = "map")]
1618      Value::Map(x) => x.borrow().kind(),
1619      #[cfg(feature = "record")]
1620      Value::Record(x) => x.borrow().kind(),
1621      #[cfg(feature = "tuple")]
1622      Value::Tuple(x) => x.borrow().kind(),
1623      #[cfg(feature = "enum")]
1624      Value::Enum(x) => x.borrow().kind(),
1625      Value::MutableReference(x) => ValueKind::Reference(Box::new(x.borrow().kind())),
1626      Value::Empty => ValueKind::Empty,
1627      Value::IndexAll => ValueKind::Empty,
1628      Value::Id(x) => ValueKind::Id,
1629      Value::Index(x) => ValueKind::Index,
1630      Value::Kind(x) => x.clone(),
1631    }
1632  }
1633
1634  #[cfg(feature = "matrix")]
1635  pub fn is_matrix(&self) -> bool {
1636    match self {
1637      #[cfg(feature = "matrix")]
1638      Value::MatrixIndex(_) => true,
1639      #[cfg(all(feature = "matrix", feature = "bool"))]
1640      Value::MatrixBool(_) => true,
1641      #[cfg(all(feature = "matrix", feature = "u8"))]
1642      Value::MatrixU8(_) => true,
1643      #[cfg(all(feature = "matrix", feature = "u16"))]
1644      Value::MatrixU16(_) => true,
1645      #[cfg(all(feature = "matrix", feature = "u32"))]
1646      Value::MatrixU32(_) => true,
1647      #[cfg(all(feature = "matrix", feature = "u64"))]
1648      Value::MatrixU64(_) => true,
1649      #[cfg(all(feature = "matrix", feature = "u128"))]
1650      Value::MatrixU128(_) => true,
1651      #[cfg(all(feature = "matrix", feature = "i8"))]
1652      Value::MatrixI8(_) => true,
1653      #[cfg(all(feature = "matrix", feature = "i16"))]
1654      Value::MatrixI16(_) => true,
1655      #[cfg(all(feature = "matrix", feature = "i32"))]
1656      Value::MatrixI32(_) => true,
1657      #[cfg(all(feature = "matrix", feature = "i64"))]
1658      Value::MatrixI64(_) => true,
1659      #[cfg(all(feature = "matrix", feature = "i128"))]
1660      Value::MatrixI128(_) => true,
1661      #[cfg(all(feature = "matrix", feature = "f32"))]
1662      Value::MatrixF32(_) => true,
1663      #[cfg(all(feature = "matrix", feature = "f64"))]
1664      Value::MatrixF64(_) => true,
1665      #[cfg(all(feature = "matrix", feature = "string"))]
1666      Value::MatrixString(_) => true,
1667      #[cfg(all(feature = "matrix", feature = "rational"))]
1668      Value::MatrixR64(_) => true,
1669      #[cfg(all(feature = "matrix", feature = "complex"))]
1670      Value::MatrixC64(_) => true,
1671      #[cfg(feature = "matrix")]
1672      Value::MatrixValue(_) => true,
1673      _ => false,
1674    }
1675  }
1676
1677  pub fn is_scalar(&self) -> bool {
1678    match self {
1679      #[cfg(feature = "u8")]
1680      Value::U8(_) => true,
1681      #[cfg(feature = "u16")]
1682      Value::U16(_) => true,
1683      #[cfg(feature = "u32")]
1684      Value::U32(_) => true,
1685      #[cfg(feature = "u64")]
1686      Value::U64(_) => true,
1687      #[cfg(feature = "u128")]
1688      Value::U128(_) => true,
1689      #[cfg(feature = "i8")]
1690      Value::I8(_) => true,
1691      #[cfg(feature = "i16")]
1692      Value::I16(_) => true,
1693      #[cfg(feature = "i32")]
1694      Value::I32(_) => true,
1695      #[cfg(feature = "i64")]
1696      Value::I64(_) => true,
1697      #[cfg(feature = "i128")]
1698      Value::I128(_) => true,
1699      #[cfg(feature = "f32")]
1700      Value::F32(_) => true,
1701      #[cfg(feature = "f64")]
1702      Value::F64(_) => true,
1703      #[cfg(any(feature = "bool", feature = "variable_define"))]
1704      Value::Bool(_) => true,
1705      #[cfg(any(feature = "string", feature = "variable_define"))]
1706      Value::String(_) => true,
1707      #[cfg(feature = "atom")]
1708      Value::Atom(_) => true,
1709      Value::Index(_) => true,
1710      _ => false,
1711    }
1712  }
1713
1714  #[cfg(any(feature = "bool", feature = "variable_define"))]
1715  pub fn as_bool(&self) -> MResult<Ref<bool>> {if let Value::Bool(v) = self { Ok(v.clone()) } else if let Value::MutableReference(val) = self { val.borrow().as_bool() } else { Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}) }}
1716  
1717  impl_as_type!(i8);
1718  impl_as_type!(i16);
1719  impl_as_type!(i32);
1720  impl_as_type!(i64);
1721  impl_as_type!(i128);
1722  impl_as_type!(u8);
1723  impl_as_type!(u16);
1724  impl_as_type!(u32);
1725  impl_as_type!(u64);
1726  impl_as_type!(u128);
1727
1728  #[cfg(any(feature = "string", feature = "variable_define"))]
1729  pub fn as_string(&self) -> MResult<Ref<String>> {
1730    match self {
1731      Value::String(v) => Ok(v.clone()),
1732      #[cfg(feature = "u8")]
1733      Value::U8(v) => Ok(Ref::new(v.borrow().to_string())),
1734      #[cfg(feature = "u16")]
1735      Value::U16(v) => Ok(Ref::new(v.borrow().to_string())),
1736      #[cfg(feature = "u32")]
1737      Value::U32(v) => Ok(Ref::new(v.borrow().to_string())),
1738      #[cfg(feature = "u64")]
1739      Value::U64(v) => Ok(Ref::new(v.borrow().to_string())),
1740      #[cfg(feature = "u128")]
1741      Value::U128(v) => Ok(Ref::new(v.borrow().to_string())),
1742      #[cfg(feature = "i8")]
1743      Value::I8(v) => Ok(Ref::new(v.borrow().to_string())),
1744      #[cfg(feature = "i16")]
1745      Value::I16(v) => Ok(Ref::new(v.borrow().to_string())),
1746      #[cfg(feature = "i32")]
1747      Value::I32(v) => Ok(Ref::new(v.borrow().to_string())),
1748      #[cfg(feature = "i64")]
1749      Value::I64(v) => Ok(Ref::new(v.borrow().to_string())),
1750      #[cfg(feature = "i128")]
1751      Value::I128(v) => Ok(Ref::new(v.borrow().to_string())),
1752      #[cfg(feature = "f32")]
1753      Value::F32(v) => Ok(Ref::new(format!("{}", v.borrow().0))),
1754      #[cfg(feature = "f64")]
1755      Value::F64(v) => Ok(Ref::new(format!("{}", v.borrow().0))),
1756      #[cfg(any(feature = "bool", feature = "variable_define"))]
1757      Value::Bool(v) => Ok(Ref::new(format!("{}", v.borrow()))),
1758      #[cfg(feature = "rational")]
1759      Value::R64(v) => Ok(Ref::new(v.borrow().to_string())),
1760      #[cfg(feature = "complex")]
1761      Value::C64(v) => Ok(Ref::new(v.borrow().to_string())),
1762      Value::MutableReference(val) => val.borrow().as_string(),
1763      _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}),
1764    }
1765  }
1766
1767  #[cfg(feature = "r64")]
1768  pub fn as_r64(&self) -> MResult<Ref<R64>> {
1769    match self {
1770      Value::R64(v) => Ok(v.clone()),
1771      #[cfg(feature = "f32")]
1772      Value::F32(v) => Ok(Ref::new(R64::new(v.borrow().0 as i64, 1))),
1773      #[cfg(feature = "f64")]
1774      Value::F64(v) => Ok(Ref::new(R64::new(v.borrow().0 as i64, 1))),
1775      #[cfg(feature = "u8")]
1776      Value::U8(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1777      #[cfg(feature = "u16")]
1778      Value::U16(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1779      #[cfg(feature = "u32")]
1780      Value::U32(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1781      #[cfg(feature = "u64")]
1782      Value::U64(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1783      #[cfg(feature = "u128")]
1784      Value::U128(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1785      #[cfg(feature = "i8")]
1786      Value::I8(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1787      #[cfg(feature = "i16")]
1788      Value::I16(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1789      #[cfg(feature = "i32")]
1790      Value::I32(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1791      #[cfg(feature = "i64")]
1792      Value::I64(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1793      #[cfg(feature = "i128")]
1794      Value::I128(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1795      Value::MutableReference(val) => val.borrow().as_r64(),
1796      _ => Err(MechError {
1797        file: file!().to_string(),
1798        tokens: vec![],
1799        msg: "Value cannot be converted to R64".to_string(),
1800        id: line!(),
1801        kind: MechErrorKind::UnhandledFunctionArgumentKind,
1802      }),
1803    }
1804  }
1805
1806  #[cfg(feature = "c64")]
1807  pub fn as_c64(&self) -> MResult<Ref<C64>> {
1808    match self {
1809      Value::C64(v) => Ok(v.clone()),
1810      #[cfg(feature = "f32")]
1811      Value::F32(v) => Ok(Ref::new(C64::new(v.borrow().0 as f64, 0.0))),
1812      #[cfg(feature = "f64")]
1813      Value::F64(v) => Ok(Ref::new(C64::new(v.borrow().0, 0.0))),
1814      #[cfg(feature = "u8")]
1815      Value::U8(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1816      #[cfg(feature = "u16")]
1817      Value::U16(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1818      #[cfg(feature = "u32")]
1819      Value::U32(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1820      #[cfg(feature = "u64")]
1821      Value::U64(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1822      #[cfg(feature = "u128")]
1823      Value::U128(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1824      #[cfg(feature = "i8")]
1825      Value::I8(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1826      #[cfg(feature = "i16")]
1827      Value::I16(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1828      #[cfg(feature = "i32")]
1829      Value::I32(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1830      #[cfg(feature = "i64")]
1831      Value::I64(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1832      #[cfg(feature = "i128")]
1833      Value::I128(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1834      Value::MutableReference(val) => val.borrow().as_c64(),
1835      _ => Err(MechError {
1836        file: file!().to_string(),
1837        tokens: vec![],
1838        msg: "Value cannot be converted to C64".to_string(),
1839        id: line!(),
1840        kind: MechErrorKind::UnhandledFunctionArgumentKind,
1841      }),
1842    }
1843  }
1844
1845  #[cfg(feature = "f32")]
1846  pub fn as_f32(&self) -> MResult<Ref<F32>> {
1847    match self {
1848      #[cfg(feature = "u8")]
1849      Value::U8(v) => Ok(Ref::new(F32::new(*v.borrow() as f32))),
1850      #[cfg(feature = "u16")]
1851      Value::U16(v) => Ok(Ref::new(F32::new(*v.borrow() as f32))),
1852      #[cfg(feature = "u32")]
1853      Value::U32(v) => Ok(Ref::new(F32::new(*v.borrow() as f32))),
1854      #[cfg(feature = "u64")]
1855      Value::U64(v) => Ok(Ref::new(F32::new(*v.borrow() as f32))),
1856      #[cfg(feature = "u128")]
1857      Value::U128(v) => Ok(Ref::new(F32::new(*v.borrow() as f32))),
1858      #[cfg(feature = "i8")]
1859      Value::I8(v) => Ok(Ref::new(F32::new(*v.borrow() as f32))),
1860      #[cfg(feature = "i16")]
1861      Value::I16(v) => Ok(Ref::new(F32::new(*v.borrow() as f32))),
1862      #[cfg(feature = "i32")]
1863      Value::I32(v) => Ok(Ref::new(F32::new(*v.borrow() as f32))),
1864      #[cfg(feature = "i64")]
1865      Value::I64(v) => Ok(Ref::new(F32::new(*v.borrow() as f32))),
1866      #[cfg(feature = "i128")]
1867      Value::I128(v) => Ok(Ref::new(F32::new(*v.borrow() as f32))),
1868      #[cfg(feature = "f32")]
1869      Value::F32(v) => Ok(v.clone()),
1870      #[cfg(feature = "f64")]
1871      Value::F64(v) => Ok(Ref::new(F32::new((*v.borrow()).0 as f32))),
1872      Value::MutableReference(val) => val.borrow().as_f32(),
1873      _ => Err(MechError {
1874        file: file!().to_string(),
1875        tokens: vec![],
1876        msg: "Value cannot be converted to F32".to_string(),
1877        id: line!(),
1878        kind: MechErrorKind::UnhandledFunctionArgumentKind,
1879      }),
1880    }
1881  }
1882
1883  #[cfg(feature = "f64")]
1884  pub fn as_f64(&self) -> MResult<Ref<F64>> {
1885    match self {
1886      #[cfg(feature = "u8")]
1887      Value::U8(v) => Ok(Ref::new(F64::new(*v.borrow() as f64))),
1888      #[cfg(feature = "u16")]
1889      Value::U16(v) => Ok(Ref::new(F64::new(*v.borrow() as f64))),
1890      #[cfg(feature = "u32")]
1891      Value::U32(v) => Ok(Ref::new(F64::new(*v.borrow() as f64))),
1892      #[cfg(feature = "u64")]
1893      Value::U64(v) => Ok(Ref::new(F64::new(*v.borrow() as f64))),
1894      #[cfg(feature = "u128")]
1895      Value::U128(v) => Ok(Ref::new(F64::new(*v.borrow() as f64))),
1896      #[cfg(feature = "i8")]
1897      Value::I8(v) => Ok(Ref::new(F64::new(*v.borrow() as f64))),
1898      #[cfg(feature = "i16")]
1899      Value::I16(v) => Ok(Ref::new(F64::new(*v.borrow() as f64))),
1900      #[cfg(feature = "i32")]
1901      Value::I32(v) => Ok(Ref::new(F64::new(*v.borrow() as f64))),
1902      #[cfg(feature = "i64")]
1903      Value::I64(v) => Ok(Ref::new(F64::new(*v.borrow() as f64))),
1904      #[cfg(feature = "i128")]
1905      Value::I128(v) => Ok(Ref::new(F64::new(*v.borrow() as f64))),
1906      Value::F64(v) => Ok(v.clone()),
1907      Value::MutableReference(val) => val.borrow().as_f64(),
1908      _ => Err(MechError {
1909        file: file!().to_string(),
1910        tokens: vec![],
1911        msg: "Value cannot be converted to F64".to_string(),
1912        id: line!(),
1913        kind: MechErrorKind::UnhandledFunctionArgumentKind,
1914      }),
1915    }
1916  }
1917
1918  #[cfg(all(feature = "matrix", feature = "bool"))] pub fn as_vecbool(&self) -> MResult<Vec<bool>> { if let Value::MatrixBool(v) = self { Ok(v.as_vec()) } else if let Value::Bool(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecbool() } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<bool>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1919  #[cfg(all(feature = "matrix", feature = "f64"))] pub fn as_vecf64(&self) -> MResult<Vec<F64>> { if let Value::MatrixF64(v) = self { Ok(v.as_vec()) } else if let Value::F64(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecf64() } else if let Ok(v) = self.as_f64() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<F64>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1920  #[cfg(all(feature = "matrix", feature = "f32"))] pub fn as_vecf32(&self) -> MResult<Vec<F32>> { if let Value::MatrixF32(v) = self { Ok(v.as_vec()) } else if let Value::F32(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecf32() } else if let Ok(v) = self.as_f32() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<F32>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1921  #[cfg(all(feature = "matrix", feature = "u8"))] pub fn as_vecu8(&self) -> MResult<Vec<u8>> { if let Value::MatrixU8(v) = self { Ok(v.as_vec()) } else if let Value::U8(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu8() } else if let Ok(v) = self.as_u8() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<u8>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1922  #[cfg(all(feature = "matrix", feature = "u16"))] pub fn as_vecu16(&self) -> MResult<Vec<u16>> { if let Value::MatrixU16(v) = self { Ok(v.as_vec()) } else if let Value::U16(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu16() } else if let Ok(v) = self.as_u16() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<u16>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1923  #[cfg(all(feature = "matrix", feature = "u32"))] pub fn as_vecu32(&self) -> MResult<Vec<u32>> { if let Value::MatrixU32(v) = self { Ok(v.as_vec()) } else if let Value::U32(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu32() } else if let Ok(v) = self.as_u32() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<u32>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1924  #[cfg(all(feature = "matrix", feature = "u64"))] pub fn as_vecu64(&self) -> MResult<Vec<u64>> { if let Value::MatrixU64(v) = self { Ok(v.as_vec()) } else if let Value::U64(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu64() } else if let Ok(v) = self.as_u64() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<u64>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1925  #[cfg(all(feature = "matrix", feature = "u128"))] pub fn as_vecu128(&self) -> MResult<Vec<u128>> { if let Value::MatrixU128(v) = self { Ok(v.as_vec()) } else if let Value::U128(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu128() } else if let Ok(v) = self.as_u128() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<u128>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1926  #[cfg(all(feature = "matrix", feature = "i8"))] pub fn as_veci8(&self) -> MResult<Vec<i8>> { if let Value::MatrixI8(v) = self { Ok(v.as_vec()) } else if let Value::I8(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci8() } else if let Ok(v) = self.as_i8() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<i8>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1927  #[cfg(all(feature = "matrix", feature = "i16"))] pub fn as_veci16(&self) -> MResult<Vec<i16>> { if let Value::MatrixI16(v) = self { Ok(v.as_vec()) } else if let Value::I16(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci16() } else if let Ok(v) = self.as_i16() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<i16>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1928  #[cfg(all(feature = "matrix", feature = "i32"))] pub fn as_veci32(&self) -> MResult<Vec<i32>> { if let Value::MatrixI32(v) = self { Ok(v.as_vec()) } else if let Value::I32(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci32() } else if let Ok(v) = self.as_i32() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<i32>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1929  #[cfg(all(feature = "matrix", feature = "i64"))] pub fn as_veci64(&self) -> MResult<Vec<i64>> { if let Value::MatrixI64(v) = self { Ok(v.as_vec()) } else if let Value::I64(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci64() } else if let Ok(v) = self.as_i64() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<i64>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1930  #[cfg(all(feature = "matrix", feature = "i128"))] pub fn as_veci128(&self) -> MResult<Vec<i128>> { if let Value::MatrixI128(v) = self { Ok(v.as_vec()) } else if let Value::I128(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci128() } else if let Ok(v) = self.as_i128() { Ok(vec![v.borrow().clone()]) } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<i128>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1931  #[cfg(all(feature = "matrix", feature = "string"))] pub fn as_vecstring(&self) -> MResult<Vec<String>> { if let Value::MatrixString(v) = self { Ok(v.as_vec()) } else if let Value::String(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecstring() } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<String>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1932  #[cfg(all(feature = "matrix", feature = "r64"))] pub fn as_vecr64(&self) -> MResult<Vec<R64>> { if let Value::MatrixR64(v) = self { Ok(v.as_vec()) } else if let Value::R64(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecr64() } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<R64>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1933  #[cfg(all(feature = "matrix", feature = "c64"))] pub fn as_vecc64(&self) -> MResult<Vec<C64>> { if let Value::MatrixC64(v) = self { Ok(v.as_vec()) } else if let Value::C64(v) = self { Ok(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecc64() } else { Err(MechError { file: file!().to_string(), tokens: vec![], msg: "Cannot convert to Vec<C64>".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }) } }
1934
1935  pub fn as_vecusize(&self) -> MResult<Vec<usize>> {
1936    match self {
1937      #[cfg(feature = "u8")]
1938      Value::U8(v) => Ok(vec![*v.borrow() as usize]),
1939      #[cfg(feature = "u16")]
1940      Value::U16(v) => Ok(vec![*v.borrow() as usize]),
1941      #[cfg(feature = "u32")]
1942      Value::U32(v) => Ok(vec![*v.borrow() as usize]),
1943      #[cfg(feature = "u64")]
1944      Value::U64(v) => Ok(vec![*v.borrow() as usize]),
1945      #[cfg(feature = "u128")]
1946      Value::U128(v) => Ok(vec![*v.borrow() as usize]),
1947      #[cfg(feature = "i8")]
1948      Value::I8(v) => Ok(vec![*v.borrow() as usize]),
1949      #[cfg(feature = "i16")]
1950      Value::I16(v) => Ok(vec![*v.borrow() as usize]),
1951      #[cfg(feature = "i32")]
1952      Value::I32(v) => Ok(vec![*v.borrow() as usize]),
1953      #[cfg(feature = "i64")]
1954      Value::I64(v) => Ok(vec![*v.borrow() as usize]),
1955      #[cfg(feature = "i128")]
1956      Value::I128(v) => Ok(vec![*v.borrow() as usize]),
1957      #[cfg(feature = "f32")]
1958      Value::F32(v) => Ok(vec![(*v.borrow()).0 as usize]),
1959      #[cfg(feature = "f64")]
1960      Value::F64(v) => Ok(vec![(*v.borrow()).0 as usize]),
1961      #[cfg(feature = "matrix")]
1962      Value::MatrixIndex(v) => Ok(v.as_vec()),
1963      #[cfg(all(feature = "matrix", feature = "f64"))]
1964      Value::MatrixF64(v) => Ok(v.as_vec().iter().map(|x| (*x).0 as usize).collect::<Vec<usize>>()),
1965      #[cfg(all(feature = "matrix", feature = "f32"))]
1966      Value::MatrixF32(v) => Ok(v.as_vec().iter().map(|x| (*x).0 as usize).collect::<Vec<usize>>()),
1967      #[cfg(all(feature = "matrix", feature = "u8"))]
1968      Value::MatrixU8(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1969      #[cfg(all(feature = "matrix", feature = "u16"))]  
1970      Value::MatrixU16(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1971      #[cfg(all(feature = "matrix", feature = "u32"))]
1972      Value::MatrixU32(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1973      #[cfg(all(feature = "matrix", feature = "u64"))]
1974      Value::MatrixU64(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1975      #[cfg(all(feature = "matrix", feature = "u128"))]
1976      Value::MatrixU128(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1977      #[cfg(all(feature = "matrix", feature = "i8"))]
1978      Value::MatrixI8(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1979      #[cfg(all(feature = "matrix", feature = "i16"))]
1980      Value::MatrixI16(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1981      #[cfg(all(feature = "matrix", feature = "i32"))]
1982      Value::MatrixI32(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1983      #[cfg(all(feature = "matrix", feature = "i128"))]
1984      Value::MatrixI128(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1985      #[cfg(all(feature = "matrix", feature = "i64"))]
1986      Value::MatrixI64(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1987      #[cfg(all(feature = "matrix", feature = "bool"))]
1988      Value::MatrixBool(_) => Err(MechError {
1989        file: file!().to_string(),
1990        tokens: vec![],
1991        msg: "Cannot convert MatrixBool to Vec<usize>".to_string(),
1992        id: line!(),
1993        kind: MechErrorKind::UnhandledFunctionArgumentKind,
1994      }),
1995      #[cfg(any(feature = "bool", feature = "variable_define"))]
1996      Value::Bool(_) => Err(MechError {
1997        file: file!().to_string(),
1998        tokens: vec![],
1999        msg: "Cannot convert Bool to Vec<usize>".to_string(),
2000        id: line!(),
2001        kind: MechErrorKind::UnhandledFunctionArgumentKind,
2002      }),
2003      Value::MutableReference(x) => x.borrow().as_vecusize(),
2004      _ => Err(MechError {
2005        file: file!().to_string(),
2006        tokens: vec![],
2007        msg: "Unhandled case for as_vecusize".to_string(),
2008        id: line!(),
2009        kind: MechErrorKind::UnhandledFunctionArgumentKind,
2010      }),
2011    }
2012  }
2013
2014  pub fn as_index(&self) -> MResult<Value> {
2015    match self.as_usize() {      
2016      Ok(ix) => Ok(Value::Index(Ref::new(ix))),
2017      #[cfg(feature = "matrix")]
2018      Err(_) => match self.as_vecusize() {
2019        #[cfg(feature = "matrix")]
2020        Ok(x) => {
2021          let shape = self.shape();
2022          let out = Value::MatrixIndex(usize::to_matrix(x, shape[0] * shape[1],1 ));
2023          Ok(out)
2024        },
2025        #[cfg(all(feature = "matrix", feature = "bool"))]
2026        Err(_) => match self.as_vecbool() {
2027          Ok(x) => {
2028            let shape = self.shape();
2029            let out = match (shape[0], shape[1]) {
2030              (1,1) => Value::Bool(Ref::new(x[0])),
2031              #[cfg(all(feature = "vectord", feature = "bool"))]
2032              (1,n) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
2033              #[cfg(all(feature = "vectord", feature = "bool"))]
2034              (m,1) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
2035              #[cfg(all(feature = "vectord", feature = "bool"))]
2036              (m,n) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
2037              _ => todo!(),
2038            };
2039            Ok(out)
2040          }
2041          Err(_) => match self.as_bool() {
2042            Ok(x) => Ok(Value::Bool(x)),
2043            Err(_) => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledIndexKind}),
2044          }
2045        }
2046        x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::None}),
2047      }
2048      _ => todo!(),
2049    }
2050  }
2051
2052  pub fn as_usize(&self) -> MResult<usize> {
2053    match self {      
2054      Value::Index(v) => Ok(*v.borrow()),
2055      #[cfg(feature = "u8")]
2056      Value::U8(v) => Ok(*v.borrow() as usize),
2057      #[cfg(feature = "u16")]
2058      Value::U16(v) => Ok(*v.borrow() as usize),
2059      #[cfg(feature = "u32")]
2060      Value::U32(v) => Ok(*v.borrow() as usize),
2061      #[cfg(feature = "u64")]
2062      Value::U64(v) => Ok(*v.borrow() as usize),
2063      #[cfg(feature = "u128")]
2064      Value::U128(v) => Ok(*v.borrow() as usize),
2065      #[cfg(feature = "i8")]
2066      Value::I8(v) => Ok(*v.borrow() as usize),
2067      #[cfg(feature = "i16")]
2068      Value::I16(v) => Ok(*v.borrow() as usize),
2069      #[cfg(feature = "i32")]
2070      Value::I32(v) => Ok(*v.borrow() as usize),
2071      #[cfg(feature = "i64")]
2072      Value::I64(v) => Ok(*v.borrow() as usize),
2073      #[cfg(feature = "i128")]
2074      Value::I128(v) => Ok(*v.borrow() as usize),
2075      #[cfg(feature = "f32")]
2076      Value::F32(v) => Ok((*v.borrow()).0 as usize),
2077      #[cfg(feature = "f64")]
2078      Value::F64(v) => Ok((*v.borrow()).0 as usize),
2079      Value::MutableReference(v) => v.borrow().as_usize(),
2080      _ => Err(MechError {
2081        file: file!().to_string(),
2082        tokens: vec![],
2083        msg: "Value cannot be converted to usize".to_string(),
2084        id: line!(),
2085        kind: MechErrorKind::UnhandledFunctionArgumentKind,
2086      }),
2087    }
2088  }
2089
2090  #[cfg(feature = "u8")]
2091  pub fn expect_u8(&self) -> MResult<Ref<u8>> {
2092    match self {
2093      Value::U8(v) => Ok(v.clone()),
2094      Value::MutableReference(v) => v.borrow().expect_u8(),
2095      _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::None}),
2096    }
2097  }
2098
2099  #[cfg(feature = "f64")]
2100  pub fn expect_f64(&self) -> MResult<Ref<F64>> {
2101    match self {
2102      Value::F64(v) => Ok(v.clone()),
2103      Value::MutableReference(v) => v.borrow().expect_f64(),
2104      _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::None}),
2105    }
2106  }
2107
2108}
2109
2110#[cfg(feature = "pretty_print")]
2111impl PrettyPrint for Value {
2112  fn pretty_print(&self) -> String {
2113    let mut builder = Builder::default();
2114    match self {
2115      #[cfg(feature = "u8")]
2116      Value::U8(x)   => {builder.push_record(vec![format!("{}",x.borrow())]);},
2117      #[cfg(feature = "u16")]
2118      Value::U16(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2119      #[cfg(feature = "u32")]
2120      Value::U32(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2121      #[cfg(feature = "u64")]
2122      Value::U64(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2123      #[cfg(feature = "u128")]
2124      Value::U128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2125      #[cfg(feature = "i8")]
2126      Value::I8(x)   => {builder.push_record(vec![format!("{}",x.borrow())]);},
2127      #[cfg(feature = "i16")]
2128      Value::I16(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2129      #[cfg(feature = "i32")]
2130      Value::I32(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2131      #[cfg(feature = "i64")]
2132      Value::I64(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2133      #[cfg(feature = "i128")]
2134      Value::I128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2135      #[cfg(feature = "f32")]
2136      Value::F32(x)  => {builder.push_record(vec![format!("{}",x.borrow().0)]);},
2137      #[cfg(feature = "f64")]
2138      Value::F64(x)  => {builder.push_record(vec![format!("{}",x.borrow().0)]);},
2139      #[cfg(any(feature = "bool", feature = "variable_define"))]
2140      Value::Bool(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2141      #[cfg(feature = "complex")]
2142      Value::C64(x) => {builder.push_record(vec![x.borrow().pretty_print()]);},
2143      #[cfg(feature = "rational")]
2144      Value::R64(x) => {builder.push_record(vec![format!("{}",x.borrow().pretty_print())]);},
2145      #[cfg(feature = "atom")]
2146      Value::Atom(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2147      #[cfg(feature = "set")]
2148      Value::Set(x)  => {return x.borrow().pretty_print();}
2149      #[cfg(feature = "map")]
2150      Value::Map(x)  => {return x.borrow().pretty_print();}
2151      #[cfg(any(feature = "string", feature = "variable_define"))]
2152      Value::String(x) => {return format!("\"{}\"",x.borrow().clone());},
2153      #[cfg(feature = "table")]
2154      Value::Table(x)  => {return x.borrow().pretty_print();},
2155      #[cfg(feature = "tuple")]
2156      Value::Tuple(x)  => {return x.borrow().pretty_print();},
2157      #[cfg(feature = "record")]
2158      Value::Record(x) => {return x.borrow().pretty_print();},
2159      #[cfg(feature = "enum")]
2160      Value::Enum(x) => {return x.borrow().pretty_print();},
2161      #[cfg(feature = "matrix")]
2162      Value::MatrixIndex(x) => {return x.pretty_print();},
2163      #[cfg(all(feature = "matrix", feature = "bool"))]
2164      Value::MatrixBool(x) => {return x.pretty_print();},
2165      #[cfg(all(feature = "matrix", feature = "u8"))]
2166      Value::MatrixU8(x)   => {return x.pretty_print();},
2167      #[cfg(all(feature = "matrix", feature = "u16"))]
2168      Value::MatrixU16(x)  => {return x.pretty_print();},
2169      #[cfg(all(feature = "matrix", feature = "u32"))]
2170      Value::MatrixU32(x)  => {return x.pretty_print();},
2171      #[cfg(all(feature = "matrix", feature = "u64"))]
2172      Value::MatrixU64(x)  => {return x.pretty_print();},
2173      #[cfg(all(feature = "matrix", feature = "u128"))]
2174      Value::MatrixU128(x) => {return x.pretty_print();},
2175      #[cfg(all(feature = "matrix", feature = "i8"))]
2176      Value::MatrixI8(x)   => {return x.pretty_print();},
2177      #[cfg(all(feature = "matrix", feature = "i16"))]
2178      Value::MatrixI16(x)  => {return x.pretty_print();},
2179      #[cfg(all(feature = "matrix", feature = "i32"))]
2180      Value::MatrixI32(x)  => {return x.pretty_print();},
2181      #[cfg(all(feature = "matrix", feature = "i64"))]
2182      Value::MatrixI64(x)  => {return x.pretty_print();},
2183      #[cfg(all(feature = "matrix", feature = "i128"))]
2184      Value::MatrixI128(x) => {return x.pretty_print();},
2185      #[cfg(all(feature = "matrix", feature = "f32"))]
2186      Value::MatrixF32(x)  => {return x.pretty_print();},
2187      #[cfg(all(feature = "matrix", feature = "f64"))]
2188      Value::MatrixF64(x)  => {return x.pretty_print();},
2189      #[cfg(all(feature = "matrix", feature = "any"))]
2190      Value::MatrixValue(x)  => {return x.pretty_print();},
2191      #[cfg(all(feature = "matrix", feature = "string"))]
2192      Value::MatrixString(x)  => {return x.pretty_print();},
2193      #[cfg(all(feature = "matrix", feature = "rational"))]
2194      Value::MatrixR64(x) => {return x.pretty_print();},
2195      #[cfg(all(feature = "matrix", feature = "complex"))]
2196      Value::MatrixC64(x) => {return x.pretty_print();},
2197      Value::Index(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2198      Value::MutableReference(x) => {return x.borrow().pretty_print();},
2199      Value::Empty => builder.push_record(vec!["_"]),
2200      Value::IndexAll => builder.push_record(vec![":"]),
2201      Value::Id(x) => builder.push_record(vec![format!("{}",humanize(x))]),
2202      Value::Kind(x) => builder.push_record(vec![format!("{}",x)]),
2203      x => {
2204        todo!("{x:#?}");
2205      },
2206    };
2207    let value_style = Style::empty()
2208      .top(' ')
2209      .left(' ')
2210      .right(' ')
2211      .bottom(' ')
2212      .vertical(' ')
2213      .intersection_bottom(' ')
2214      .corner_top_left(' ')
2215      .corner_top_right(' ')
2216      .corner_bottom_left(' ')
2217      .corner_bottom_right(' ');
2218    let mut table = builder.build();
2219    table.with(value_style);
2220    format!("{table}")
2221  }
2222}
2223
2224
2225pub trait ToIndex {
2226  fn to_index(&self) -> Value;
2227}
2228
2229#[cfg(feature = "matrix")]
2230impl ToIndex for Ref<Vec<i64>> { fn to_index(&self) -> Value { (*self.borrow()).iter().map(|x| *x as usize).collect::<Vec<usize>>().to_value() } }
2231
2232pub trait ToValue {
2233  fn to_value(&self) -> Value;
2234}
2235
2236#[cfg(feature = "matrix")]
2237impl ToValue for Vec<usize> {
2238  fn to_value(&self) -> Value {
2239    match self.len() {
2240      1 => Value::Index(Ref::new(self[0].clone())),
2241      #[cfg(feature = "vector2")]
2242      2 => Value::MatrixIndex(Matrix::Vector2(Ref::new(Vector2::from_vec(self.clone())))),
2243      #[cfg(feature = "vector3")]
2244      3 => Value::MatrixIndex(Matrix::Vector3(Ref::new(Vector3::from_vec(self.clone())))),
2245      #[cfg(feature = "vector4")]
2246      4 => Value::MatrixIndex(Matrix::Vector4(Ref::new(Vector4::from_vec(self.clone())))),
2247      #[cfg(feature = "vectord")]
2248      n => Value::MatrixIndex(Matrix::DVector(Ref::new(DVector::from_vec(self.clone())))),
2249      _ => todo!(),
2250    }
2251  }
2252}
2253
2254impl ToValue for Ref<usize>  { fn to_value(&self) -> Value { Value::Index(self.clone())  } }
2255#[cfg(feature = "u8")]
2256impl ToValue for Ref<u8>     { fn to_value(&self) -> Value { Value::U8(self.clone())     } }
2257#[cfg(feature = "u16")]
2258impl ToValue for Ref<u16>    { fn to_value(&self) -> Value { Value::U16(self.clone())    } }
2259#[cfg(feature = "u32")]
2260impl ToValue for Ref<u32>    { fn to_value(&self) -> Value { Value::U32(self.clone())    } }
2261#[cfg(feature = "u64")]
2262impl ToValue for Ref<u64>    { fn to_value(&self) -> Value { Value::U64(self.clone())    } }
2263#[cfg(feature = "u128")]
2264impl ToValue for Ref<u128>   { fn to_value(&self) -> Value { Value::U128(self.clone())   } }
2265#[cfg(feature = "i8")]
2266impl ToValue for Ref<i8>     { fn to_value(&self) -> Value { Value::I8(self.clone())     } }
2267#[cfg(feature = "i16")]
2268impl ToValue for Ref<i16>    { fn to_value(&self) -> Value { Value::I16(self.clone())    } }
2269#[cfg(feature = "i32")]
2270impl ToValue for Ref<i32>    { fn to_value(&self) -> Value { Value::I32(self.clone())    } }
2271#[cfg(feature = "i64")]
2272impl ToValue for Ref<i64>    { fn to_value(&self) -> Value { Value::I64(self.clone())    } }
2273#[cfg(feature = "i128")]
2274impl ToValue for Ref<i128>   { fn to_value(&self) -> Value { Value::I128(self.clone())   } }
2275#[cfg(feature = "f32")]
2276impl ToValue for Ref<F32>    { fn to_value(&self) -> Value { Value::F32(self.clone())    } }
2277#[cfg(feature = "f64")]
2278impl ToValue for Ref<F64>    { fn to_value(&self) -> Value { Value::F64(self.clone())    } }
2279#[cfg(any(feature = "bool", feature = "variable_define"))]
2280impl ToValue for Ref<bool>   { fn to_value(&self) -> Value { Value::Bool(self.clone())   } }
2281#[cfg(any(feature = "string", feature = "variable_define"))]
2282impl ToValue for Ref<String> { fn to_value(&self) -> Value { Value::String(self.clone()) } }
2283#[cfg(feature = "rational")]
2284impl ToValue for Ref<R64> { fn to_value(&self) -> Value { Value::R64(self.clone()) } }
2285#[cfg(feature = "complex")]
2286impl ToValue for Ref<C64> { fn to_value(&self) -> Value { Value::C64(self.clone()) } }
2287
2288impl ToValue for Ref<Value> { fn to_value(&self) -> Value { (*self.borrow()).clone() } }
2289
2290#[cfg(feature = "u8")]
2291impl From<u8> for Value {
2292  fn from(val: u8) -> Self {
2293    Value::U8(Ref::new(val))
2294  }
2295}
2296
2297#[cfg(feature = "u16")]
2298impl From<u16> for Value {
2299  fn from(val: u16) -> Self {
2300    Value::U16(Ref::new(val))
2301  }
2302}
2303
2304#[cfg(feature = "u32")]
2305impl From<u32> for Value {
2306  fn from(val: u32) -> Self {
2307    Value::U32(Ref::new(val))
2308  }
2309}
2310
2311#[cfg(feature = "u64")]
2312impl From<u64> for Value {
2313  fn from(val: u64) -> Self {
2314    Value::U64(Ref::new(val))
2315  }
2316}
2317
2318#[cfg(feature = "u128")]
2319impl From<u128> for Value {
2320  fn from(val: u128) -> Self {
2321    Value::U128(Ref::new(val))
2322  }
2323}
2324
2325#[cfg(feature = "i8")]
2326impl From<i8> for Value {
2327  fn from(val: i8) -> Self {
2328    Value::I8(Ref::new(val))
2329  }
2330}
2331
2332#[cfg(feature = "i16")]
2333impl From<i16> for Value {
2334  fn from(val: i16) -> Self {
2335    Value::I16(Ref::new(val))
2336  }
2337}
2338
2339#[cfg(feature = "i32")]
2340impl From<i32> for Value {
2341  fn from(val: i32) -> Self {
2342    Value::I32(Ref::new(val))
2343  }
2344}
2345
2346#[cfg(feature = "i64")]
2347impl From<i64> for Value {
2348  fn from(val: i64) -> Self {
2349    Value::I64(Ref::new(val))
2350  }
2351}
2352
2353#[cfg(feature = "i128")]
2354impl From<i128> for Value {
2355  fn from(val: i128) -> Self {
2356    Value::I128(Ref::new(val))
2357  }
2358}
2359
2360#[cfg(any(feature = "bool", feature = "variable_define"))]
2361impl From<bool> for Value {
2362  fn from(val: bool) -> Self {
2363    Value::Bool(Ref::new(val))
2364  }
2365}
2366
2367#[cfg(any(feature = "string", feature = "variable_define"))]
2368impl From<String> for Value {
2369  fn from(val: String) -> Self {
2370    Value::String(Ref::new(val))
2371  }
2372}
2373
2374#[cfg(feature = "rational")]
2375impl From<R64> for Value {
2376  fn from(val: R64) -> Self {
2377    Value::R64(Ref::new(val))
2378  }
2379}
2380
2381
2382pub trait ToUsize {
2383  fn to_usize(&self) -> usize;
2384}
2385
2386macro_rules! impl_to_usize_for {
2387  ($t:ty) => {
2388    impl ToUsize for $t {
2389      fn to_usize(&self) -> usize {
2390        #[allow(unused_comparisons)]
2391        if *self < 0 as $t {
2392          panic!("Cannot convert negative number to usize");
2393        }
2394        *self as usize
2395      }
2396    }
2397  };
2398}
2399
2400#[cfg(feature = "u8")]
2401impl_to_usize_for!(u8);
2402#[cfg(feature = "u16")]
2403impl_to_usize_for!(u16);
2404#[cfg(feature = "u32")]
2405impl_to_usize_for!(u32);
2406#[cfg(feature = "u64")]
2407impl_to_usize_for!(u64);
2408#[cfg(feature = "u128")]
2409impl_to_usize_for!(u128);
2410impl_to_usize_for!(usize);
2411
2412#[cfg(feature = "i8")]
2413impl_to_usize_for!(i8);
2414#[cfg(feature = "i16")]
2415impl_to_usize_for!(i16);
2416#[cfg(feature = "i32")]
2417impl_to_usize_for!(i32);
2418#[cfg(feature = "i64")]
2419impl_to_usize_for!(i64);
2420#[cfg(feature = "i128")]
2421impl_to_usize_for!(i128);
2422
2423#[cfg(feature = "table")]
2424impl ToValue for Ref<MechTable> {
2425  fn to_value(&self) -> Value {
2426    Value::Table(self.clone())
2427  }
2428}
2429
2430#[cfg(feature = "set")]
2431impl ToValue for Ref<MechSet> {
2432  fn to_value(&self) -> Value {
2433    Value::Set(self.clone())
2434  }
2435}
2436
2437#[cfg(feature = "map")]
2438impl ToValue for Ref<MechMap> {
2439  fn to_value(&self) -> Value {
2440    Value::Map(self.clone())
2441  }
2442}
2443
2444#[cfg(feature = "tuple")]
2445impl ToValue for Ref<MechTuple> {
2446  fn to_value(&self) -> Value {
2447    Value::Tuple(self.clone())
2448  }
2449}
2450
2451#[cfg(feature = "record")]
2452impl ToValue for Ref<MechRecord> {
2453  fn to_value(&self) -> Value {
2454    Value::Record(self.clone())
2455  }
2456}