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