1#[macro_use]
2use crate::stdlib::*;
3
4#[cfg(feature = "matrix")]
5pub mod matrix;
6#[cfg(feature = "record")]
7pub mod record;
8#[cfg(feature = "table")]
9pub mod table;
10
11#[cfg(feature = "matrix")]
12pub use self::matrix::*;
13#[cfg(feature = "record")]
14pub use self::record::*;
15#[cfg(feature = "table")]
16pub use self::table::*;
17
18#[derive(Debug)]
25struct Assign<T> {
26 sink: Ref<T>,
27 source: Ref<T>,
28}
29impl<T> MechFunctionImpl for Assign<T>
30where
31 T: Clone + Debug,
32 Ref<T>: ToValue
33{
34 fn solve(&self) {
35 let source_ptr = self.source.as_ptr();
36 let sink_ptr = self.sink.as_mut_ptr();
37 unsafe {
38 *sink_ptr = (*source_ptr).clone();
39 }
40 }
41 fn out(&self) -> Value { self.sink.to_value() }
42 fn to_string(&self) -> String { format!("{:#?}", self) }
43}
44#[cfg(feature = "compiler")]
45impl<T> MechFunctionCompiler for Assign<T> {
46 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
47 todo!();
48 }
49}
50
51#[macro_export]
52macro_rules! impl_assign_value_match_arms {
53 ($arg:expr,$($value_kind:ident, $feature:tt);+ $(;)?) => {
54 paste::paste! {
55 match $arg {
56 $(
57 #[cfg(feature = $feature)]
58 (Value::$value_kind(sink), Value::$value_kind(source)) => Ok(Box::new(Assign{ sink: sink.clone(), source: source.clone() })),
59 #[cfg(all(feature = $feature, feature = "matrix1"))]
60 (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix1(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
61 #[cfg(all(feature = $feature, feature = "matrix2"))]
62 (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix2(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
63 #[cfg(all(feature = $feature, feature = "matrix2x3"))]
64 (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix2x3(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
65 #[cfg(all(feature = $feature, feature = "matrix3x2"))]
66 (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix3x2(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
67 #[cfg(all(feature = $feature, feature = "matrix3"))]
68 (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix3(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
69 #[cfg(all(feature = $feature, feature = "matrix4"))]
70 (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix4(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
71 #[cfg(all(feature = $feature, feature = "matrixd"))]
72 (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), Value::[<Matrix $value_kind>](Matrix::DMatrix(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
73 #[cfg(all(feature = $feature, feature = "vector2"))]
74 (Value::[<Matrix $value_kind>](Matrix::Vector2(sink)), Value::[<Matrix $value_kind>](Matrix::Vector2(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
75 #[cfg(all(feature = $feature, feature = "vector3"))]
76 (Value::[<Matrix $value_kind>](Matrix::Vector3(sink)), Value::[<Matrix $value_kind>](Matrix::Vector3(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
77 #[cfg(all(feature = $feature, feature = "vector4"))]
78 (Value::[<Matrix $value_kind>](Matrix::Vector4(sink)), Value::[<Matrix $value_kind>](Matrix::Vector4(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
79 #[cfg(all(feature = $feature, feature = "vectord"))]
80 (Value::[<Matrix $value_kind>](Matrix::DVector(sink)), Value::[<Matrix $value_kind>](Matrix::DVector(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
81 #[cfg(all(feature = $feature, feature = "row_vector2"))]
82 (Value::[<Matrix $value_kind>](Matrix::RowVector2(sink)), Value::[<Matrix $value_kind>](Matrix::RowVector2(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
83 #[cfg(all(feature = $feature, feature = "row_vector3"))]
84 (Value::[<Matrix $value_kind>](Matrix::RowVector3(sink)), Value::[<Matrix $value_kind>](Matrix::RowVector3(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
85 #[cfg(all(feature = $feature, feature = "row_vector4"))]
86 (Value::[<Matrix $value_kind>](Matrix::RowVector4(sink)), Value::[<Matrix $value_kind>](Matrix::RowVector4(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
87 #[cfg(all(feature = $feature, feature = "row_vectord"))]
88 (Value::[<Matrix $value_kind>](Matrix::RowDVector(sink)), Value::[<Matrix $value_kind>](Matrix::RowDVector(source))) => Ok(Box::new(Assign{sink: sink.clone(), source: source.clone()})),
89 )+
90 x => Err(MechError {file: file!().to_string(),tokens: vec![],msg: format!("Unhandled args {:?}", x),id: line!(),kind: MechErrorKind::UnhandledFunctionArgumentKind,}),
91 }
92 }
93 };
94}
95
96fn assign_value_fxn(sink: Value, source: Value) -> Result<Box<dyn MechFunction>, MechError> {
97 impl_assign_value_match_arms!(
98 (sink, source),
99 Bool, "bool";
100 String, "string";
101 U8, "u8";
102 U16, "u16";
103 U32, "u32";
104 U64, "u64";
105 U128, "u128";
106 I8, "i8";
107 I16, "i16";
108 I32, "i32";
109 I64, "i64";
110 U128, "u128";
111 F32, "f32";
112 F64, "f64";
113 RationalNumber, "rational";
114 ComplexNumber, "complex";
115 )
116}
117
118pub struct AssignValue {}
119impl NativeFunctionCompiler for AssignValue {
120 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
121 if arguments.len() <= 1 {
122 return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
123 }
124 let sink = arguments[0].clone();
125 let source = arguments[1].clone();
126 match assign_value_fxn(sink.clone(),source.clone()) {
127 Ok(fxn) => Ok(fxn),
128 Err(x) => {
129 match (sink,source) {
130 (Value::MutableReference(sink),Value::MutableReference(source)) => { assign_value_fxn(sink.borrow().clone(),source.borrow().clone()) },
131 (sink,Value::MutableReference(source)) => { assign_value_fxn(sink.clone(),source.borrow().clone()) },
132 (Value::MutableReference(sink),source) => { assign_value_fxn(sink.borrow().clone(),source.clone()) },
133 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
134 }
135 }
136 }
137 }
138}
139
140pub struct AssignColumn {}
141impl NativeFunctionCompiler for AssignColumn {
142 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
143 if arguments.len() < 1 {
144 return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
145 }
146 let src = &arguments[0];
147 match src.kind().deref_kind() {
148 #[cfg(feature = "table")]
149 ValueKind::Table(_,_) => AssignTableColumn{}.compile(&arguments),
150 #[cfg(feature = "record")]
151 ValueKind::Record(_) => AssignRecordColumn{}.compile(&arguments),
152 _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}),
153 }
154 }
155}
156
157pub fn add_assign_value_fxn(sink: Value, source: Value) -> MResult<Box<dyn MechFunction>> {
160 match sink {
161 #[cfg(feature = "table")]
162 Value::Table(_) => add_assign_table_fxn(sink, source),
163 #[cfg(feature = "add_assign")]
164 _ => add_assign_math_fxn(sink, source),
165 _ => Err(MechError{file: file!().to_string(),tokens: vec![],msg: format!("Unhandled args {:?}, {:?}", sink, source),id: line!(),kind: MechErrorKind::UnhandledFunctionArgumentKind,}),
166 }
167}
168
169pub struct AddAssignValue {}
170impl NativeFunctionCompiler for AddAssignValue {
171 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
172 if arguments.len() <= 1 {
173 return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
174 }
175 let sink = arguments[0].clone();
176 let source = arguments[1].clone();
177 match add_assign_value_fxn(sink.clone(),source.clone()) {
178 Ok(fxn) => Ok(fxn),
179 Err(x) => {
180 match (sink,source) {
181 (Value::MutableReference(sink),Value::MutableReference(source)) => { add_assign_value_fxn(sink.borrow().clone(),source.borrow().clone()) },
182 (sink,Value::MutableReference(source)) => { add_assign_value_fxn(sink.clone(),source.borrow().clone()) },
183 (Value::MutableReference(sink),source) => { add_assign_value_fxn(sink.borrow().clone(),source.clone()) },
184 x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
185 }
186 }
187 }
188 }
189}