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
6macro_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#[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}