mech_interpreter/stdlib/assign/
table.rs

1#[macro_use]
2use crate::stdlib::*;
3use self::assign::*;
4use na::{Vector3, DVector, Vector2, Vector4, RowDVector, Matrix1, Matrix3, Matrix4, RowVector3, RowVector4, RowVector2, DMatrix, Rotation3, Matrix2x3, Matrix3x2, Matrix6, Matrix2};
5
6// x.a = 1 --------------------------------------------------------------------
7
8// Table Set ------------------------------------------------------------------
9
10macro_rules! impl_col_set_fxn {
11  ($fxn_name:ident, $vector_size:ident, $out_type:ty) => {
12    #[derive(Debug)]
13    struct $fxn_name {
14      source: Ref<$vector_size<$out_type>>,
15      sink: Ref<$vector_size<Value>>,
16    }
17    impl MechFunction for $fxn_name {
18      fn solve(&self) {
19        let source_ptr = self.source.as_ptr();
20        let sink_ptr = self.sink.as_ptr();
21        unsafe { 
22          for i in 0..(*source_ptr).len() {
23            paste! {
24              (*sink_ptr)[i] = Value::[<$out_type:camel>](new_ref((*source_ptr).index(i).clone()));
25            }
26          }
27        }
28      }
29      fn out(&self) -> Value { Value::MatrixValue(Matrix::$vector_size(self.sink.clone())) }
30      fn to_string(&self) -> String { format!("{:#?}", self) }
31    }
32  }
33}
34
35macro_rules! impl_col_set_fxn_shapes {
36  ($type:ident) => {
37    paste!{
38      impl_col_set_fxn!([<TableSetCol $type:camel M1>], Matrix1, $type);
39      impl_col_set_fxn!([<TableSetCol $type:camel V2>], Vector2, $type);
40      impl_col_set_fxn!([<TableSetCol $type:camel V3>], Vector3, $type);
41      impl_col_set_fxn!([<TableSetCol $type:camel V4>], Vector4, $type);
42      impl_col_set_fxn!([<TableSetCol $type:camel VD>], DVector, $type);
43    }
44  }
45}
46
47impl_col_set_fxn_shapes!(bool);
48impl_col_set_fxn_shapes!(i8);
49impl_col_set_fxn_shapes!(i16);
50impl_col_set_fxn_shapes!(i32);
51impl_col_set_fxn_shapes!(i64);
52impl_col_set_fxn_shapes!(i128);
53impl_col_set_fxn_shapes!(u8);
54impl_col_set_fxn_shapes!(u16);
55impl_col_set_fxn_shapes!(u32);
56impl_col_set_fxn_shapes!(u64);
57impl_col_set_fxn_shapes!(u128);
58impl_col_set_fxn_shapes!(F32);
59impl_col_set_fxn_shapes!(F64);
60
61macro_rules! impl_set_column_match_arms {
62  ($arg:expr, $($lhs_type:ident, $($default:expr),+);+ $(;)?) => {
63    paste!{
64      match $arg {
65        (Value::Record(rcrd),source,Value::Id(k)) => {
66          match (rcrd.data.get(&k),source) {
67            (Some(Value::Bool(sink)), Value::Bool(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
68            (Some(Value::I8(sink)), Value::I8(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
69            (Some(Value::I16(sink)), Value::I16(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
70            (Some(Value::I32(sink)), Value::I32(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
71            (Some(Value::I64(sink)), Value::I64(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
72            (Some(Value::I128(sink)), Value::I128(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
73            (Some(Value::U8(sink)), Value::U8(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
74            (Some(Value::U16(sink)), Value::U16(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
75            (Some(Value::U32(sink)), Value::U32(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
76            (Some(Value::U64(sink)), Value::U64(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
77            (Some(Value::U128(sink)), Value::U128(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
78            (Some(Value::F32(sink)), Value::F32(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
79            (Some(Value::F64(sink)), Value::F64(source)) => Ok(Box::new(RecordSet{sink: sink.clone(), source: source.clone()})),
80            _ => return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UndefinedField(k)}),
81          }
82        }
83        (Value::Table(tbl),source,Value::Id(k)) => {
84          let key = Value::Id(k);
85          match (tbl.get(&key),tbl.rows(),source) {
86            $(
87                (Some((ValueKind::$lhs_type,Matrix::Matrix1(sink))),1,Value::[<Matrix $lhs_type>](Matrix::Matrix1(source))) => Ok(Box::new([<TableSetCol $lhs_type M1>]{source: source.clone(), sink: sink.clone() })),
88                (Some((ValueKind::$lhs_type,Matrix::Vector2(sink))),2,Value::[<Matrix $lhs_type>](Matrix::Vector2(source))) => Ok(Box::new([<TableSetCol $lhs_type V2>]{source: source.clone(), sink: sink.clone() })),
89                (Some((ValueKind::$lhs_type,Matrix::Vector3(sink))),3,Value::[<Matrix $lhs_type>](Matrix::Vector3(source))) => Ok(Box::new([<TableSetCol $lhs_type V3>]{source: source.clone(), sink: sink.clone() })),
90                (Some((ValueKind::$lhs_type,Matrix::Vector4(sink))),4,Value::[<Matrix $lhs_type>](Matrix::Vector4(source))) => Ok(Box::new([<TableSetCol $lhs_type V4>]{source: source.clone(), sink: sink.clone() })),
91                (Some((ValueKind::$lhs_type,Matrix::DVector(sink))),n,Value::[<Matrix $lhs_type>](Matrix::DVector(source))) => Ok(Box::new([<TableSetCol $lhs_type VD>]{source: source.clone(), sink: sink.clone() })),
92            )+
93            x => return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UndefinedField(k)}),
94          }
95        }
96        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
97      }
98    }
99  }
100}
101
102fn impl_set_column_fxn(sink: Value, source: Value, key: Value) -> Result<Box<dyn MechFunction>, MechError> {
103  impl_set_column_match_arms!(
104    (sink,source,key),
105    Bool,false;
106    I8,i8::zero();
107    I16,i16::zero();
108    I32,i32::zero();
109    I64,i64::zero();
110    I128,i128::zero();
111    U8,u8::zero();
112    U16,u16::zero();
113    U32,u32::zero();
114    U64,u64::zero();
115    U128,u128::zero();
116    F32,F32::zero();
117    F64,F64::zero();
118  )
119}
120
121pub struct SetColumn {}
122impl NativeFunctionCompiler for SetColumn {
123  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
124    if arguments.len() < 3 {
125      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
126    }
127    let sink = arguments[0].clone();
128    let source = arguments[1].clone();
129    let key = arguments[2].clone();
130    match impl_set_column_fxn(sink.clone(), source.clone(), key.clone()) {
131      Ok(fxn) => Ok(fxn),
132      Err(_) => {
133        match (&sink,&source,&key) {
134          (Value::MutableReference(sink),_,_) => { impl_set_column_fxn(sink.borrow().clone(), source.clone(), key.clone()) }
135          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
136        }
137      }
138    }
139  }
140}