mech_interpreter/stdlib/assign/
mod.rs

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// ----------------------------------------------------------------------------
19// Assign 
20// ----------------------------------------------------------------------------
21
22// x = 1 ----------------------------------------------------------------------
23
24#[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
157// x += y ----------------------------------------------------------------------
158
159pub 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}