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()) as $target_type)),
45          #[cfg(feature = "f64")]
46          Value::F64(v) => Ok(Ref::new((*v.borrow()) 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(
50            MechError2::new(
51              CannotConvertToTypeError { target_type: stringify!($target_type) },
52              None
53            ).with_compiler_loc()
54          ),
55        }
56      }
57    }
58  };
59}
60
61// Value Kind
62// ----------------------------------------------------------------------------
63
64#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
65#[derive(Clone, Debug, Eq, PartialEq, Hash)]
66pub enum ValueKind {
67  U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, C64, R64,
68  String, Bool, Id, Index, Empty, Any, None,
69  Matrix(Box<ValueKind>,Vec<usize>),  Enum(u64,String),             Record(Vec<(String,ValueKind)>),
70  Map(Box<ValueKind>,Box<ValueKind>), Atom(u64,String),             Table(Vec<(String,ValueKind)>, usize), 
71  Tuple(Vec<ValueKind>),              Reference(Box<ValueKind>),    Set(Box<ValueKind>, Option<usize>), 
72  Option(Box<ValueKind>),             Kind(Box<ValueKind>),    
73}
74
75impl Display for ValueKind {
76  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
77    match self {
78      ValueKind::R64 => write!(f, "r64"),
79      ValueKind::C64 => write!(f, "c64"),
80      ValueKind::U8 => write!(f, "u8"),
81      ValueKind::U16 => write!(f, "u16"),
82      ValueKind::U32 => write!(f, "u32"),
83      ValueKind::U64 => write!(f, "u64"),
84      ValueKind::U128 => write!(f, "u128"),
85      ValueKind::I8 => write!(f, "i8"),
86      ValueKind::I16 => write!(f, "i16"),
87      ValueKind::I32 => write!(f, "i32"),
88      ValueKind::I64 => write!(f, "i64"),
89      ValueKind::I128 => write!(f, "i128"),
90      ValueKind::F32 => write!(f, "f32"),
91      ValueKind::F64 => write!(f, "f64"),
92      ValueKind::String => write!(f, "string"),
93      ValueKind::Bool => write!(f, "bool"),
94      ValueKind::Matrix(x,s) => write!(f, "[{}]:{}", x, s.iter().map(|s| s.to_string()).collect::<Vec<String>>().join(",")),
95      ValueKind::Set(x,el) => write!(f, "{{{}}}{}", x, el.map_or("".to_string(), |e| format!(":{}", e))),
96      ValueKind::Map(x,y) => write!(f, "{{{}:{}}}",x,y),
97      ValueKind::Record(x) => write!(f, "{{{}}}",x.iter().map(|(i,k)| format!("{}<{}>",i.to_string(),k)).collect::<Vec<String>>().join(" ")),
98      ValueKind::Table(x,y) => {
99        let size_str = if y > &0 { format!(":{}", y) } else { "".to_string() };
100        write!(f, "|{}|{}",x.iter().map(|(i,k)| format!("{}<{}>",i.to_string(),k)).collect::<Vec<String>>().join(" "),size_str)
101      }
102      ValueKind::Tuple(x) => write!(f, "({})",x.iter().map(|x| format!("{}",x)).collect::<Vec<String>>().join(",")),
103      ValueKind::Id => write!(f, "id"),
104      ValueKind::Index => write!(f, "ix"),
105      ValueKind::Reference(x) => write!(f, "{}",x),
106      ValueKind::Enum(x, name) => write!(f, ":{}", name),
107      ValueKind::Atom(x, name) => write!(f, ":{}", name),
108      ValueKind::Empty => write!(f, "_"),
109      ValueKind::Any => write!(f, "*"),
110      ValueKind::None => write!(f, "none"),
111      ValueKind::Option(x) => write!(f, "{}?", x),
112      ValueKind::Kind(x) => write!(f, "<{}>", x),
113    }
114  }
115}
116
117impl ValueKind {
118
119  #[cfg(feature = "compiler")]
120  pub fn to_feature_kind(&self) -> FeatureKind {
121    match self {
122      #[cfg(feature = "i8")]
123      ValueKind::I8 => FeatureKind::I8,
124      #[cfg(feature = "i16")]
125      ValueKind::I16 => FeatureKind::I16,
126      #[cfg(feature = "i32")]
127      ValueKind::I32 => FeatureKind::I32,
128      #[cfg(feature = "i64")]
129      ValueKind::I64 => FeatureKind::I64,
130      #[cfg(feature = "i128")]
131      ValueKind::I128 => FeatureKind::I128,
132      #[cfg(feature = "u8")] 
133      ValueKind::U8 => FeatureKind::U8,
134      #[cfg(feature = "u16")]
135      ValueKind::U16 => FeatureKind::U16,
136      #[cfg(feature = "u32")]
137      ValueKind::U32 => FeatureKind::U32,
138      #[cfg(feature = "u64")]
139      ValueKind::U64 => FeatureKind::U64,
140      #[cfg(feature = "u128")]
141      ValueKind::U128 => FeatureKind::U128,
142      #[cfg(feature = "f32")]
143      ValueKind::F32 => FeatureKind::F32, 
144      #[cfg(feature = "f64")]
145      ValueKind::F64 => FeatureKind::F64,
146      #[cfg(any(feature = "string", feature = "variable_define"))]
147      ValueKind::String => FeatureKind::String,
148      #[cfg(any(feature = "bool", feature = "variable_define"))]
149      ValueKind::Bool => FeatureKind::Bool,
150      #[cfg(feature = "table")]
151      ValueKind::Table(_,_) => FeatureKind::Table,
152      #[cfg(feature = "set")]
153      ValueKind::Set(_,_) => FeatureKind::Set,
154      #[cfg(feature = "map")]
155      ValueKind::Map(_,_) => FeatureKind::Map,
156      #[cfg(feature = "record")]
157      ValueKind::Record(_) => FeatureKind::Record,
158      #[cfg(feature = "tuple")] 
159      ValueKind::Tuple(_) => FeatureKind::Tuple,
160      #[cfg(feature = "enum")]
161      ValueKind::Enum(..) => FeatureKind::Enum,
162      #[cfg(feature = "matrix")]
163      ValueKind::Matrix(_,shape) => {
164        match shape[..] {
165          #[cfg(feature = "matrix1")]
166          [1,1] => FeatureKind::Matrix1,
167          #[cfg(feature = "matrix2")]
168          [2,2] => FeatureKind::Matrix2,
169          #[cfg(feature = "matrix3")]
170          [3,3] => FeatureKind::Matrix3,
171          #[cfg(feature = "matrix4")]
172          [4,4] => FeatureKind::Matrix4,
173          #[cfg(feature = "matrix2x3")]
174          [2,3] => FeatureKind::Matrix2x3,
175          #[cfg(feature = "matrix3x2")]
176          [3,2] => FeatureKind::Matrix3x2,
177          #[cfg(feature = "row_vector2")]
178          [1,2] => FeatureKind::RowVector2,
179          #[cfg(feature = "row_vector3")]
180          [1,3] => FeatureKind::RowVector3,
181          #[cfg(feature = "row_vector4")]
182          [1,4] => FeatureKind::RowVector4,
183          #[cfg(feature = "vector2")]
184          [2,1] => FeatureKind::Vector2,
185          #[cfg(feature = "vector3")]
186          [3,1] => FeatureKind::Vector3,
187          #[cfg(feature = "vector4")]
188          [4,1] => FeatureKind::Vector4,
189          #[cfg(feature = "row_vectord")]
190          [1,n] => FeatureKind::RowVectorD,
191          #[cfg(feature = "vectord")]
192          [n,1] => FeatureKind::VectorD,
193          #[cfg(feature = "matrixd")]
194          [n,m] => FeatureKind::MatrixD,
195          _ => panic!("Unsupported matrix shape for feature kind: {}", self),
196        }
197      }
198      #[cfg(feature = "complex")]
199      ValueKind::C64 => FeatureKind::C64,
200      #[cfg(feature = "rational")]
201      ValueKind::R64 => FeatureKind::R64,
202      ValueKind::Atom(..) => FeatureKind::Atom,
203      ValueKind::Index => FeatureKind::Index,
204      _ => panic!("Unsupported feature kind for value kind: {}", self),
205    }
206  }
207
208  pub fn collection_kind(&self) -> Option<ValueKind> {
209    match self {
210      ValueKind::Matrix(x,_) => Some(*x.clone()),
211      ValueKind::Set(x,_) => Some(*x.clone()),
212      _ => None,
213    }
214  }
215
216  pub fn deref_kind(&self) -> ValueKind {
217    match self {
218      ValueKind::Reference(x) => *x.clone(),
219      _ => self.clone(),
220    }
221  }
222
223  pub fn is_convertible_to(&self, other: &ValueKind) -> bool {
224    use ValueKind::*;
225    match (self, other) {
226      // Unsigned widening
227      (U8, U16) | (U8, U32) | (U8, U64) | (U8, U128) |
228      (U16, U32) | (U16, U64) | (U16, U128) |
229      (U32, U64) | (U32, U128) |
230      (U64, U128) => true,
231
232      // Signed widening
233      (I8, I16) | (I8, I32) | (I8, I64) | (I8, I128) |
234      (I16, I32) | (I16, I64) | (I16, I128) |
235      (I32, I64) | (I32, I128) |
236      (I64, I128) => true,
237
238      // Unsigned -> signed widening
239      (U8, I16) | (U8, I32) | (U8, I64) | (U8, I128) |
240      (U16, I32) | (U16, I64) | (U16, I128) |
241      (U32, I64) | (U32, I128) |
242      (U64, I128) => true,
243
244      // Signed -> unsigned widening (runtime safety not enforced here)
245      (I8, U16) | (I8, U32) | (I8, U64) | (I8, U128) |
246      (I16, U32) | (I16, U64) | (I16, U128) |
247      (I32, U64) | (I32, U128) |
248      (I64, U128) => true,
249
250      // Integer -> float
251      (U8, F32) | (U8, F64) |
252      (U16, F32) | (U16, F64) |
253      (U32, F32) | (U32, F64) |
254      (U64, F32) | (U64, F64) |
255      (U128, F32) | (U128, F64) |
256      (I8, F32) | (I8, F64) |
257      (I16, F32) | (I16, F64) |
258      (I32, F32) | (I32, F64) |
259      (I64, F32) | (I64, F64) |
260      (I128, F32) | (I128, F64) => true,
261
262      // Float widening + narrowing
263      (F32, F64) | (F64, F32) => true,
264
265      // Float -> integer (allowed, but lossy)
266      (F32, I8) | (F32, I16) | (F32, I32) | (F32, I64) | (F32, I128) |
267      (F32, U8) | (F32, U16) | (F32, U32) | (F32, U64) | (F32, U128) |
268      (F64, I8) | (F64, I16) | (F64, I32) | (F64, I64) | (F64, I128) |
269      (F64, U8) | (F64, U16) | (F64, U32) | (F64, U64) | (F64, U128) => true,
270
271      // Index conversions (both ways)
272      (Index, U8) | (Index, U16) | (Index, U32) | (Index, U64) | (Index, U128) |
273      (Index, I8) | (Index, I16) | (Index, I32) | (Index, I64) | (Index, I128) |
274      (Index, F32) | (Index, F64) |
275      (U8, Index) | (U16, Index) | (U32, Index) | (U64, Index) | (U128, Index) |
276      (I8, Index) | (I16, Index) | (I32, Index) | (I64, Index) | (I128, Index) => true,
277
278      // Matrix: element type convertible and shape matches
279      (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,
280
281      // Option conversions
282      (Option(box a), Option(box b)) if a.is_convertible_to(b) => true,
283
284      // Reference conversions
285      (Reference(box a), Reference(box b)) if a.is_convertible_to(b) => true,
286
287      // Tuple conversions (element-wise)
288      (Tuple(a), Tuple(b)) if a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| x.is_convertible_to(y)) => true,
289
290      // Set conversions
291      (Set(box a, _), Set(box b, _)) if a.is_convertible_to(b) => true,
292
293      // Map conversions
294      (Map(box ak, box av), Map(box bk, box bv)) if ak.is_convertible_to(bk) && av.is_convertible_to(bv) => true,
295
296      // Table conversions: allow source to have extra columns
297      (Table(acols, _), Table(bcols, _)) if bcols.iter().all(|(bk, bv)| 
298        acols.iter().any(|(ak, av)| ak == bk && av.is_convertible_to(bv))
299      ) => true,
300
301      // Record conversions: allow source to have extra fields
302      (Record(afields), Record(bfields)) if bfields.iter().all(|(bk, bv)| 
303        afields.iter().any(|(ak, av)| ak == bk && av.is_convertible_to(bv))
304      ) => true,
305
306      // Direct match
307      _ => self == other,
308    }
309  }
310
311  pub fn is_compatible(k1: ValueKind, k2: ValueKind) -> bool {
312    match k1 {
313      ValueKind::Reference(x) => {
314        ValueKind::is_compatible(*x,k2)
315      }
316      ValueKind::Matrix(x,_) => {
317        *x == k2
318      }
319      x => x == k2,
320    }
321  }
322
323  pub fn align(&self) -> usize {
324    // pointer alignment (platform word size)
325    let ptr_align = mem::align_of::<usize>();
326
327    match self {
328      // unsigned integers
329      ValueKind::U8   => 1,
330      ValueKind::U16  => 2,
331      ValueKind::U32  => 4,
332      ValueKind::U64  => 8,
333      ValueKind::U128 => 16,
334      // signed integers
335      ValueKind::I8   => 1,
336      ValueKind::I16  => 2,
337      ValueKind::I32  => 4,
338      ValueKind::I64  => 8,
339      ValueKind::I128 => 16,
340      // floats
341      ValueKind::F32  => 4,
342      ValueKind::F64  => 8,
343      // complex / rational (assume composed of f64 parts)
344      ValueKind::C64 => 8,
345      ValueKind::R64 => 8,
346      // small simple payloads
347      ValueKind::Bool  => 1,
348      ValueKind::String => ptr_align, // String = (ptr, len, cap)
349      ValueKind::Id | ValueKind::Index => 8,
350      ValueKind::Empty => 1,
351      ValueKind::Any   => ptr_align,
352      ValueKind::None  => 1,
353      // compound types
354      ValueKind::Matrix(elem_ty, _) => {
355        // flat element storage
356        elem_ty.align()
357      }
358      // inline enum / atom payloads
359      ValueKind::Enum(_, _) => 8, // u64 + String => max(8, 8)
360      ValueKind::Atom(_, _) => 8,
361      ValueKind::Record(fields) => {
362        // record alignment = max field alignment
363        fields.iter()
364          .map(|(_, ty)| ty.align())
365          .max()
366          .unwrap_or(1)
367      }
368      // pointer-backed containers
369      ValueKind::Map(_, _)   => ptr_align,
370      ValueKind::Table(cols, _) => {
371        cols.iter()
372          .map(|(_, ty)| ty.align())
373          .max()
374          .unwrap_or(ptr_align)
375      }
376      ValueKind::Tuple(elems) => {
377        elems.iter()
378          .map(|ty| ty.align())
379          .max()
380          .unwrap_or(1)
381      }
382      ValueKind::Reference(_) => ptr_align,
383      ValueKind::Set(elem, _) => {
384        // if Set is implemented inline; otherwise use ptr_align
385        elem.align()
386      }
387      ValueKind::Option(inner) => inner.align(),
388      ValueKind::Kind(inner) => inner.align(),
389    }
390  }
391}
392
393pub trait AsNaKind {
394  fn as_na_kind() -> String;
395}
396
397macro_rules! impl_as_na_kind {
398  ($type:ty, $kind:expr) => {
399    impl<T> AsNaKind for $type {
400      fn as_na_kind() -> String { $kind.to_string() }
401    }
402  };
403}
404
405#[cfg(feature = "row_vector2")]
406impl_as_na_kind!(RowVector2<T>, "RowVector2");
407#[cfg(feature = "row_vector3")]
408impl_as_na_kind!(RowVector3<T>, "RowVector3");
409#[cfg(feature = "row_vector4")]
410impl_as_na_kind!(RowVector4<T>, "RowVector4");
411#[cfg(feature = "row_vectord")]
412impl_as_na_kind!(RowDVector<T>, "RowDVector");
413#[cfg(feature = "vector2")]
414impl_as_na_kind!(Vector2<T>, "Vector2");
415#[cfg(feature = "vector3")]
416impl_as_na_kind!(Vector3<T>, "Vector3");
417#[cfg(feature = "vector4")]
418impl_as_na_kind!(Vector4<T>, "Vector4");
419#[cfg(feature = "vectord")]
420impl_as_na_kind!(DVector<T>, "DVector");
421#[cfg(feature = "matrix1")]
422impl_as_na_kind!(Matrix1<T>, "Matrix1");
423#[cfg(feature = "matrix2")]
424impl_as_na_kind!(Matrix2<T>, "Matrix2");
425#[cfg(feature = "matrix3")]
426impl_as_na_kind!(Matrix3<T>, "Matrix3");
427#[cfg(feature = "matrix4")]
428impl_as_na_kind!(Matrix4<T>, "Matrix4");
429#[cfg(feature = "matrix2x3")]
430impl_as_na_kind!(Matrix2x3<T>, "Matrix2x3");
431#[cfg(feature = "matrix3x2")]
432impl_as_na_kind!(Matrix3x2<T>, "Matrix3x2");
433#[cfg(feature = "matrixd")]
434impl_as_na_kind!(DMatrix<T>, "DMatrix");
435
436pub trait AsValueKind {
437  fn as_value_kind() -> ValueKind;
438}
439
440macro_rules! impl_as_value_kind {
441  ($type:ty, $value_kind:expr) => {
442    impl AsValueKind for $type {
443      fn as_value_kind() -> ValueKind { $value_kind }
444    }
445  };
446}
447
448impl_as_value_kind!(usize, ValueKind::Index);
449
450#[cfg(feature = "i8")]
451impl_as_value_kind!(i8, ValueKind::I8);
452#[cfg(feature = "i16")]
453impl_as_value_kind!(i16, ValueKind::I16);
454#[cfg(feature = "i32")]
455impl_as_value_kind!(i32, ValueKind::I32);
456#[cfg(feature = "i64")]
457impl_as_value_kind!(i64, ValueKind::I64);
458#[cfg(feature = "i128")]
459impl_as_value_kind!(i128, ValueKind::I128);
460#[cfg(feature = "u8")]
461impl_as_value_kind!(u8, ValueKind::U8);
462#[cfg(feature = "u16")]
463impl_as_value_kind!(u16, ValueKind::U16);
464#[cfg(feature = "u32")]
465impl_as_value_kind!(u32, ValueKind::U32);
466#[cfg(feature = "u64")]
467impl_as_value_kind!(u64, ValueKind::U64);
468#[cfg(feature = "u128")]
469impl_as_value_kind!(u128, ValueKind::U128);
470#[cfg(feature = "f32")]
471impl_as_value_kind!(f32, ValueKind::F32);
472#[cfg(feature = "f64")]
473impl_as_value_kind!(f64, ValueKind::F64);
474#[cfg(any(feature = "bool", feature = "variable_define"))]
475impl_as_value_kind!(bool, ValueKind::Bool);
476#[cfg(any(feature = "string", feature = "variable_define"))]
477impl_as_value_kind!(String, ValueKind::String);
478#[cfg(feature = "rational")]
479impl_as_value_kind!(R64, ValueKind::R64);
480#[cfg(feature = "complex")]
481impl_as_value_kind!(C64, ValueKind::C64);
482
483
484macro_rules! impl_as_value_kind_for_matrix {
485  ($type:ty, $dims:expr) => {
486    impl<T: AsValueKind> AsValueKind for $type {
487      fn as_value_kind() -> ValueKind {
488        ValueKind::Matrix(Box::new(T::as_value_kind()), $dims)
489      }
490    }
491  };
492}
493
494#[cfg(feature = "row_vectord")]
495impl_as_value_kind_for_matrix!(RowDVector<T>, vec![1, 0]);
496#[cfg(feature = "row_vector2")]
497impl_as_value_kind_for_matrix!(RowVector2<T>, vec![1, 2]);
498#[cfg(feature = "row_vector3")]
499impl_as_value_kind_for_matrix!(RowVector3<T>, vec![1, 3]);
500#[cfg(feature = "row_vector4")]
501impl_as_value_kind_for_matrix!(RowVector4<T>, vec![1, 4]);
502#[cfg(feature = "vectord")]
503impl_as_value_kind_for_matrix!(DVector<T>, vec![0, 1]);
504#[cfg(feature = "vector2")]
505impl_as_value_kind_for_matrix!(Vector2<T>, vec![2, 1]);
506#[cfg(feature = "vector3")]
507impl_as_value_kind_for_matrix!(Vector3<T>, vec![3, 1]);
508#[cfg(feature = "vector4")]
509impl_as_value_kind_for_matrix!(Vector4<T>, vec![4, 1]);
510#[cfg(feature = "matrix1")]
511impl_as_value_kind_for_matrix!(Matrix1<T>, vec![1, 1]);
512#[cfg(feature = "matrix2")]
513impl_as_value_kind_for_matrix!(Matrix2<T>, vec![2, 2]);
514#[cfg(feature = "matrix3")]
515impl_as_value_kind_for_matrix!(Matrix3<T>, vec![3, 3]);
516#[cfg(feature = "matrix4")]
517impl_as_value_kind_for_matrix!(Matrix4<T>, vec![4, 4]);
518#[cfg(feature = "matrix2x3")]
519impl_as_value_kind_for_matrix!(Matrix2x3<T>, vec![2, 3]);
520#[cfg(feature = "matrix3x2")]
521impl_as_value_kind_for_matrix!(Matrix3x2<T>, vec![3, 2]);
522#[cfg(feature = "matrixd")]
523impl_as_value_kind_for_matrix!(DMatrix<T>, vec![0, 0]);
524
525impl AsValueKind for Value {
526  fn as_value_kind() -> ValueKind {
527    ValueKind::Any
528  }
529}
530
531
532// Value
533// ----------------------------------------------------------------------------
534
535#[derive(Clone, Debug, PartialEq)]
536pub enum Value {
537  #[cfg(feature = "u8")]
538  U8(Ref<u8>),
539  #[cfg(feature = "u16")]
540  U16(Ref<u16>),
541  #[cfg(feature = "u32")]
542  U32(Ref<u32>),
543  #[cfg(feature = "u64")]
544  U64(Ref<u64>),
545  #[cfg(feature = "u128")]
546  U128(Ref<u128>),
547  #[cfg(feature = "i8")]
548  I8(Ref<i8>),
549  #[cfg(feature = "i16")]
550  I16(Ref<i16>),
551  #[cfg(feature = "i32")]
552  I32(Ref<i32>),
553  #[cfg(feature = "i64")]
554  I64(Ref<i64>),
555  #[cfg(feature = "i128")]
556  I128(Ref<i128>),
557  #[cfg(feature = "f32")]
558  F32(Ref<f32>),
559  #[cfg(feature = "f64")]
560  F64(Ref<f64>),
561  #[cfg(any(feature = "string", feature = "variable_define"))]
562  String(Ref<String>),
563  #[cfg(any(feature = "bool", feature = "variable_define"))]
564  Bool(Ref<bool>),
565  #[cfg(feature = "atom")]
566  Atom(Ref<MechAtom>),
567  #[cfg(feature = "matrix")]
568  MatrixIndex(Matrix<usize>),
569  #[cfg(all(feature = "matrix", feature = "bool"))]
570  MatrixBool(Matrix<bool>),
571  #[cfg(all(feature = "matrix", feature = "u8"))]
572  MatrixU8(Matrix<u8>),
573  #[cfg(all(feature = "matrix", feature = "u16"))]
574  MatrixU16(Matrix<u16>),
575  #[cfg(all(feature = "matrix", feature = "u32"))]
576  MatrixU32(Matrix<u32>),
577  #[cfg(all(feature = "matrix", feature = "u64"))]
578  MatrixU64(Matrix<u64>),
579  #[cfg(all(feature = "matrix", feature = "u128"))]
580  MatrixU128(Matrix<u128>),
581  #[cfg(all(feature = "matrix", feature = "i8"))]
582  MatrixI8(Matrix<i8>),
583  #[cfg(all(feature = "matrix", feature = "i16"))]
584  MatrixI16(Matrix<i16>),
585  #[cfg(all(feature = "matrix", feature = "i32"))]
586  MatrixI32(Matrix<i32>),
587  #[cfg(all(feature = "matrix", feature = "i64"))]
588  MatrixI64(Matrix<i64>),
589  #[cfg(all(feature = "matrix", feature = "i128"))]
590  MatrixI128(Matrix<i128>),
591  #[cfg(all(feature = "matrix", feature = "f32"))]
592  MatrixF32(Matrix<f32>),
593  #[cfg(all(feature = "matrix", feature = "f64"))]
594  MatrixF64(Matrix<f64>),
595  #[cfg(all(feature = "matrix", feature = "string"))]
596  MatrixString(Matrix<String>),
597  #[cfg(all(feature = "matrix", feature = "rational"))]
598  MatrixR64(Matrix<R64>),
599  #[cfg(all(feature = "matrix", feature = "complex"))]
600  MatrixC64(Matrix<C64>),
601  #[cfg(feature = "matrix")]
602  MatrixValue(Matrix<Value>),
603  #[cfg(feature = "complex")]
604  C64(Ref<C64>),
605  #[cfg(feature = "rational")]
606  R64(Ref<R64>),
607  #[cfg(feature = "set")]
608  Set(Ref<MechSet>),
609  #[cfg(feature = "map")]
610  Map(Ref<MechMap>),
611  #[cfg(feature = "record")]
612  Record(Ref<MechRecord>),
613  #[cfg(feature = "table")]
614  Table(Ref<MechTable>),
615  #[cfg(feature = "tuple")]
616  Tuple(Ref<MechTuple>),
617  #[cfg(feature = "enum")]
618  Enum(Ref<MechEnum>),
619  Id(u64),
620  Index(Ref<usize>),
621  MutableReference(MutableReference),
622  Kind(ValueKind),
623  IndexAll,
624  Empty
625}
626
627impl Eq for Value {}
628
629impl fmt::Display for Value {
630  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
631    if cfg!(feature = "pretty_print") {
632      #[cfg(feature = "pretty_print")]
633      return fmt::Display::fmt(&self.pretty_print(), f);
634      fmt::Display::fmt(&"".to_string(), f) // kind of a hack to assuage the compiler
635    } else {
636      write!(f, "{:?}", self)
637    }
638  }
639}
640
641impl Hash for Value {
642  fn hash<H: Hasher>(&self, state: &mut H) {
643    match self {
644      #[cfg(feature = "rational")]
645      Value::R64(x) => x.borrow().hash(state),
646      #[cfg(feature = "u8")]
647      Value::U8(x)   => x.borrow().hash(state),
648      #[cfg(feature = "u16")]
649      Value::U16(x)  => x.borrow().hash(state),
650      #[cfg(feature = "u32")]
651      Value::U32(x)  => x.borrow().hash(state),
652      #[cfg(feature = "u64")]
653      Value::U64(x)  => x.borrow().hash(state),
654      #[cfg(feature = "u128")]
655      Value::U128(x) => x.borrow().hash(state),
656      #[cfg(feature = "i8")]
657      Value::I8(x)   => x.borrow().hash(state),
658      #[cfg(feature = "i16")]
659      Value::I16(x)  => x.borrow().hash(state),
660      #[cfg(feature = "i32")]
661      Value::I32(x)  => x.borrow().hash(state),
662      #[cfg(feature = "i64")]
663      Value::I64(x)  => x.borrow().hash(state),
664      #[cfg(feature = "i128")]
665      Value::I128(x) => x.borrow().hash(state),
666      #[cfg(feature = "f32")]
667      Value::F32(x)  => x.borrow().to_bits().hash(state),
668      #[cfg(feature = "f64")]
669      Value::F64(x)  => x.borrow().to_bits().hash(state),
670      #[cfg(feature = "complex")]
671      Value::C64(x) => x.borrow().hash(state),
672      #[cfg(any(feature = "bool", feature = "variable_define"))]
673      Value::Bool(x) => x.borrow().hash(state),
674      #[cfg(feature = "atom")]
675      Value::Atom(x) => x.borrow().hash(state),
676      #[cfg(feature = "set")]
677      Value::Set(x)  => x.borrow().hash(state),
678      #[cfg(feature = "map")]
679      Value::Map(x)  => x.borrow().hash(state),
680      #[cfg(feature = "table")]
681      Value::Table(x) => x.borrow().hash(state),
682      #[cfg(feature = "tuple")]
683      Value::Tuple(x) => x.borrow().hash(state),
684      #[cfg(feature = "record")]
685      Value::Record(x) => x.borrow().hash(state),
686      #[cfg(feature = "enum")]
687      Value::Enum(x) => x.borrow().hash(state),
688      #[cfg(any(feature = "string", feature = "variable_define"))]
689      Value::String(x) => x.borrow().hash(state),
690      #[cfg(all(feature = "matrix", feature = "bool"))]
691      Value::MatrixBool(x) => x.hash(state),
692      #[cfg(feature = "matrix")]
693      Value::MatrixIndex(x) => x.hash(state),
694      #[cfg(all(feature = "matrix", feature = "u8"))]
695      Value::MatrixU8(x)   => x.hash(state),
696      #[cfg(all(feature = "matrix", feature = "u16"))]
697      Value::MatrixU16(x)  => x.hash(state),
698      #[cfg(all(feature = "matrix", feature = "u32"))]
699      Value::MatrixU32(x)  => x.hash(state),
700      #[cfg(all(feature = "matrix", feature = "u64"))]
701      Value::MatrixU64(x)  => x.hash(state),
702      #[cfg(all(feature = "matrix", feature = "u128"))]
703      Value::MatrixU128(x) => x.hash(state),
704      #[cfg(all(feature = "matrix", feature = "i8"))]
705      Value::MatrixI8(x)   => x.hash(state),
706      #[cfg(all(feature = "matrix", feature = "i16"))]
707      Value::MatrixI16(x)  => x.hash(state),
708      #[cfg(all(feature = "matrix", feature = "i32"))]
709      Value::MatrixI32(x)  => x.hash(state),
710      #[cfg(all(feature = "matrix", feature = "i64"))]
711      Value::MatrixI64(x)  => x.hash(state),
712      #[cfg(all(feature = "matrix", feature = "i128"))]
713      Value::MatrixI128(x) => x.hash(state),
714      #[cfg(all(feature = "matrix", feature = "f32"))]
715      Value::MatrixF32(x)  => todo!(),
716      #[cfg(all(feature = "matrix", feature = "f64"))]
717      Value::MatrixF64(x)  => todo!(),
718      #[cfg(all(feature = "matrix", feature = "string"))]
719      Value::MatrixString(x) => x.hash(state),
720      #[cfg(feature = "matrix")]
721      Value::MatrixValue(x)  => x.hash(state),
722      #[cfg(all(feature = "matrix", feature = "rational"))]
723      Value::MatrixR64(x) => x.hash(state),
724      #[cfg(all(feature = "matrix", feature = "complex"))]
725      Value::MatrixC64(x) => x.hash(state),
726      Value::Id(x)   => x.hash(state),
727      Value::Kind(x) => x.hash(state),
728      Value::Index(x)=> x.borrow().hash(state),
729      Value::MutableReference(x) => x.borrow().hash(state),
730      Value::Empty => Value::Empty.hash(state),
731      Value::IndexAll => Value::IndexAll.hash(state),
732    }
733  }
734}
735impl Value {
736
737  pub fn from_kind(kind: &ValueKind) -> Self {
738    todo!();
739  }
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((*v.borrow()) as f32))),
985    #[cfg(all(feature = "u8", feature = "f64"))]
986    (Value::U8(v), ValueKind::F64) => Some(Value::F64(Ref::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((*v.borrow()) as f32))),
1006    #[cfg(all(feature = "u16", feature = "f64"))]
1007    (Value::U16(v), ValueKind::F64) => Some(Value::F64(Ref::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((*v.borrow()) as f32))),
1027    #[cfg(all(feature = "u32", feature = "f64"))]
1028    (Value::U32(v), ValueKind::F64) => Some(Value::F64(Ref::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((*v.borrow()) as f32))),
1048    #[cfg(all(feature = "u64", feature = "f64"))]
1049    (Value::U64(v), ValueKind::F64) => Some(Value::F64(Ref::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((*v.borrow()) as f32))),
1069    #[cfg(all(feature = "u128", feature = "f64"))]
1070    (Value::U128(v), ValueKind::F64) => Some(Value::F64(Ref::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((*v.borrow()) as f32))),
1091    #[cfg(all(feature = "i8", feature = "f64"))]
1092    (Value::I8(v), ValueKind::F64) => Some(Value::F64(Ref::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((*v.borrow()) as f32))),
1112    #[cfg(all(feature = "i16", feature = "f64"))]
1113    (Value::I16(v), ValueKind::F64) => Some(Value::F64(Ref::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((*v.borrow()) as f32))),
1133    #[cfg(all(feature = "i32", feature = "f64"))]
1134    (Value::I32(v), ValueKind::F64) => Some(Value::F64(Ref::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((*v.borrow()) as f32))),
1154    #[cfg(all(feature = "i64", feature = "f64"))]
1155    (Value::I64(v), ValueKind::F64) => Some(Value::F64(Ref::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((*v.borrow()) as f32))),
1175    #[cfg(all(feature = "i128", feature = "f64"))]
1176    (Value::I128(v), ValueKind::F64) => Some(Value::F64(Ref::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((*v.borrow()) as f64))),
1181    #[cfg(all(feature = "f32", feature = "f64"))]
1182    (Value::F64(v), ValueKind::F32) => Some(Value::F32(Ref::new((*v.borrow()) 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() as i8))),
1187    #[cfg(all(feature = "f32", feature = "i16"))]
1188    (Value::F32(v), ValueKind::I16) => Some(Value::I16(Ref::new(*v.borrow() as i16))),
1189    #[cfg(all(feature = "f32", feature = "i32"))]
1190    (Value::F32(v), ValueKind::I32) => Some(Value::I32(Ref::new(*v.borrow() as i32))),
1191    #[cfg(all(feature = "f32", feature = "i64"))]
1192    (Value::F32(v), ValueKind::I64) => Some(Value::I64(Ref::new(*v.borrow() as i64))),
1193    #[cfg(all(feature = "f32", feature = "i128"))]
1194    (Value::F32(v), ValueKind::I128) => Some(Value::I128(Ref::new(*v.borrow() as i128))),
1195    #[cfg(all(feature = "f32", feature = "u8"))]
1196    (Value::F32(v), ValueKind::U8) => Some(Value::U8(Ref::new(*v.borrow() as u8))),
1197    #[cfg(all(feature = "f32", feature = "u16"))]
1198    (Value::F32(v), ValueKind::U16) => Some(Value::U16(Ref::new(*v.borrow() as u16))),
1199    #[cfg(all(feature = "f32", feature = "u32"))]
1200    (Value::F32(v), ValueKind::U32) => Some(Value::U32(Ref::new(*v.borrow() as u32))),
1201    #[cfg(all(feature = "f32", feature = "u64"))]
1202    (Value::F32(v), ValueKind::U64) => Some(Value::U64(Ref::new(*v.borrow() as u64))),
1203    #[cfg(all(feature = "f32", feature = "u128"))]
1204    (Value::F32(v), ValueKind::U128) => Some(Value::U128(Ref::new(*v.borrow() as u128))),
1205    #[cfg(all(feature = "f64", feature = "i8"))]
1206    (Value::F64(v), ValueKind::I8) => Some(Value::I8(Ref::new(*v.borrow() as i8))),
1207    #[cfg(all(feature = "f64", feature = "i16"))]
1208    (Value::F64(v), ValueKind::I16) => Some(Value::I16(Ref::new(*v.borrow() as i16))),
1209    #[cfg(all(feature = "f64", feature = "i32"))]
1210    (Value::F64(v), ValueKind::I32) => Some(Value::I32(Ref::new(*v.borrow() as i32))),
1211    #[cfg(all(feature = "f64", feature = "i64"))]
1212    (Value::F64(v), ValueKind::I64) => Some(Value::I64(Ref::new(*v.borrow() as i64))),
1213    #[cfg(all(feature = "f64", feature = "i128"))]
1214    (Value::F64(v), ValueKind::I128) => Some(Value::I128(Ref::new(*v.borrow() as i128))),
1215    #[cfg(all(feature = "f64", feature = "u8"))]
1216    (Value::F64(v), ValueKind::U8) => Some(Value::U8(Ref::new(*v.borrow() as u8))),
1217    #[cfg(all(feature = "f64", feature = "u16"))]
1218    (Value::F64(v), ValueKind::U16) => Some(Value::U16(Ref::new(*v.borrow() as u16))),
1219    #[cfg(all(feature = "f64", feature = "u32"))]
1220    (Value::F64(v), ValueKind::U32) => Some(Value::U32(Ref::new(*v.borrow() as u32))),
1221    #[cfg(all(feature = "f64", feature = "u64"))]
1222    (Value::F64(v), ValueKind::U64) => Some(Value::U64(Ref::new(*v.borrow() as u64))),
1223    #[cfg(all(feature = "f64", feature = "u128"))]
1224    (Value::F64(v), ValueKind::U128) => Some(Value::U128(Ref::new(*v.borrow() as u128))),
1225
1226      /*
1227      // ==== INDEX conversions ====
1228      (Value::Index(i), U32) => Some(Value::U32(Ref::new((*i.borrow()) as u32))),
1229      (Value::U32(v), Index) => Some(Value::Index(Ref::new((*v.borrow()) as usize))),
1230
1231
1232      // ==== MATRIX conversions (element-wise) ====
1233      (Value::MatrixU8(m), MatrixU16) => Some(Value::MatrixU16(m.map(|x| *x as u16))),
1234      (Value::MatrixI32(m), MatrixF64) => Some(Value::MatrixF64(m.map(|x| (*x) as f64))),
1235      // You can expand other matrix conversions similarly...
1236
1237      // ==== COMPLEX TYPES (stubs) ====
1238      (Value::Set(set), Set(_)) => Some(Value::Set(set.clone())), // TODO: element-wise convert
1239      (Value::Map(map), Map(_)) => Some(Value::Map(map.clone())), // TODO: key/value convert
1240      (Value::Record(r), Record(_)) => Some(Value::Record(r.clone())), // TODO: field convert
1241      (Value::Table(t), Table(_)) => Some(Value::Table(t.clone())), // TODO: column convert
1242
1243      // ==== ENUM, KIND ====
1244      (Value::Enum(e), Enum(_)) => Some(Value::Enum(e.clone())),
1245      (Value::Kind(k), Kind(_)) => Some(Value::Kind(k.clone())),
1246
1247      // ==== SPECIAL CASES ====
1248      (Value::IndexAll, IndexAll) => Some(Value::IndexAll),
1249      (Value::Empty, Empty) => Some(Value::Empty),
1250      */
1251      // ==== FALLBACK ====
1252      _ => None,
1253    }
1254  }
1255
1256  pub fn size_of(&self) -> usize {
1257    match self {
1258      #[cfg(feature = "rational")]
1259      Value::R64(x) => 16,
1260      #[cfg(feature = "u8")]
1261      Value::U8(x) => 1,
1262      #[cfg(feature = "u16")]
1263      Value::U16(x) => 2,
1264      #[cfg(feature = "u32")]
1265      Value::U32(x) => 4,
1266      #[cfg(feature = "u64")]
1267      Value::U64(x) => 8,
1268      #[cfg(feature = "u128")]
1269      Value::U128(x) => 16,
1270      #[cfg(feature = "i8")]
1271      Value::I8(x) => 1,
1272      #[cfg(feature = "i16")]
1273      Value::I16(x) => 2,
1274      #[cfg(feature = "i32")]
1275      Value::I32(x) => 4,
1276      #[cfg(feature = "i64")]
1277      Value::I64(x) => 8,
1278      #[cfg(feature = "i128")]
1279      Value::I128(x) => 16,
1280      #[cfg(feature = "f32")]
1281      Value::F32(x) => 4,
1282      #[cfg(feature = "f64")]
1283      Value::F64(x) => 8,
1284      #[cfg(any(feature = "bool", feature = "variable_define"))]
1285      Value::Bool(x) => 1,
1286      #[cfg(feature = "complex")]
1287      Value::C64(x) => 16,
1288      #[cfg(all(feature = "matrix"))]
1289      Value::MatrixIndex(x) => x.size_of(),
1290      #[cfg(all(feature = "matrix", feature = "bool"))]
1291      Value::MatrixBool(x) => x.size_of(),
1292      #[cfg(all(feature = "matrix", feature = "u8"))]
1293      Value::MatrixU8(x)   => x.size_of(),
1294      #[cfg(all(feature = "matrix", feature = "u16"))]
1295      Value::MatrixU16(x)  => x.size_of(),
1296      #[cfg(all(feature = "matrix", feature = "u32"))]
1297      Value::MatrixU32(x)  => x.size_of(),
1298      #[cfg(all(feature = "matrix", feature = "u64"))]
1299      Value::MatrixU64(x)  => x.size_of(),
1300      #[cfg(all(feature = "matrix", feature = "u128"))]
1301      Value::MatrixU128(x) => x.size_of(),
1302      #[cfg(all(feature = "matrix", feature = "i8"))]
1303      Value::MatrixI8(x)   => x.size_of(),
1304      #[cfg(all(feature = "matrix", feature = "i16"))]
1305      Value::MatrixI16(x)  => x.size_of(),
1306      #[cfg(all(feature = "matrix", feature = "i32"))]
1307      Value::MatrixI32(x)  => x.size_of(),
1308      #[cfg(all(feature = "matrix", feature = "i64"))]
1309      Value::MatrixI64(x)  => x.size_of(),
1310      #[cfg(all(feature = "matrix", feature = "i128"))]
1311      Value::MatrixI128(x) => x.size_of(),
1312      #[cfg(all(feature = "matrix", feature = "f32"))]
1313      Value::MatrixF32(x)  => x.size_of(),
1314      #[cfg(all(feature = "matrix", feature = "f64"))]
1315      Value::MatrixF64(x)  => x.size_of(),
1316      #[cfg(feature = "matrix")]
1317      Value::MatrixValue(x)  => x.size_of(),
1318      #[cfg(all(feature = "matrix", feature = "string"))]
1319      Value::MatrixString(x) => x.size_of(),
1320      #[cfg(all(feature = "matrix", feature = "rational"))]
1321      Value::MatrixR64(x) => x.size_of(),
1322      #[cfg(all(feature = "matrix", feature = "complex"))]
1323      Value::MatrixC64(x) => x.size_of(),
1324      #[cfg(any(feature = "string", feature = "variable_define"))]
1325      Value::String(x) => x.borrow().len(),
1326      #[cfg(feature = "atom")]
1327      Value::Atom(x) => 8,
1328      #[cfg(feature = "set")]
1329      Value::Set(x) => x.borrow().size_of(),
1330      #[cfg(feature = "map")]
1331      Value::Map(x) => x.borrow().size_of(),
1332      #[cfg(feature = "table")]
1333      Value::Table(x) => x.borrow().size_of(),
1334      #[cfg(feature = "record")]
1335      Value::Record(x) => x.borrow().size_of(),
1336      #[cfg(feature = "tuple")]
1337      Value::Tuple(x) => x.borrow().size_of(),
1338      #[cfg(feature = "enum")]
1339      Value::Enum(x) => x.borrow().size_of(),
1340      Value::MutableReference(x) => x.borrow().size_of(),
1341      Value::Id(_) => 8,
1342      Value::Index(x) => 8,
1343      Value::Kind(_) => 0, // Kind is not a value, so it has no size
1344      Value::Empty => 0,
1345      Value::IndexAll => 0, // IndexAll is a special value, so it has no size
1346    }
1347  }
1348
1349  #[cfg(feature = "pretty_print")]
1350  pub fn to_html(&self) -> String {
1351    match self {
1352      #[cfg(feature = "u8")]
1353      Value::U8(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1354      #[cfg(feature = "u16")]
1355      Value::U16(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1356      #[cfg(feature = "u32")]
1357      Value::U32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1358      #[cfg(feature = "u64")]
1359      Value::U64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1360      #[cfg(feature = "i8")]
1361      Value::I8(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1362      #[cfg(feature = "i128")]
1363      Value::I128(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1364      #[cfg(feature = "i16")]
1365      Value::I16(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1366      #[cfg(feature = "i32")]
1367      Value::I32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1368      #[cfg(feature = "i64")]
1369      Value::I64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1370      #[cfg(feature = "i128")]
1371      Value::I128(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1372      #[cfg(feature = "f32")]
1373      Value::F32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1374      #[cfg(feature = "f64")]
1375      Value::F64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1376      #[cfg(any(feature = "string", feature = "variable_define"))]
1377      Value::String(s) => format!("<span class='mech-string'>\"{}\"</span>", s.borrow()),
1378      #[cfg(any(feature = "bool", feature = "variable_define"))]
1379      Value::Bool(b) => format!("<span class='mech-boolean'>{}</span>", b.borrow()),
1380      #[cfg(feature = "complex")]
1381      Value::C64(c) => c.borrow().to_html(),
1382      #[cfg(feature = "rational")]
1383      Value::R64(r) => r.borrow().to_html(),
1384      #[cfg(all(feature = "matrix", feature = "u8"))]
1385      Value::MatrixU8(m) => m.to_html(),
1386      #[cfg(all(feature = "matrix", feature = "u16"))]
1387      Value::MatrixU16(m) => m.to_html(),
1388      #[cfg(all(feature = "matrix", feature = "u32"))]
1389      Value::MatrixU32(m) => m.to_html(),
1390      #[cfg(all(feature = "matrix", feature = "u64"))]
1391      Value::MatrixU64(m) => m.to_html(),
1392      #[cfg(all(feature = "matrix", feature = "u128"))]
1393      Value::MatrixU128(m) => m.to_html(),
1394      #[cfg(all(feature = "matrix", feature = "i8"))]
1395      Value::MatrixI8(m) => m.to_html(),
1396      #[cfg(all(feature = "matrix", feature = "i16"))]
1397      Value::MatrixI16(m) => m.to_html(),
1398      #[cfg(all(feature = "matrix", feature = "i32"))]
1399      Value::MatrixI32(m) => m.to_html(),
1400      #[cfg(all(feature = "matrix", feature = "i64"))]
1401      Value::MatrixI64(m) => m.to_html(),
1402      #[cfg(all(feature = "matrix", feature = "i128"))]
1403      Value::MatrixI128(m) => m.to_html(),
1404      #[cfg(all(feature = "matrix", feature = "f64"))]
1405      Value::MatrixF64(m) => m.to_html(),
1406      #[cfg(all(feature = "matrix", feature = "f32"))]
1407      Value::MatrixF32(m) => m.to_html(),
1408      #[cfg(feature = "matrix")]
1409      Value::MatrixIndex(m) => m.to_html(),
1410      #[cfg(all(feature = "matrix", feature = "bool"))]
1411      Value::MatrixBool(m) => m.to_html(),
1412      #[cfg(all(feature = "matrix", feature = "string"))]
1413      Value::MatrixString(m) => m.to_html(),
1414      #[cfg(feature = "matrix")]
1415      Value::MatrixValue(m) => m.to_html(),
1416      #[cfg(all(feature = "matrix", feature = "rational"))]
1417      Value::MatrixR64(m) => m.to_html(),
1418      #[cfg(all(feature = "matrix", feature = "complex"))]
1419      Value::MatrixC64(m) => m.to_html(),
1420      #[cfg(feature = "atom")]
1421      Value::Atom(a) => a.borrow().to_html(),
1422      #[cfg(feature = "set")]
1423      Value::Set(s) => s.borrow().to_html(),
1424      #[cfg(feature = "map")]
1425      Value::Map(m) => m.borrow().to_html(),
1426      #[cfg(feature = "table")]
1427      Value::Table(t) => t.borrow().to_html(),
1428      #[cfg(feature = "record")]
1429      Value::Record(r) => r.borrow().to_html(),
1430      #[cfg(feature = "tuple")]
1431      Value::Tuple(t) => t.borrow().to_html(),
1432      #[cfg(feature = "enum")]
1433      Value::Enum(e) => e.borrow().to_html(),
1434      Value::MutableReference(m) => {
1435        let inner = m.borrow();
1436        format!("<span class='mech-reference'>{}</span>", inner.to_html())
1437      },
1438      _ => "???".to_string(),
1439    }
1440  }
1441
1442  pub fn shape(&self) -> Vec<usize> {
1443    match self {
1444      #[cfg(feature = "rational")]
1445      Value::R64(x) => vec![1,1],
1446      #[cfg(feature = "complex")]
1447      Value::C64(x) => vec![1,1],
1448      #[cfg(feature = "u8")]
1449      Value::U8(x) => vec![1,1],
1450      #[cfg(feature = "u16")]
1451      Value::U16(x) => vec![1,1],
1452      #[cfg(feature = "u32")]
1453      Value::U32(x) => vec![1,1],
1454      #[cfg(feature = "u64")]
1455      Value::U64(x) => vec![1,1],
1456      #[cfg(feature = "u128")]
1457      Value::U128(x) => vec![1,1],
1458      #[cfg(feature = "i8")]
1459      Value::I8(x) => vec![1,1],
1460      #[cfg(feature = "i16")]
1461      Value::I16(x) => vec![1,1],
1462      #[cfg(feature = "i32")]
1463      Value::I32(x) => vec![1,1],
1464      #[cfg(feature = "i64")]
1465      Value::I64(x) => vec![1,1],
1466      #[cfg(feature = "i128")]
1467      Value::I128(x) => vec![1,1],
1468      #[cfg(feature = "f32")]
1469      Value::F32(x) => vec![1,1],
1470      #[cfg(feature = "f64")]
1471      Value::F64(x) => vec![1,1],
1472      #[cfg(any(feature = "string", feature = "variable_define"))]
1473      Value::String(x) => vec![1,1],
1474      #[cfg(any(feature = "bool", feature = "variable_define"))]
1475      Value::Bool(x) => vec![1,1],
1476      #[cfg(feature = "atom")]
1477      Value::Atom(x) => vec![1,1],
1478      #[cfg(feature = "matrix")]
1479      Value::MatrixIndex(x) => x.shape(),
1480      #[cfg(all(feature = "matrix", feature = "bool"))]
1481      Value::MatrixBool(x) => x.shape(),
1482      #[cfg(all(feature = "matrix", feature = "u8"))]
1483      Value::MatrixU8(x) => x.shape(),
1484      #[cfg(all(feature = "matrix", feature = "u16"))]
1485      Value::MatrixU16(x) => x.shape(),
1486      #[cfg(all(feature = "matrix", feature = "u32"))]
1487      Value::MatrixU32(x) => x.shape(),
1488      #[cfg(all(feature = "matrix", feature = "u64"))]
1489      Value::MatrixU64(x) => x.shape(),
1490      #[cfg(all(feature = "matrix", feature = "u128"))]
1491      Value::MatrixU128(x) => x.shape(),
1492      #[cfg(all(feature = "matrix", feature = "i8"))]
1493      Value::MatrixI8(x) => x.shape(),
1494      #[cfg(all(feature = "matrix", feature = "i16"))]
1495      Value::MatrixI16(x) => x.shape(),
1496      #[cfg(all(feature = "matrix", feature = "i32"))]
1497      Value::MatrixI32(x) => x.shape(),
1498      #[cfg(all(feature = "matrix", feature = "i64"))]
1499      Value::MatrixI64(x) => x.shape(),
1500      #[cfg(all(feature = "matrix", feature = "i128"))]
1501      Value::MatrixI128(x) => x.shape(),
1502      #[cfg(all(feature = "matrix", feature = "f32"))]
1503      Value::MatrixF32(x) => x.shape(),
1504      #[cfg(all(feature = "matrix", feature = "f64"))]
1505      Value::MatrixF64(x) => x.shape(),
1506      #[cfg(all(feature = "matrix", feature = "string"))]
1507      Value::MatrixString(x) => x.shape(),
1508      #[cfg(feature = "matrix")]
1509      Value::MatrixValue(x) => x.shape(),
1510      #[cfg(all(feature = "matrix", feature = "rational"))]
1511      Value::MatrixR64(x) => x.shape(),
1512      #[cfg(all(feature = "matrix", feature = "complex"))]
1513      Value::MatrixC64(x) => x.shape(),
1514      #[cfg(feature = "enum")]
1515      Value::Enum(x) => vec![1,1],
1516      #[cfg(feature = "table")]
1517      Value::Table(x) => x.borrow().shape(),
1518      #[cfg(feature = "set")]
1519      Value::Set(x) => vec![1,x.borrow().set.len()],
1520      #[cfg(feature = "map")]
1521      Value::Map(x) => vec![1,x.borrow().map.len()],
1522      #[cfg(feature = "record")]
1523      Value::Record(x) => x.borrow().shape(),
1524      #[cfg(feature = "tuple")]
1525      Value::Tuple(x) => vec![1,x.borrow().size()],
1526      Value::Index(x) => vec![1,1],
1527      Value::MutableReference(x) => x.borrow().shape(),
1528      Value::Empty => vec![0,0],
1529      Value::IndexAll => vec![0,0],
1530      Value::Kind(_) => vec![0,0],
1531      Value::Id(x) => vec![0,0],
1532    }
1533  }
1534
1535  pub fn deref_kind(&self) -> ValueKind {
1536    match self {
1537      Value::MutableReference(x) => x.borrow().kind(),
1538      x => x.kind(),
1539    }
1540  }
1541
1542  pub fn kind(&self) -> ValueKind {
1543    match self {
1544      #[cfg(feature = "complex")]
1545      Value::C64(_) => ValueKind::C64,
1546      #[cfg(feature = "rational")]
1547      Value::R64(_) => ValueKind::R64,
1548      #[cfg(feature = "u8")]
1549      Value::U8(_) => ValueKind::U8,
1550      #[cfg(feature = "u16")]
1551      Value::U16(_) => ValueKind::U16,
1552      #[cfg(feature = "u32")]
1553      Value::U32(_) => ValueKind::U32,
1554      #[cfg(feature = "u64")]
1555      Value::U64(_) => ValueKind::U64,
1556      #[cfg(feature = "u128")]
1557      Value::U128(_) => ValueKind::U128,
1558      #[cfg(feature = "i8")]
1559      Value::I8(_) => ValueKind::I8,
1560      #[cfg(feature = "i16")]
1561      Value::I16(_) => ValueKind::I16,
1562      #[cfg(feature = "i32")]
1563      Value::I32(_) => ValueKind::I32,
1564      #[cfg(feature = "i64")]
1565      Value::I64(_) => ValueKind::I64,
1566      #[cfg(feature = "i128")]
1567      Value::I128(_) => ValueKind::I128,
1568      #[cfg(feature = "f32")]
1569      Value::F32(_) => ValueKind::F32,
1570      #[cfg(feature = "f64")]
1571      Value::F64(_) => ValueKind::F64,
1572      #[cfg(any(feature = "string", feature = "variable_define"))]
1573      Value::String(_) => ValueKind::String,
1574      #[cfg(any(feature = "bool", feature = "variable_define"))]
1575      Value::Bool(_) => ValueKind::Bool,
1576      #[cfg(feature = "atom")]
1577      Value::Atom(x) => ValueKind::Atom(x.borrow().id(), x.borrow().name().clone()),
1578      #[cfg(feature = "matrix")]
1579      Value::MatrixValue(x) => ValueKind::Matrix(Box::new(ValueKind::Any),x.shape()),
1580      #[cfg(feature = "matrix")]
1581      Value::MatrixIndex(x) => ValueKind::Matrix(Box::new(ValueKind::Index),x.shape()),
1582      #[cfg(all(feature = "matrix", feature = "bool"))]
1583      Value::MatrixBool(x) => ValueKind::Matrix(Box::new(ValueKind::Bool), x.shape()),
1584      #[cfg(all(feature = "matrix", feature = "u8"))]
1585      Value::MatrixU8(x) => ValueKind::Matrix(Box::new(ValueKind::U8), x.shape()),
1586      #[cfg(all(feature = "matrix", feature = "u16"))]
1587      Value::MatrixU16(x) => ValueKind::Matrix(Box::new(ValueKind::U16), x.shape()),
1588      #[cfg(all(feature = "matrix", feature = "u32"))]
1589      Value::MatrixU32(x) => ValueKind::Matrix(Box::new(ValueKind::U32), x.shape()),
1590      #[cfg(all(feature = "matrix", feature = "u64"))]
1591      Value::MatrixU64(x) => ValueKind::Matrix(Box::new(ValueKind::U64), x.shape()),
1592      #[cfg(all(feature = "matrix", feature = "u128"))]
1593      Value::MatrixU128(x) => ValueKind::Matrix(Box::new(ValueKind::U128), x.shape()),
1594      #[cfg(all(feature = "matrix", feature = "i8"))]
1595      Value::MatrixI8(x) => ValueKind::Matrix(Box::new(ValueKind::I8), x.shape()),
1596      #[cfg(all(feature = "matrix", feature = "i16"))]
1597      Value::MatrixI16(x) => ValueKind::Matrix(Box::new(ValueKind::I16), x.shape()),
1598      #[cfg(all(feature = "matrix", feature = "i32"))]
1599      Value::MatrixI32(x) => ValueKind::Matrix(Box::new(ValueKind::I32), x.shape()),
1600      #[cfg(all(feature = "matrix", feature = "i64"))]
1601      Value::MatrixI64(x) => ValueKind::Matrix(Box::new(ValueKind::I64), x.shape()),
1602      #[cfg(all(feature = "matrix", feature = "i128"))]
1603      Value::MatrixI128(x) => ValueKind::Matrix(Box::new(ValueKind::I128), x.shape()),
1604      #[cfg(all(feature = "matrix", feature = "f32"))]
1605      Value::MatrixF32(x) => ValueKind::Matrix(Box::new(ValueKind::F32), x.shape()),
1606      #[cfg(all(feature = "matrix", feature = "f64"))]
1607      Value::MatrixF64(x) => ValueKind::Matrix(Box::new(ValueKind::F64), x.shape()),
1608      #[cfg(all(feature = "matrix", feature = "string"))]
1609      Value::MatrixString(x) => ValueKind::Matrix(Box::new(ValueKind::String), x.shape()),
1610      #[cfg(all(feature = "matrix", feature = "rational"))]
1611      Value::MatrixR64(x) => ValueKind::Matrix(Box::new(ValueKind::R64), x.shape()),
1612      #[cfg(all(feature = "matrix", feature = "complex"))]
1613      Value::MatrixC64(x) => ValueKind::Matrix(Box::new(ValueKind::C64), x.shape()),
1614      #[cfg(feature = "table")]
1615      Value::Table(x) => x.borrow().kind(),
1616      #[cfg(feature = "set")]
1617      Value::Set(x) => x.borrow().kind(),
1618      #[cfg(feature = "map")]
1619      Value::Map(x) => x.borrow().kind(),
1620      #[cfg(feature = "record")]
1621      Value::Record(x) => x.borrow().kind(),
1622      #[cfg(feature = "tuple")]
1623      Value::Tuple(x) => x.borrow().kind(),
1624      #[cfg(feature = "enum")]
1625      Value::Enum(x) => x.borrow().kind(),
1626      Value::MutableReference(x) => ValueKind::Reference(Box::new(x.borrow().kind())),
1627      Value::Empty => ValueKind::Empty,
1628      Value::IndexAll => ValueKind::Empty,
1629      Value::Id(x) => ValueKind::Id,
1630      Value::Index(x) => ValueKind::Index,
1631      Value::Kind(x) => x.clone(),
1632    }
1633  }
1634
1635  #[cfg(feature = "matrix")]
1636  pub fn is_matrix(&self) -> bool {
1637    match self {
1638      #[cfg(feature = "matrix")]
1639      Value::MatrixIndex(_) => true,
1640      #[cfg(all(feature = "matrix", feature = "bool"))]
1641      Value::MatrixBool(_) => true,
1642      #[cfg(all(feature = "matrix", feature = "u8"))]
1643      Value::MatrixU8(_) => true,
1644      #[cfg(all(feature = "matrix", feature = "u16"))]
1645      Value::MatrixU16(_) => true,
1646      #[cfg(all(feature = "matrix", feature = "u32"))]
1647      Value::MatrixU32(_) => true,
1648      #[cfg(all(feature = "matrix", feature = "u64"))]
1649      Value::MatrixU64(_) => true,
1650      #[cfg(all(feature = "matrix", feature = "u128"))]
1651      Value::MatrixU128(_) => true,
1652      #[cfg(all(feature = "matrix", feature = "i8"))]
1653      Value::MatrixI8(_) => true,
1654      #[cfg(all(feature = "matrix", feature = "i16"))]
1655      Value::MatrixI16(_) => true,
1656      #[cfg(all(feature = "matrix", feature = "i32"))]
1657      Value::MatrixI32(_) => true,
1658      #[cfg(all(feature = "matrix", feature = "i64"))]
1659      Value::MatrixI64(_) => true,
1660      #[cfg(all(feature = "matrix", feature = "i128"))]
1661      Value::MatrixI128(_) => true,
1662      #[cfg(all(feature = "matrix", feature = "f32"))]
1663      Value::MatrixF32(_) => true,
1664      #[cfg(all(feature = "matrix", feature = "f64"))]
1665      Value::MatrixF64(_) => true,
1666      #[cfg(all(feature = "matrix", feature = "string"))]
1667      Value::MatrixString(_) => true,
1668      #[cfg(all(feature = "matrix", feature = "rational"))]
1669      Value::MatrixR64(_) => true,
1670      #[cfg(all(feature = "matrix", feature = "complex"))]
1671      Value::MatrixC64(_) => true,
1672      #[cfg(feature = "matrix")]
1673      Value::MatrixValue(_) => true,
1674      _ => false,
1675    }
1676  }
1677
1678  pub fn is_scalar(&self) -> bool {
1679    match self {
1680      #[cfg(feature = "u8")]
1681      Value::U8(_) => true,
1682      #[cfg(feature = "u16")]
1683      Value::U16(_) => true,
1684      #[cfg(feature = "u32")]
1685      Value::U32(_) => true,
1686      #[cfg(feature = "u64")]
1687      Value::U64(_) => true,
1688      #[cfg(feature = "u128")]
1689      Value::U128(_) => true,
1690      #[cfg(feature = "i8")]
1691      Value::I8(_) => true,
1692      #[cfg(feature = "i16")]
1693      Value::I16(_) => true,
1694      #[cfg(feature = "i32")]
1695      Value::I32(_) => true,
1696      #[cfg(feature = "i64")]
1697      Value::I64(_) => true,
1698      #[cfg(feature = "i128")]
1699      Value::I128(_) => true,
1700      #[cfg(feature = "f32")]
1701      Value::F32(_) => true,
1702      #[cfg(feature = "f64")]
1703      Value::F64(_) => true,
1704      #[cfg(any(feature = "bool", feature = "variable_define"))]
1705      Value::Bool(_) => true,
1706      #[cfg(any(feature = "string", feature = "variable_define"))]
1707      Value::String(_) => true,
1708      #[cfg(feature = "atom")]
1709      Value::Atom(_) => true,
1710      Value::Index(_) => true,
1711      _ => false,
1712    }
1713  }
1714
1715  #[cfg(any(feature = "bool", feature = "variable_define"))]
1716  pub fn as_bool(&self) -> MResult<Ref<bool>> {
1717    if let Value::Bool(v) = self {
1718      Ok(v.clone())
1719    } else if let Value::MutableReference(val) = self {
1720      val.borrow().as_bool()
1721    } else {
1722      Err(MechError2::new(
1723        UnhandledFunctionArgumentKindError,
1724        None
1725      ).with_compiler_loc())
1726    }
1727  }
1728
1729  impl_as_type!(i8);
1730  impl_as_type!(i16);
1731  impl_as_type!(i32);
1732  impl_as_type!(i64);
1733  impl_as_type!(i128);
1734  impl_as_type!(u8);
1735  impl_as_type!(u16);
1736  impl_as_type!(u32);
1737  impl_as_type!(u64);
1738  impl_as_type!(u128);
1739
1740  pub fn is_string(&self) -> bool {
1741    match self {
1742      #[cfg(feature = "string")]
1743      Value::String(_) => true,
1744      #[cfg(feature = "string")]
1745      Value::MatrixString(_) => true,
1746      Value::MutableReference(val) => val.borrow().is_string(),
1747      _ => false,
1748    }
1749  }
1750
1751  #[cfg(any(feature = "string", feature = "variable_define"))]
1752  pub fn as_string(&self) -> MResult<Ref<String>> {
1753    match self {
1754      Value::String(v) => Ok(v.clone()),
1755      #[cfg(feature = "u8")]
1756      Value::U8(v) => Ok(Ref::new(v.borrow().to_string())),
1757      #[cfg(feature = "u16")]
1758      Value::U16(v) => Ok(Ref::new(v.borrow().to_string())),
1759      #[cfg(feature = "u32")]
1760      Value::U32(v) => Ok(Ref::new(v.borrow().to_string())),
1761      #[cfg(feature = "u64")]
1762      Value::U64(v) => Ok(Ref::new(v.borrow().to_string())),
1763      #[cfg(feature = "u128")]
1764      Value::U128(v) => Ok(Ref::new(v.borrow().to_string())),
1765      #[cfg(feature = "i8")]
1766      Value::I8(v) => Ok(Ref::new(v.borrow().to_string())),
1767      #[cfg(feature = "i16")]
1768      Value::I16(v) => Ok(Ref::new(v.borrow().to_string())),
1769      #[cfg(feature = "i32")]
1770      Value::I32(v) => Ok(Ref::new(v.borrow().to_string())),
1771      #[cfg(feature = "i64")]
1772      Value::I64(v) => Ok(Ref::new(v.borrow().to_string())),
1773      #[cfg(feature = "i128")]
1774      Value::I128(v) => Ok(Ref::new(v.borrow().to_string())),
1775      #[cfg(feature = "f32")]
1776      Value::F32(v) => Ok(Ref::new(format!("{}", v.borrow()))),
1777      #[cfg(feature = "f64")]
1778      Value::F64(v) => Ok(Ref::new(format!("{}", v.borrow()))),
1779      #[cfg(any(feature = "bool", feature = "variable_define"))]
1780      Value::Bool(v) => Ok(Ref::new(format!("{}", v.borrow()))),
1781      #[cfg(feature = "rational")]
1782      Value::R64(v) => Ok(Ref::new(v.borrow().to_string())),
1783      #[cfg(feature = "complex")]
1784      Value::C64(v) => Ok(Ref::new(v.borrow().to_string())),
1785      Value::MutableReference(val) => val.borrow().as_string(),
1786      _ => Err(
1787        MechError2::new(
1788          CannotConvertToTypeError { 
1789            target_type: "string",
1790          },
1791          None
1792        ).with_compiler_loc()
1793      ),
1794    }
1795  }
1796
1797  #[cfg(feature = "r64")]
1798  pub fn as_r64(&self) -> MResult<Ref<R64>> {
1799    match self {
1800      Value::R64(v) => Ok(v.clone()),
1801      #[cfg(feature = "f32")]
1802      Value::F32(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1803      #[cfg(feature = "f64")]
1804      Value::F64(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1805      #[cfg(feature = "u8")]
1806      Value::U8(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1807      #[cfg(feature = "u16")]
1808      Value::U16(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1809      #[cfg(feature = "u32")]
1810      Value::U32(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1811      #[cfg(feature = "u64")]
1812      Value::U64(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1813      #[cfg(feature = "u128")]
1814      Value::U128(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1815      #[cfg(feature = "i8")]
1816      Value::I8(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1817      #[cfg(feature = "i16")]
1818      Value::I16(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1819      #[cfg(feature = "i32")]
1820      Value::I32(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1821      #[cfg(feature = "i64")]
1822      Value::I64(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1823      #[cfg(feature = "i128")]
1824      Value::I128(v) => Ok(Ref::new(R64::new(*v.borrow() as i64, 1))),
1825      Value::MutableReference(val) => val.borrow().as_r64(),
1826      _ => Err(
1827        MechError2::new(
1828          CannotConvertToTypeError { 
1829            target_type: "r64",
1830          },
1831          None
1832        ).with_compiler_loc()
1833      ),
1834    }
1835  }
1836
1837  #[cfg(feature = "c64")]
1838  pub fn as_c64(&self) -> MResult<Ref<C64>> {
1839    match self {
1840      Value::C64(v) => Ok(v.clone()),
1841      #[cfg(feature = "f32")]
1842      Value::F32(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1843      #[cfg(feature = "f64")]
1844      Value::F64(v) => Ok(Ref::new(C64::new(*v.borrow(), 0.0))),
1845      #[cfg(feature = "u8")]
1846      Value::U8(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1847      #[cfg(feature = "u16")]
1848      Value::U16(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1849      #[cfg(feature = "u32")]
1850      Value::U32(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1851      #[cfg(feature = "u64")]
1852      Value::U64(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1853      #[cfg(feature = "u128")]
1854      Value::U128(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1855      #[cfg(feature = "i8")]
1856      Value::I8(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1857      #[cfg(feature = "i16")]
1858      Value::I16(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1859      #[cfg(feature = "i32")]
1860      Value::I32(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1861      #[cfg(feature = "i64")]
1862      Value::I64(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1863      #[cfg(feature = "i128")]
1864      Value::I128(v) => Ok(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1865      Value::MutableReference(val) => val.borrow().as_c64(),
1866      _ => Err(
1867        MechError2::new(
1868          CannotConvertToTypeError { 
1869            target_type: "c64",
1870          },
1871          None
1872        ).with_compiler_loc()
1873      ),
1874    }
1875  }
1876
1877  #[cfg(feature = "f32")]
1878  pub fn as_f32(&self) -> MResult<Ref<f32>> {
1879    match self {
1880      #[cfg(feature = "u8")]
1881      Value::U8(v) => Ok(Ref::new(*v.borrow() as f32)),
1882      #[cfg(feature = "u16")]
1883      Value::U16(v) => Ok(Ref::new(*v.borrow() as f32)),
1884      #[cfg(feature = "u32")]
1885      Value::U32(v) => Ok(Ref::new(*v.borrow() as f32)),
1886      #[cfg(feature = "u64")]
1887      Value::U64(v) => Ok(Ref::new(*v.borrow() as f32)),
1888      #[cfg(feature = "u128")]
1889      Value::U128(v) => Ok(Ref::new(*v.borrow() as f32)),
1890      #[cfg(feature = "i8")]
1891      Value::I8(v) => Ok(Ref::new(*v.borrow() as f32)),
1892      #[cfg(feature = "i16")]
1893      Value::I16(v) => Ok(Ref::new(*v.borrow() as f32)),
1894      #[cfg(feature = "i32")]
1895      Value::I32(v) => Ok(Ref::new(*v.borrow() as f32)),
1896      #[cfg(feature = "i64")]
1897      Value::I64(v) => Ok(Ref::new(*v.borrow() as f32)),
1898      #[cfg(feature = "i128")]
1899      Value::I128(v) => Ok(Ref::new(*v.borrow() as f32)),
1900      Value::F32(v) => Ok(v.clone()),
1901      #[cfg(feature = "f64")]
1902      Value::F64(v) => Ok(Ref::new((*v.borrow()) as f32)),
1903      Value::MutableReference(val) => val.borrow().as_f32(),
1904      _ => Err(
1905        MechError2::new(
1906          CannotConvertToTypeError { 
1907            target_type: "f32",
1908          },
1909          None
1910        ).with_compiler_loc()
1911      ),
1912    }
1913  }
1914
1915  #[cfg(feature = "f64")]
1916  pub fn as_f64(&self) -> MResult<Ref<f64>> {
1917    match self {
1918      #[cfg(feature = "u8")]
1919      Value::U8(v) => Ok(Ref::new(*v.borrow() as f64)),
1920      #[cfg(feature = "u16")]
1921      Value::U16(v) => Ok(Ref::new(*v.borrow() as f64)),
1922      #[cfg(feature = "u32")]
1923      Value::U32(v) => Ok(Ref::new(*v.borrow() as f64)),
1924      #[cfg(feature = "u64")]
1925      Value::U64(v) => Ok(Ref::new(*v.borrow() as f64)),
1926      #[cfg(feature = "u128")]
1927      Value::U128(v) => Ok(Ref::new(*v.borrow() as f64)),
1928      #[cfg(feature = "i8")]
1929      Value::I8(v) => Ok(Ref::new(*v.borrow() as f64)),
1930      #[cfg(feature = "i16")]
1931      Value::I16(v) => Ok(Ref::new(*v.borrow() as f64)),
1932      #[cfg(feature = "i32")]
1933      Value::I32(v) => Ok(Ref::new(*v.borrow() as f64)),
1934      #[cfg(feature = "i64")]
1935      Value::I64(v) => Ok(Ref::new(*v.borrow() as f64)),
1936      #[cfg(feature = "i128")]
1937      Value::I128(v) => Ok(Ref::new(*v.borrow() as f64)),
1938      #[cfg(feature = "f32")]
1939      Value::F32(v) => Ok(Ref::new((*v.borrow()) as f64)),
1940      Value::F64(v) => Ok(v.clone()),
1941      Value::MutableReference(val) => val.borrow().as_f64(),
1942      _ => Err(
1943        MechError2::new(
1944          CannotConvertToTypeError { 
1945            target_type: "f64",
1946          },
1947          None
1948        ).with_compiler_loc()
1949      ),
1950    }
1951  }
1952
1953  #[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(MechError2::new(CannotConvertToTypeError { target_type: "bool" }, None).with_compiler_loc()) } }
1954  #[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(MechError2::new(CannotConvertToTypeError { target_type: "f64" }, None).with_compiler_loc()) } }
1955  #[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(MechError2::new(CannotConvertToTypeError { target_type: "f32" }, None).with_compiler_loc()) } }
1956  #[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(MechError2::new(CannotConvertToTypeError { target_type: "u8" }, None).with_compiler_loc()) } }
1957  #[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(MechError2::new(CannotConvertToTypeError { target_type: "u16" }, None).with_compiler_loc()) } }
1958  #[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(MechError2::new(CannotConvertToTypeError { target_type: "u32" }, None).with_compiler_loc()) } }
1959  #[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(MechError2::new(CannotConvertToTypeError { target_type: "u64" }, None).with_compiler_loc()) } }
1960  #[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(MechError2::new(CannotConvertToTypeError { target_type: "u128" }, None).with_compiler_loc()) } }
1961  #[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(MechError2::new(CannotConvertToTypeError { target_type: "i8" }, None).with_compiler_loc()) } }
1962  #[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(MechError2::new(CannotConvertToTypeError { target_type: "i16" }, None).with_compiler_loc()) } }
1963  #[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(MechError2::new(CannotConvertToTypeError { target_type: "i32" }, None).with_compiler_loc()) } }
1964  #[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(MechError2::new(CannotConvertToTypeError { target_type: "i64" }, None).with_compiler_loc()) } }
1965  #[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(MechError2::new(CannotConvertToTypeError { target_type: "i128" }, None).with_compiler_loc()) } }
1966  #[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(MechError2::new(CannotConvertToTypeError { target_type: "string" }, None).with_compiler_loc()) } }
1967  #[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(MechError2::new(CannotConvertToTypeError { target_type: "r64" }, None).with_compiler_loc()) } }
1968  #[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(MechError2::new(CannotConvertToTypeError { target_type: "c64" }, None).with_compiler_loc()) } }
1969
1970  pub fn as_vecusize(&self) -> MResult<Vec<usize>> {
1971    match self {
1972      #[cfg(feature = "u8")]
1973      Value::U8(v) => Ok(vec![*v.borrow() as usize]),
1974      #[cfg(feature = "u16")]
1975      Value::U16(v) => Ok(vec![*v.borrow() as usize]),
1976      #[cfg(feature = "u32")]
1977      Value::U32(v) => Ok(vec![*v.borrow() as usize]),
1978      #[cfg(feature = "u64")]
1979      Value::U64(v) => Ok(vec![*v.borrow() as usize]),
1980      #[cfg(feature = "u128")]
1981      Value::U128(v) => Ok(vec![*v.borrow() as usize]),
1982      #[cfg(feature = "i8")]
1983      Value::I8(v) => Ok(vec![*v.borrow() as usize]),
1984      #[cfg(feature = "i16")]
1985      Value::I16(v) => Ok(vec![*v.borrow() as usize]),
1986      #[cfg(feature = "i32")]
1987      Value::I32(v) => Ok(vec![*v.borrow() as usize]),
1988      #[cfg(feature = "i64")]
1989      Value::I64(v) => Ok(vec![*v.borrow() as usize]),
1990      #[cfg(feature = "i128")]
1991      Value::I128(v) => Ok(vec![*v.borrow() as usize]),
1992      #[cfg(feature = "f32")]
1993      Value::F32(v) => Ok(vec![(*v.borrow()) as usize]),
1994      #[cfg(feature = "f64")]
1995      Value::F64(v) => Ok(vec![(*v.borrow()) as usize]),
1996      #[cfg(feature = "matrix")]
1997      Value::MatrixIndex(v) => Ok(v.as_vec()),
1998      #[cfg(all(feature = "matrix", feature = "f64"))]
1999      Value::MatrixF64(v) => Ok(v.as_vec().iter().map(|x| (*x) as usize).collect::<Vec<usize>>()),
2000      #[cfg(all(feature = "matrix", feature = "f32"))]
2001      Value::MatrixF32(v) => Ok(v.as_vec().iter().map(|x| (*x) as usize).collect::<Vec<usize>>()),
2002      #[cfg(all(feature = "matrix", feature = "u8"))]
2003      Value::MatrixU8(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
2004      #[cfg(all(feature = "matrix", feature = "u16"))]  
2005      Value::MatrixU16(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
2006      #[cfg(all(feature = "matrix", feature = "u32"))]
2007      Value::MatrixU32(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
2008      #[cfg(all(feature = "matrix", feature = "u64"))]
2009      Value::MatrixU64(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
2010      #[cfg(all(feature = "matrix", feature = "u128"))]
2011      Value::MatrixU128(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
2012      #[cfg(all(feature = "matrix", feature = "i8"))]
2013      Value::MatrixI8(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
2014      #[cfg(all(feature = "matrix", feature = "i16"))]
2015      Value::MatrixI16(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
2016      #[cfg(all(feature = "matrix", feature = "i32"))]
2017      Value::MatrixI32(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
2018      #[cfg(all(feature = "matrix", feature = "i128"))]
2019      Value::MatrixI128(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
2020      #[cfg(all(feature = "matrix", feature = "i64"))]
2021      Value::MatrixI64(v) => Ok(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
2022      #[cfg(all(feature = "matrix", feature = "bool"))]
2023      Value::MatrixBool(_) =>
2024        Err(MechError2::new(
2025          CannotConvertToTypeError { target_type: "[usize]" },
2026          None
2027        ).with_compiler_loc()),
2028      #[cfg(any(feature = "bool", feature = "[usize]"))]
2029      Value::Bool(_) =>
2030        Err(MechError2::new(
2031          CannotConvertToTypeError { target_type: "[usize]" },
2032          None
2033        ).with_compiler_loc()),
2034      Value::MutableReference(x) => x.borrow().as_vecusize(),
2035      _ =>
2036        Err(MechError2::new(
2037          CannotConvertToTypeError { target_type: "[usize]" },
2038          None
2039        ).with_compiler_loc()),
2040    }
2041  }
2042
2043
2044    pub fn as_index(&self) -> MResult<Value> {
2045    match self.as_usize() {      
2046      Ok(ix) => Ok(Value::Index(Ref::new(ix))),
2047      #[cfg(feature = "matrix")]
2048      Err(_) => match self.as_vecusize() {
2049        #[cfg(feature = "matrix")]
2050        Ok(x) => {
2051          let shape = self.shape();
2052          let out = Value::MatrixIndex(usize::to_matrix(x, shape[0] * shape[1],1 ));
2053          Ok(out)
2054        },
2055        #[cfg(all(feature = "matrix", feature = "bool"))]
2056        Err(_) => match self.as_vecbool() {
2057          Ok(x) => {
2058            let shape = self.shape();
2059            let out = match (shape[0], shape[1]) {
2060              (1,1) => Value::Bool(Ref::new(x[0])),
2061              #[cfg(all(feature = "vectord", feature = "bool"))]
2062              (1,n) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
2063              #[cfg(all(feature = "vectord", feature = "bool"))]
2064              (m,1) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
2065              #[cfg(all(feature = "vectord", feature = "bool"))]
2066              (m,n) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
2067              _ => todo!(),
2068            };
2069            Ok(out)
2070          }
2071          Err(_) => match self.as_bool() {
2072            Ok(x) => Ok(Value::Bool(x)),
2073            Err(_) => Err(MechError2::new(
2074              CannotConvertToTypeError { target_type: "ix" },
2075              None
2076            ).with_compiler_loc()),
2077          }
2078        }
2079        x => Err(MechError2::new(
2080          CannotConvertToTypeError { target_type: "ix" },
2081          None
2082        ).with_compiler_loc()),
2083      }
2084      _ => todo!(),
2085    }
2086  }
2087
2088  pub fn as_usize(&self) -> MResult<usize> {
2089    match self {      
2090      Value::Index(v) => Ok(*v.borrow()),
2091      #[cfg(feature = "u8")]
2092      Value::U8(v) => Ok(*v.borrow() as usize),
2093      #[cfg(feature = "u16")]
2094      Value::U16(v) => Ok(*v.borrow() as usize),
2095      #[cfg(feature = "u32")]
2096      Value::U32(v) => Ok(*v.borrow() as usize),
2097      #[cfg(feature = "u64")]
2098      Value::U64(v) => Ok(*v.borrow() as usize),
2099      #[cfg(feature = "u128")]
2100      Value::U128(v) => Ok(*v.borrow() as usize),
2101      #[cfg(feature = "i8")]
2102      Value::I8(v) => Ok(*v.borrow() as usize),
2103      #[cfg(feature = "i16")]
2104      Value::I16(v) => Ok(*v.borrow() as usize),
2105      #[cfg(feature = "i32")]
2106      Value::I32(v) => Ok(*v.borrow() as usize),
2107      #[cfg(feature = "i64")]
2108      Value::I64(v) => Ok(*v.borrow() as usize),
2109      #[cfg(feature = "i128")]
2110      Value::I128(v) => Ok(*v.borrow() as usize),
2111      #[cfg(feature = "f32")]
2112      Value::F32(v) => Ok((*v.borrow()) as usize),
2113      #[cfg(feature = "f64")]
2114      Value::F64(v) => Ok((*v.borrow()) as usize),
2115      Value::MutableReference(v) => v.borrow().as_usize(),
2116      _ =>
2117        Err(
2118          MechError2::new(
2119            CannotConvertToTypeError { target_type: "usize" },
2120            None
2121          ).with_compiler_loc()
2122        ),
2123    }
2124  }
2125
2126  #[cfg(feature = "u8")]
2127  pub fn expect_u8(&self) -> MResult<Ref<u8>> {
2128    match self {
2129      Value::U8(v) => Ok(v.clone()),
2130      Value::MutableReference(v) => v.borrow().expect_u8(),
2131      _ =>
2132        Err(
2133          MechError2::new(
2134            CannotConvertToTypeError { target_type: "u8" },
2135            None
2136          ).with_compiler_loc()
2137        ),
2138    }
2139  }
2140
2141  #[cfg(feature = "f64")]
2142  pub fn expect_f64(&self) -> MResult<Ref<f64>> {
2143    match self {
2144      Value::F64(v) => Ok(v.clone()),
2145      Value::MutableReference(v) => v.borrow().expect_f64(),
2146      _ =>
2147        Err(
2148          MechError2::new(
2149            CannotConvertToTypeError { target_type: "f64" },
2150            None
2151          ).with_compiler_loc()
2152        ),
2153    }
2154  }
2155
2156}
2157
2158#[cfg(feature = "pretty_print")]
2159impl PrettyPrint for Value {
2160  fn pretty_print(&self) -> String {
2161    let mut builder = Builder::default();
2162    match self {
2163      #[cfg(feature = "u8")]
2164      Value::U8(x)   => {builder.push_record(vec![format!("{}",x.borrow())]);},
2165      #[cfg(feature = "u16")]
2166      Value::U16(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2167      #[cfg(feature = "u32")]
2168      Value::U32(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2169      #[cfg(feature = "u64")]
2170      Value::U64(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2171      #[cfg(feature = "u128")]
2172      Value::U128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2173      #[cfg(feature = "i8")]
2174      Value::I8(x)   => {builder.push_record(vec![format!("{}",x.borrow())]);},
2175      #[cfg(feature = "i16")]
2176      Value::I16(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2177      #[cfg(feature = "i32")]
2178      Value::I32(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2179      #[cfg(feature = "i64")]
2180      Value::I64(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2181      #[cfg(feature = "i128")]
2182      Value::I128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2183      #[cfg(feature = "f32")]
2184      Value::F32(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2185      #[cfg(feature = "f64")]
2186      Value::F64(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2187      #[cfg(any(feature = "bool", feature = "variable_define"))]
2188      Value::Bool(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2189      #[cfg(feature = "complex")]
2190      Value::C64(x) => {builder.push_record(vec![x.borrow().pretty_print()]);},
2191      #[cfg(feature = "rational")]
2192      Value::R64(x) => {builder.push_record(vec![format!("{}",x.borrow().pretty_print())]);},
2193      #[cfg(feature = "atom")]
2194      Value::Atom(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2195      #[cfg(feature = "set")]
2196      Value::Set(x)  => {return x.borrow().pretty_print();}
2197      #[cfg(feature = "map")]
2198      Value::Map(x)  => {return x.borrow().pretty_print();}
2199      #[cfg(any(feature = "string", feature = "variable_define"))]
2200      Value::String(x) => {return format!("\"{}\"",x.borrow().clone());},
2201      #[cfg(feature = "table")]
2202      Value::Table(x)  => {return x.borrow().pretty_print();},
2203      #[cfg(feature = "tuple")]
2204      Value::Tuple(x)  => {return x.borrow().pretty_print();},
2205      #[cfg(feature = "record")]
2206      Value::Record(x) => {return x.borrow().pretty_print();},
2207      #[cfg(feature = "enum")]
2208      Value::Enum(x) => {return x.borrow().pretty_print();},
2209      #[cfg(feature = "matrix")]
2210      Value::MatrixIndex(x) => {return x.pretty_print();},
2211      #[cfg(all(feature = "matrix", feature = "bool"))]
2212      Value::MatrixBool(x) => {return x.pretty_print();},
2213      #[cfg(all(feature = "matrix", feature = "u8"))]
2214      Value::MatrixU8(x)   => {return x.pretty_print();},
2215      #[cfg(all(feature = "matrix", feature = "u16"))]
2216      Value::MatrixU16(x)  => {return x.pretty_print();},
2217      #[cfg(all(feature = "matrix", feature = "u32"))]
2218      Value::MatrixU32(x)  => {return x.pretty_print();},
2219      #[cfg(all(feature = "matrix", feature = "u64"))]
2220      Value::MatrixU64(x)  => {return x.pretty_print();},
2221      #[cfg(all(feature = "matrix", feature = "u128"))]
2222      Value::MatrixU128(x) => {return x.pretty_print();},
2223      #[cfg(all(feature = "matrix", feature = "i8"))]
2224      Value::MatrixI8(x)   => {return x.pretty_print();},
2225      #[cfg(all(feature = "matrix", feature = "i16"))]
2226      Value::MatrixI16(x)  => {return x.pretty_print();},
2227      #[cfg(all(feature = "matrix", feature = "i32"))]
2228      Value::MatrixI32(x)  => {return x.pretty_print();},
2229      #[cfg(all(feature = "matrix", feature = "i64"))]
2230      Value::MatrixI64(x)  => {return x.pretty_print();},
2231      #[cfg(all(feature = "matrix", feature = "i128"))]
2232      Value::MatrixI128(x) => {return x.pretty_print();},
2233      #[cfg(all(feature = "matrix", feature = "f32"))]
2234      Value::MatrixF32(x)  => {return x.pretty_print();},
2235      #[cfg(all(feature = "matrix", feature = "f64"))]
2236      Value::MatrixF64(x)  => {return x.pretty_print();},
2237      #[cfg(all(feature = "matrix", feature = "any"))]
2238      Value::MatrixValue(x)  => {return x.pretty_print();},
2239      #[cfg(all(feature = "matrix", feature = "string"))]
2240      Value::MatrixString(x)  => {return x.pretty_print();},
2241      #[cfg(all(feature = "matrix", feature = "rational"))]
2242      Value::MatrixR64(x) => {return x.pretty_print();},
2243      #[cfg(all(feature = "matrix", feature = "complex"))]
2244      Value::MatrixC64(x) => {return x.pretty_print();},
2245      Value::Index(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2246      Value::MutableReference(x) => {return x.borrow().pretty_print();},
2247      Value::Empty => builder.push_record(vec!["_"]),
2248      Value::IndexAll => builder.push_record(vec![":"]),
2249      Value::Id(x) => builder.push_record(vec![format!("{}",humanize(x))]),
2250      Value::Kind(x) => builder.push_record(vec![format!("<{}>",x)]),
2251      x => {
2252        todo!("{x:#?}");
2253      },
2254    };
2255    let value_style = Style::empty()
2256      .top(' ')
2257      .left(' ')
2258      .right(' ')
2259      .bottom(' ')
2260      .vertical(' ')
2261      .intersection_bottom(' ')
2262      .corner_top_left(' ')
2263      .corner_top_right(' ')
2264      .corner_bottom_left(' ')
2265      .corner_bottom_right(' ');
2266    let mut table = builder.build();
2267    table.with(value_style);
2268    format!("{table}")
2269  }
2270}
2271
2272
2273pub trait ToIndex {
2274  fn to_index(&self) -> Value;
2275}
2276
2277#[cfg(feature = "matrix")]
2278impl ToIndex for Ref<Vec<i64>> { fn to_index(&self) -> Value { (*self.borrow()).iter().map(|x| *x as usize).collect::<Vec<usize>>().to_value() } }
2279
2280pub trait ToValue {
2281  fn to_value(&self) -> Value;
2282}
2283
2284#[cfg(feature = "matrix")]
2285impl ToValue for Vec<usize> {
2286  fn to_value(&self) -> Value {
2287    match self.len() {
2288      1 => Value::Index(Ref::new(self[0].clone())),
2289      #[cfg(feature = "vector2")]
2290      2 => Value::MatrixIndex(Matrix::Vector2(Ref::new(Vector2::from_vec(self.clone())))),
2291      #[cfg(feature = "vector3")]
2292      3 => Value::MatrixIndex(Matrix::Vector3(Ref::new(Vector3::from_vec(self.clone())))),
2293      #[cfg(feature = "vector4")]
2294      4 => Value::MatrixIndex(Matrix::Vector4(Ref::new(Vector4::from_vec(self.clone())))),
2295      #[cfg(feature = "vectord")]
2296      n => Value::MatrixIndex(Matrix::DVector(Ref::new(DVector::from_vec(self.clone())))),
2297      _ => todo!(),
2298    }
2299  }
2300}
2301
2302impl ToValue for Ref<usize>  { fn to_value(&self) -> Value { Value::Index(self.clone())  } }
2303#[cfg(feature = "u8")]
2304impl ToValue for Ref<u8>     { fn to_value(&self) -> Value { Value::U8(self.clone())     } }
2305#[cfg(feature = "u16")]
2306impl ToValue for Ref<u16>    { fn to_value(&self) -> Value { Value::U16(self.clone())    } }
2307#[cfg(feature = "u32")]
2308impl ToValue for Ref<u32>    { fn to_value(&self) -> Value { Value::U32(self.clone())    } }
2309#[cfg(feature = "u64")]
2310impl ToValue for Ref<u64>    { fn to_value(&self) -> Value { Value::U64(self.clone())    } }
2311#[cfg(feature = "u128")]
2312impl ToValue for Ref<u128>   { fn to_value(&self) -> Value { Value::U128(self.clone())   } }
2313#[cfg(feature = "i8")]
2314impl ToValue for Ref<i8>     { fn to_value(&self) -> Value { Value::I8(self.clone())     } }
2315#[cfg(feature = "i16")]
2316impl ToValue for Ref<i16>    { fn to_value(&self) -> Value { Value::I16(self.clone())    } }
2317#[cfg(feature = "i32")]
2318impl ToValue for Ref<i32>    { fn to_value(&self) -> Value { Value::I32(self.clone())    } }
2319#[cfg(feature = "i64")]
2320impl ToValue for Ref<i64>    { fn to_value(&self) -> Value { Value::I64(self.clone())    } }
2321#[cfg(feature = "i128")]
2322impl ToValue for Ref<i128>   { fn to_value(&self) -> Value { Value::I128(self.clone())   } }
2323#[cfg(feature = "f32")]
2324impl ToValue for Ref<f32>    { fn to_value(&self) -> Value { Value::F32(self.clone())    } }
2325#[cfg(feature = "f64")]
2326impl ToValue for Ref<f64>    { fn to_value(&self) -> Value { Value::F64(self.clone())    } }
2327#[cfg(any(feature = "bool", feature = "variable_define"))]
2328impl ToValue for Ref<bool>   { fn to_value(&self) -> Value { Value::Bool(self.clone())   } }
2329#[cfg(any(feature = "string", feature = "variable_define"))]
2330impl ToValue for Ref<String> { fn to_value(&self) -> Value { Value::String(self.clone()) } }
2331#[cfg(feature = "rational")]
2332impl ToValue for Ref<R64> { fn to_value(&self) -> Value { Value::R64(self.clone()) } }
2333#[cfg(feature = "complex")]
2334impl ToValue for Ref<C64> { fn to_value(&self) -> Value { Value::C64(self.clone()) } }
2335#[cfg(feature = "atom")]
2336impl ToValue for Ref<MechAtom> { fn to_value(&self) -> Value { Value::Atom(self.clone()) } }
2337
2338impl ToValue for Ref<Value> { fn to_value(&self) -> Value { (*self.borrow()).clone() } }
2339
2340#[cfg(feature = "u8")]
2341impl From<u8> for Value {
2342  fn from(val: u8) -> Self {
2343    Value::U8(Ref::new(val))
2344  }
2345}
2346
2347#[cfg(feature = "u16")]
2348impl From<u16> for Value {
2349  fn from(val: u16) -> Self {
2350    Value::U16(Ref::new(val))
2351  }
2352}
2353
2354#[cfg(feature = "u32")]
2355impl From<u32> for Value {
2356  fn from(val: u32) -> Self {
2357    Value::U32(Ref::new(val))
2358  }
2359}
2360
2361#[cfg(feature = "u64")]
2362impl From<u64> for Value {
2363  fn from(val: u64) -> Self {
2364    Value::U64(Ref::new(val))
2365  }
2366}
2367
2368#[cfg(feature = "u128")]
2369impl From<u128> for Value {
2370  fn from(val: u128) -> Self {
2371    Value::U128(Ref::new(val))
2372  }
2373}
2374
2375#[cfg(feature = "i8")]
2376impl From<i8> for Value {
2377  fn from(val: i8) -> Self {
2378    Value::I8(Ref::new(val))
2379  }
2380}
2381
2382#[cfg(feature = "i16")]
2383impl From<i16> for Value {
2384  fn from(val: i16) -> Self {
2385    Value::I16(Ref::new(val))
2386  }
2387}
2388
2389#[cfg(feature = "i32")]
2390impl From<i32> for Value {
2391  fn from(val: i32) -> Self {
2392    Value::I32(Ref::new(val))
2393  }
2394}
2395
2396#[cfg(feature = "i64")]
2397impl From<i64> for Value {
2398  fn from(val: i64) -> Self {
2399    Value::I64(Ref::new(val))
2400  }
2401}
2402
2403#[cfg(feature = "i128")]
2404impl From<i128> for Value {
2405  fn from(val: i128) -> Self {
2406    Value::I128(Ref::new(val))
2407  }
2408}
2409
2410#[cfg(feature = "f32")]
2411impl From<f32> for Value {
2412  fn from(val: f32) -> Self {
2413    Value::F32(Ref::new(val))
2414  }
2415}
2416
2417#[cfg(feature = "f64")]
2418impl From<f64> for Value {
2419  fn from(val: f64) -> Self {
2420    Value::F64(Ref::new(val))
2421  }
2422}
2423
2424#[cfg(any(feature = "bool", feature = "variable_define"))]
2425impl From<bool> for Value {
2426  fn from(val: bool) -> Self {
2427    Value::Bool(Ref::new(val))
2428  }
2429}
2430
2431#[cfg(any(feature = "string", feature = "variable_define"))]
2432impl From<String> for Value {
2433  fn from(val: String) -> Self {
2434    Value::String(Ref::new(val))
2435  }
2436}
2437
2438#[cfg(feature = "rational")]
2439impl From<R64> for Value {
2440  fn from(val: R64) -> Self {
2441    Value::R64(Ref::new(val))
2442  }
2443}
2444
2445
2446pub trait ToUsize {
2447  fn to_usize(&self) -> usize;
2448}
2449
2450macro_rules! impl_to_usize_for {
2451  ($t:ty) => {
2452    impl ToUsize for $t {
2453      fn to_usize(&self) -> usize {
2454        #[allow(unused_comparisons)]
2455        if *self < 0 as $t {
2456          panic!("Cannot convert negative number to usize");
2457        }
2458        *self as usize
2459      }
2460    }
2461  };
2462}
2463
2464#[cfg(feature = "u8")]
2465impl_to_usize_for!(u8);
2466#[cfg(feature = "u16")]
2467impl_to_usize_for!(u16);
2468#[cfg(feature = "u32")]
2469impl_to_usize_for!(u32);
2470#[cfg(feature = "u64")]
2471impl_to_usize_for!(u64);
2472#[cfg(feature = "u128")]
2473impl_to_usize_for!(u128);
2474impl_to_usize_for!(usize);
2475
2476#[cfg(feature = "i8")]
2477impl_to_usize_for!(i8);
2478#[cfg(feature = "i16")]
2479impl_to_usize_for!(i16);
2480#[cfg(feature = "i32")]
2481impl_to_usize_for!(i32);
2482#[cfg(feature = "i64")]
2483impl_to_usize_for!(i64);
2484#[cfg(feature = "i128")]
2485impl_to_usize_for!(i128);
2486
2487#[cfg(feature = "f64")]
2488impl_to_usize_for!(f64);
2489#[cfg(feature = "f32")]
2490impl_to_usize_for!(f32);
2491
2492#[cfg(feature = "table")]
2493impl ToValue for Ref<MechTable> {
2494  fn to_value(&self) -> Value {
2495    Value::Table(self.clone())
2496  }
2497}
2498
2499#[cfg(feature = "set")]
2500impl ToValue for Ref<MechSet> {
2501  fn to_value(&self) -> Value {
2502    Value::Set(self.clone())
2503  }
2504}
2505
2506#[cfg(feature = "map")]
2507impl ToValue for Ref<MechMap> {
2508  fn to_value(&self) -> Value {
2509    Value::Map(self.clone())
2510  }
2511}
2512
2513#[cfg(feature = "tuple")]
2514impl ToValue for Ref<MechTuple> {
2515  fn to_value(&self) -> Value {
2516    Value::Tuple(self.clone())
2517  }
2518}
2519
2520#[cfg(feature = "record")]
2521impl ToValue for Ref<MechRecord> {
2522  fn to_value(&self) -> Value {
2523    Value::Record(self.clone())
2524  }
2525}
2526
2527// Errors
2528
2529#[derive(Debug, Clone)]
2530pub struct UnhandledFunctionArgumentKindError;
2531
2532impl MechErrorKind2 for UnhandledFunctionArgumentKindError {
2533  fn name(&self) -> &str { "UnhandledFunctionArgumentKind" }
2534  fn message(&self) -> String {
2535    "Value kind is not valid for this function.".to_string()
2536  }
2537}
2538
2539#[derive(Debug, Clone)]
2540pub struct CannotConvertToTypeError {
2541  pub target_type: &'static str,
2542}
2543
2544impl MechErrorKind2 for CannotConvertToTypeError {
2545  fn name(&self) -> &str { "CannotConvertToType" }
2546  fn message(&self) -> String {
2547    format!("Cannot convert to {}", self.target_type)
2548  }
2549}