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_in:ident, $vector_size_out:ident, $out_type:ty) => {
12    #[derive(Debug)]
13    struct $fxn_name {
14      source: Ref<$vector_size_in<$out_type>>,
15      sink: Ref<$vector_size_out<Value>>,
16    }
17    impl MechFunctionImpl for $fxn_name {
18      fn solve(&self) {
19        let source_ptr = self.source.as_ptr();
20        let sink_ptr = self.sink.as_mut_ptr();
21        unsafe { 
22          for i in 0..(*source_ptr).len() {
23            paste! {
24              (&mut (*sink_ptr))[i] = Value::[<$out_type:camel>](Ref::new((*source_ptr).index(i).clone()));
25            }
26          }
27        }
28      }
29      fn out(&self) -> Value { Value::MatrixValue(Matrix::$vector_size_out(self.sink.clone())) }
30      fn to_string(&self) -> String { format!("{:#?}", self) }
31    }
32    #[cfg(feature = "compiler")]
33    impl MechFunctionCompiler for $fxn_name {
34      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
35        todo!();
36      }
37    }
38  }
39}
40
41macro_rules! impl_col_set_fxn_shapes {
42  ($type:ident) => {
43    paste!{
44      #[cfg(feature = "matrix1")]
45      impl_col_set_fxn!([<TableSetCol $type:camel M1>], Matrix1, Matrix1, $type);
46      #[cfg(feature = "vector2")]
47      impl_col_set_fxn!([<TableSetCol $type:camel V2>], Vector2, Vector2, $type);
48      #[cfg(feature = "vector3")]
49      impl_col_set_fxn!([<TableSetCol $type:camel V3>], Vector3, Vector3, $type);
50      #[cfg(feature = "vector4")]
51      impl_col_set_fxn!([<TableSetCol $type:camel V4>], Vector4, Vector4, $type);
52      #[cfg(feature = "vectord")]
53      impl_col_set_fxn!([<TableSetCol $type:camel VD>], DVector, DVector, $type);
54      #[cfg(all(feature = "vectord", feature = "vector4"))]
55      impl_col_set_fxn!([<TableSetCol $type:camel VDV4>], Vector4, DVector, $type);
56      #[cfg(all(feature = "vectord", feature = "vector3"))]
57      impl_col_set_fxn!([<TableSetCol $type:camel VDV3>], Vector3, DVector, $type);
58      #[cfg(all(feature = "vectord", feature = "vector2"))]
59      impl_col_set_fxn!([<TableSetCol $type:camel VDV2>], Vector2, DVector, $type);
60      #[cfg(all(feature = "vectord", feature = "matrix1"))]
61      impl_col_set_fxn!([<TableSetCol $type:camel VDM1>], Matrix1, DVector, $type);
62    }
63  }
64}
65
66#[cfg(feature = "bool")]
67impl_col_set_fxn_shapes!(bool);
68#[cfg(feature = "i8")]
69impl_col_set_fxn_shapes!(i8);
70#[cfg(feature = "i16")]
71impl_col_set_fxn_shapes!(i16);
72#[cfg(feature = "i32")]
73impl_col_set_fxn_shapes!(i32);
74#[cfg(feature = "i64")]
75impl_col_set_fxn_shapes!(i64);
76#[cfg(feature = "i128")]
77impl_col_set_fxn_shapes!(i128);
78#[cfg(feature = "u8")]
79impl_col_set_fxn_shapes!(u8);
80#[cfg(feature = "u16")]
81impl_col_set_fxn_shapes!(u16);
82#[cfg(feature = "u32")]
83impl_col_set_fxn_shapes!(u32);
84#[cfg(feature = "u64")]
85impl_col_set_fxn_shapes!(u64);
86#[cfg(feature = "u128")]
87impl_col_set_fxn_shapes!(u128);
88#[cfg(feature = "f32")]
89impl_col_set_fxn_shapes!(F32);
90#[cfg(feature = "f64")]
91impl_col_set_fxn_shapes!(F64);
92#[cfg(feature = "string")]
93impl_col_set_fxn_shapes!(String);
94#[cfg(feature = "complex")]
95impl_col_set_fxn_shapes!(ComplexNumber);
96#[cfg(feature = "rational")]
97impl_col_set_fxn_shapes!(RationalNumber);
98
99macro_rules! impl_set_column_match_arms {
100  ($arg:expr, $($lhs_type:ident, $type_ident:ident, $type_feature:literal);+ $(;)?) => {
101    paste::paste! {
102      match $arg {
103        (Value::Table(tbl), source, Value::Id(k)) => {
104          let tbl_brrw = tbl.borrow();
105          match (tbl_brrw.get(&k), tbl_brrw.rows(), source) {
106            $(
107              #[cfg(all(feature = $type_feature, feature = "matrix1"))]
108              (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() })),
109              #[cfg(all(feature = $type_feature, feature = "vector2"))]
110              (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() })),
111              #[cfg(all(feature = $type_feature, feature = "vector3"))]
112              (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() })),
113              #[cfg(all(feature = $type_feature, feature = "vector4"))]
114              (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() })),
115              #[cfg(all(feature = $type_feature, feature = "vectord"))]
116              (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() })),
117              #[cfg(all(feature = $type_feature, feature = "vectord", feature = "vector4"))]
118              (Some((ValueKind::$lhs_type, Matrix::DVector(sink))), n, Value::[<Matrix $lhs_type>](Matrix::Vector4(source))) =>Ok(Box::new([<TableSetCol $lhs_type VDV4>]{ source: source.clone(), sink: sink.clone() })),
119              #[cfg(all(feature = $type_feature, feature = "vectord", feature = "vector3"))]
120              (Some((ValueKind::$lhs_type, Matrix::DVector(sink))), n, Value::[<Matrix $lhs_type>](Matrix::Vector3(source))) =>Ok(Box::new([<TableSetCol $lhs_type VDV3>]{ source: source.clone(), sink: sink.clone() })),
121              #[cfg(all(feature = $type_feature, feature = "vectord", feature = "vector2"))]
122              (Some((ValueKind::$lhs_type, Matrix::DVector(sink))), n, Value::[<Matrix $lhs_type>](Matrix::Vector2(source))) =>Ok(Box::new([<TableSetCol $lhs_type VDV2>]{ source: source.clone(), sink: sink.clone() })),
123              #[cfg(all(feature = $type_feature, feature = "vectord", feature = "matrix1"))]
124              (Some((ValueKind::$lhs_type, Matrix::DVector(sink))), n, Value::[<Matrix $lhs_type>](Matrix::Matrix1(source))) =>Ok(Box::new([<TableSetCol $lhs_type VDM1>]{ source: source.clone(), sink: sink.clone() })),
125            )+
126            x => return Err(MechError {file: file!().to_string(),tokens: vec![],msg: "".to_string(),id: line!(),kind: MechErrorKind::UndefinedField(k)}),
127          }
128        }
129        x => Err(MechError {file: file!().to_string(),tokens: vec![],msg: "".to_string(),id: line!(),kind: MechErrorKind::UnhandledFunctionArgumentKind}),
130      }
131    }
132  }
133}
134
135fn impl_set_column_fxn(sink: Value, source: Value, key: Value) -> MResult<Box<dyn MechFunction>> {
136  impl_set_column_match_arms!(
137    (sink,source,key),
138    Bool, bool, "bool";
139    I8,   i8,   "i8";
140    I16,  i16,  "i16";
141    I32,  i32,  "i32";
142    I64,  i64,  "i64";
143    I128, i128, "i128";
144    U8,   u8,   "u8";
145    U16,  u16,  "u16";
146    U32,  u32,  "u32";
147    U64,  u64,  "u64";
148    U128, u128, "u128";
149    F32,  F32,  "f32";
150    F64,  F64,  "f64";
151    String, String, "string";
152    ComplexNumber, ComplexNumber,"complex";
153    RationalNumber, RationalNumber,"rational";
154  )
155}
156
157pub struct AssignTableColumn {}
158impl NativeFunctionCompiler for AssignTableColumn {
159  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
160    if arguments.len() < 3 {
161      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
162    }
163    let sink = arguments[0].clone();
164    let source = arguments[1].clone();
165    let key = arguments[2].clone();
166    match impl_set_column_fxn(sink.clone(), source.clone(), key.clone()) {
167      Ok(fxn) => Ok(fxn),
168      Err(_) => {
169        match (&sink,&source,&key) {
170          (Value::MutableReference(sink),_,_) => { impl_set_column_fxn(sink.borrow().clone(), source.clone(), key.clone()) }
171          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
172        }
173      }
174    }
175  }
176}
177
178// table1 += table2 ------------------------------------------------------------
179
180#[derive(Debug)]
181struct TableAppendRecord {
182  sink: Ref<MechTable>,
183  source: Ref<MechRecord>,
184}
185impl MechFunctionImpl for TableAppendRecord {
186  fn solve(&self) {
187    unsafe {
188      let mut sink_ptr = (&mut *(self.sink.as_mut_ptr()));
189      let source_ptr = &(*(self.source.as_ptr()));
190      sink_ptr.append_record(source_ptr.clone());
191    }
192  }
193  fn out(&self) -> Value { Value::Table(self.sink.clone()) }
194  fn to_string(&self) -> String { format!("{:#?}", self) }
195}
196#[cfg(feature = "compiler")]
197impl MechFunctionCompiler for TableAppendRecord {
198  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
199    todo!();
200  }
201}
202
203#[derive(Debug)]
204struct TableAppendTable {
205  sink: Ref<MechTable>,
206  source: Ref<MechTable>,
207}
208impl MechFunctionImpl for TableAppendTable {
209  fn solve(&self) {
210    unsafe {
211      let mut sink_ptr = (&mut *(self.sink.as_mut_ptr()));
212      let source_ptr = &(*(self.source.as_ptr()));
213      sink_ptr.append_table(&source_ptr);
214    }
215  }
216  fn out(&self) -> Value { Value::Table(self.sink.clone()) }
217  fn to_string(&self) -> String { format!("{:#?}", self) }
218}
219#[cfg(feature = "compiler")]
220impl MechFunctionCompiler for TableAppendTable {
221  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
222    todo!();
223  }
224}
225
226pub fn add_assign_table_fxn(sink: Value, source: Value) -> Result<Box<dyn MechFunction>, MechError> {
227  match (sink.clone(),source.clone()) {
228    (Value::Table(tbl), Value::Record(rcrd)) => {
229      tbl.borrow().check_record_schema(&rcrd.borrow())?;
230      return Ok(Box::new(TableAppendRecord{ sink: tbl, source: rcrd }))
231    }
232    (Value::Table(tbl_sink), Value::Table(tbl_src)) => {
233      tbl_sink.borrow().check_table_schema(&tbl_src.borrow())?;
234      return Ok(Box::new(TableAppendTable{ sink: tbl_sink, source: tbl_src }))
235    }
236    x => return Err(MechError{file: file!().to_string(),tokens: vec![],msg: format!("Unhandled args {:?}, {:?}", sink, source),id: line!(),kind: MechErrorKind::UnhandledFunctionArgumentKind,}),
237  }
238}
239
240pub struct AddAssignTable {}
241impl NativeFunctionCompiler for AddAssignTable {
242  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
243    if arguments.len() <= 1 {
244      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
245    }
246    let sink = arguments[0].clone();
247    let source = arguments[1].clone();
248    match add_assign_table_fxn(sink.clone(),source.clone()) {
249      Ok(fxn) => Ok(fxn),
250      Err(x) => {
251        match (sink,source) {
252          (Value::MutableReference(sink),Value::MutableReference(source)) => { add_assign_table_fxn(sink.borrow().clone(),source.borrow().clone()) },
253          (sink,Value::MutableReference(source)) => { add_assign_table_fxn(sink.clone(),source.borrow().clone()) },
254          (Value::MutableReference(sink),source) => { add_assign_table_fxn(sink.borrow().clone(),source.clone()) },
255          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
256        }
257      }
258    }
259  }
260}