mech_interpreter/stdlib/assign/op_assign/
sub_assign.rs

1#[macro_use]
2use crate::stdlib::*;
3
4// Sub Assign -----------------------------------------------------------------
5
6// We will mostly use the assign macros for this
7
8#[macro_export]
9macro_rules! impl_sub_assign_match_arms {
10  ($fxn_name:ident,$macro_name:ident, $arg:expr) => {
11    paste!{
12      //VVVVVVVVV right there is where the assign macros come in.
13      [<impl_set_ $macro_name _match_arms>]!(
14        $fxn_name,
15        $arg,
16        U8, "U8";
17        U16, "U16";
18        U32, "U32";
19        U64, "U64";
20        U128, "U128";
21        I8, "I8";
22        I16, "I16";
23        I32, "I32";
24        I64, "I64";
25        U128, "U128";
26        F32, "F32"; 
27        F64, "F64" ;
28      )
29    }
30  }
31}
32
33macro_rules! impl_sub_assign_fxn {
34  ($struct_name:ident, $matrix_shape:ident, $source_matrix_shape:ty, $op:ident, $ix:ty) => {
35    #[derive(Debug)]
36    struct $struct_name<T> {
37      source: Ref<$source_matrix_shape>,
38      ixes: Ref<DVector<$ix>>,
39      sink: Ref<$matrix_shape<T>>,
40    }
41    impl<T> MechFunction for $struct_name<T>
42    where
43      T: Copy + Debug + Clone + Sync + Send + 'static +
44      Sub<Output = T> + SubAssign +
45      Zero + One +
46      PartialEq + PartialOrd,
47      Ref<$matrix_shape<T>>: ToValue
48    {
49      fn solve(&self) {
50        unsafe {
51          let ix_ptr = (*(self.ixes.as_ptr())).clone();
52          let mut sink_ptr = (&mut *(self.sink.as_ptr()));
53          let source_ptr = (*(self.source.as_ptr())).clone();
54          $op!(source_ptr,ix_ptr,sink_ptr);
55        }
56      }
57      fn out(&self) -> Value { self.sink.to_value() }
58      fn to_string(&self) -> String { format!("{:#?}", self) }
59    }};}
60
61// x = 1 ----------------------------------------------------------------------
62
63#[derive(Debug)]
64struct SubAssignVV<T> {
65  sink: Ref<T>,
66  source: Ref<T>,
67}
68impl<T> MechFunction for SubAssignVV<T> 
69where
70  T: Debug + Clone + Sync + Send + 'static +
71  Sub<Output = T> + SubAssign +
72  PartialEq + PartialOrd,
73  Ref<T>: ToValue
74{
75  fn solve(&self) {
76    let sink_ptr = self.sink.as_ptr();
77    let source_ptr = self.source.as_ptr();
78    unsafe {
79      *sink_ptr -= (*source_ptr).clone();
80    }
81  }
82  fn out(&self) -> Value { self.sink.to_value() }
83  fn to_string(&self) -> String { format!("{:#?}", self) }
84}
85
86pub struct SubAssignValue {}
87impl NativeFunctionCompiler for SubAssignValue {
88  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
89    if arguments.len() <= 1 {
90      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
91    }
92    let sink = arguments[0].clone();
93    let source = arguments[1].clone();
94    match (sink,source) {
95      (Value::U8(sink),Value::U8(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
96      (Value::U16(sink),Value::U16(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
97      (Value::U32(sink),Value::U32(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
98      (Value::U64(sink),Value::U64(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
99      (Value::U128(sink),Value::U128(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
100      (Value::I8(sink),Value::I8(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
101      (Value::I16(sink),Value::I16(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
102      (Value::I32(sink),Value::I32(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
103      (Value::I64(sink),Value::I64(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
104      (Value::I128(sink),Value::I128(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
105      (Value::F32(sink),Value::F32(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
106      (Value::F64(sink),Value::F64(source)) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
107      (Value::MatrixF64(Matrix::Matrix1(sink)),Value::MatrixF64(Matrix::Matrix1(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
108      (Value::MatrixF64(Matrix::Matrix2(sink)),Value::MatrixF64(Matrix::Matrix2(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
109      (Value::MatrixF64(Matrix::Matrix2x3(sink)),Value::MatrixF64(Matrix::Matrix2x3(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
110      (Value::MatrixF64(Matrix::Matrix3x2(sink)),Value::MatrixF64(Matrix::Matrix3x2(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
111      (Value::MatrixF64(Matrix::Matrix3(sink)),Value::MatrixF64(Matrix::Matrix3(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
112      (Value::MatrixF64(Matrix::Matrix4(sink)),Value::MatrixF64(Matrix::Matrix4(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
113      (Value::MatrixF64(Matrix::DMatrix(sink)),Value::MatrixF64(Matrix::DMatrix(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
114      (Value::MatrixF64(Matrix::Vector2(sink)),Value::MatrixF64(Matrix::Vector2(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
115      (Value::MatrixF64(Matrix::Vector3(sink)),Value::MatrixF64(Matrix::Vector3(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
116      (Value::MatrixF64(Matrix::Vector4(sink)),Value::MatrixF64(Matrix::Vector4(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
117      (Value::MatrixF64(Matrix::DVector(sink)),Value::MatrixF64(Matrix::DVector(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
118      (Value::MatrixF64(Matrix::RowVector2(sink)),Value::MatrixF64(Matrix::RowVector2(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
119      (Value::MatrixF64(Matrix::RowVector3(sink)),Value::MatrixF64(Matrix::RowVector3(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
120      (Value::MatrixF64(Matrix::RowVector4(sink)),Value::MatrixF64(Matrix::RowVector4(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
121      (Value::MatrixF64(Matrix::RowDVector(sink)),Value::MatrixF64(Matrix::RowDVector(source))) => Ok(Box::new(SubAssignVV{sink: sink.clone(), source: source.clone()})),
122      x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
123    }
124  }
125}
126
127// x[1..3] -= 1 ----------------------------------------------------------------
128
129macro_rules! sub_assign_1d_range {
130  ($source:expr, $ix:expr, $sink:expr) => {
131    unsafe { 
132      for i in 0..($ix).len() {
133        ($sink)[($ix)[i] - 1] -= ($source);
134      }
135    }
136  };}
137
138macro_rules! sub_assign_1d_range_b {
139  ($source:expr, $ix:expr, $sink:expr) => {
140    unsafe { 
141      for i in 0..($ix).len() {
142        if $ix[i] == true {
143          ($sink)[i] -= ($source);
144        }
145      }
146    }
147  };}  
148
149macro_rules! sub_assign_1d_range_vec {
150  ($source:expr, $ix:expr, $sink:expr) => {
151    unsafe { 
152      for i in 0..($ix).len() {
153        ($sink)[($ix)[i] - 1] -= ($source)[i];
154      }
155    }
156  };}
157
158impl_sub_assign_fxn!(SubAssign1DRRD,RowDVector,T,sub_assign_1d_range,usize);
159impl_sub_assign_fxn!(SubAssign1DRVD,DVector,T,sub_assign_1d_range,usize);
160impl_sub_assign_fxn!(SubAssign1DRMD,DMatrix,T,sub_assign_1d_range,usize);
161impl_sub_assign_fxn!(SubAssign1DRR4,RowVector4,T,sub_assign_1d_range,usize);
162impl_sub_assign_fxn!(SubAssign1DRR3,RowVector3,T,sub_assign_1d_range,usize);
163impl_sub_assign_fxn!(SubAssign1DRR2,RowVector2,T,sub_assign_1d_range,usize);
164impl_sub_assign_fxn!(SubAssign1DRV4,Vector4,T,sub_assign_1d_range,usize);
165impl_sub_assign_fxn!(SubAssign1DRV3,Vector3,T,sub_assign_1d_range,usize);
166impl_sub_assign_fxn!(SubAssign1DRV2,Vector2,T,sub_assign_1d_range,usize);
167impl_sub_assign_fxn!(SubAssign1DRM4,Matrix4,T,sub_assign_1d_range,usize);
168impl_sub_assign_fxn!(SubAssign1DRM3,Matrix3,T,sub_assign_1d_range,usize);
169impl_sub_assign_fxn!(SubAssign1DRM2,Matrix2,T,sub_assign_1d_range,usize);
170impl_sub_assign_fxn!(SubAssign1DRM1,Matrix1,T,sub_assign_1d_range,usize);
171impl_sub_assign_fxn!(SubAssign1DRM2x3,Matrix2x3,T,sub_assign_1d_range,usize);
172impl_sub_assign_fxn!(SubAssign1DRM3x2,Matrix3x2,T,sub_assign_1d_range,usize);
173
174impl_sub_assign_fxn!(SubAssign1DRRDB,RowDVector,T,sub_assign_1d_range_b,bool);
175impl_sub_assign_fxn!(SubAssign1DRVDB,DVector,T,sub_assign_1d_range_b,bool);
176impl_sub_assign_fxn!(SubAssign1DRMDB,DMatrix,T,sub_assign_1d_range_b,bool);
177impl_sub_assign_fxn!(SubAssign1DRR4B,RowVector4,T,sub_assign_1d_range_b,bool);
178impl_sub_assign_fxn!(SubAssign1DRR3B,RowVector3,T,sub_assign_1d_range_b,bool);
179impl_sub_assign_fxn!(SubAssign1DRR2B,RowVector2,T,sub_assign_1d_range_b,bool);
180impl_sub_assign_fxn!(SubAssign1DRV4B,Vector4,T,sub_assign_1d_range_b,bool);
181impl_sub_assign_fxn!(SubAssign1DRV3B,Vector3,T,sub_assign_1d_range_b,bool);
182impl_sub_assign_fxn!(SubAssign1DRV2B,Vector2,T,sub_assign_1d_range_b,bool);
183impl_sub_assign_fxn!(SubAssign1DRM4B,Matrix4,T,sub_assign_1d_range_b,bool);
184impl_sub_assign_fxn!(SubAssign1DRM3B,Matrix3,T,sub_assign_1d_range_b,bool);
185impl_sub_assign_fxn!(SubAssign1DRM2B,Matrix2,T,sub_assign_1d_range_b,bool);
186impl_sub_assign_fxn!(SubAssign1DRM1B,Matrix1,T,sub_assign_1d_range_b,bool);
187impl_sub_assign_fxn!(SubAssign1DRM2x3B,Matrix2x3,T,sub_assign_1d_range_b,bool);
188impl_sub_assign_fxn!(SubAssign1DRM3x2B,Matrix3x2,T,sub_assign_1d_range_b,bool);
189
190impl_sub_assign_fxn!(SubAssign1DRR4R4,RowVector4,RowVector4<T>,sub_assign_1d_range_vec,usize);
191impl_sub_assign_fxn!(SubAssign1DRR4R3,RowVector4,RowVector3<T>,sub_assign_1d_range_vec,usize);
192impl_sub_assign_fxn!(SubAssign1DRR4R2,RowVector4,RowVector2<T>,sub_assign_1d_range_vec,usize);
193impl_sub_assign_fxn!(SubAssign1DRV4V4,Vector4,Vector4<T>,sub_assign_1d_range_vec,usize);
194impl_sub_assign_fxn!(SubAssign1DRV4V3,Vector4,Vector3<T>,sub_assign_1d_range_vec,usize);
195impl_sub_assign_fxn!(SubAssign1DRV4V2,Vector4,Vector2<T>,sub_assign_1d_range_vec,usize);
196
197impl_sub_assign_fxn!(SubAssign1DRMDMD,DMatrix,DMatrix<T>,sub_assign_1d_range_vec,usize);
198
199
200fn sub_assign_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
201  impl_sub_assign_match_arms!(SubAssign1DR, range, (sink, ixes.as_slice(), source))
202}
203
204pub struct SubAssignRange {}
205impl NativeFunctionCompiler for SubAssignRange {
206  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
207    if arguments.len() <= 1 {
208      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
209    }
210    let sink: Value = arguments[0].clone();
211    let source: Value = arguments[1].clone();
212    let ixes = arguments.clone().split_off(2);
213    match sub_assign_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
214      Ok(fxn) => Ok(fxn),
215      Err(x) => {
216        match (sink,ixes,source) {
217          (Value::MutableReference(sink),ixes,Value::MutableReference(source)) => { sub_assign_range_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
218          (sink,ixes,Value::MutableReference(source)) => { sub_assign_range_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
219          (Value::MutableReference(sink),ixes,source) => { sub_assign_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
220          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
221        }
222      }
223    }
224  }
225}
226
227// x[1..3,:] -= 1 ------------------------------------------------------------------
228
229macro_rules! sub_assign_2d_vector_all {
230  ($source:expr, $ix:expr, $sink:expr) => {
231      for cix in 0..($sink).ncols() {
232        for rix in &$ix {
233          ($sink).column_mut(cix)[rix - 1] -= ($source);
234        }
235      }
236    };}
237
238macro_rules! sub_assign_2d_vector_all_b {
239  ($source:expr, $ix:expr, $sink:expr) => {
240    for cix in 0..($sink).ncols() {
241      for rix in 0..$ix.len() {
242        if $ix[rix] == true {
243          ($sink).column_mut(cix)[rix] -= ($source);
244        }
245      }
246    }
247  };} 
248
249
250#[derive(Debug)]
251struct SubAssign2DRAMDMD<T> {
252  source: Ref<DMatrix<T>>,
253  ixes: Ref<DVector<usize>>,
254  sink: Ref<DMatrix<T>>,
255}
256impl<T> MechFunction for SubAssign2DRAMDMD<T>
257where
258  T: Copy + Debug + Clone + Sync + Send + 'static +
259  Sub<Output = T> + SubAssign +
260  Zero + One +
261  PartialEq + PartialOrd,
262  Ref<DMatrix<T>>: ToValue
263{
264  fn solve(&self) {
265    unsafe {
266      let ix_ptr = &(*(self.ixes.as_ptr()));
267      let mut sink_ptr = (&mut *(self.sink.as_ptr()));
268      let source_ptr = &(*(self.source.as_ptr()));
269      for (i,rix) in (ix_ptr).iter().enumerate() {
270        let mut row = sink_ptr.row_mut(rix - 1);
271        row -= (source_ptr).row(i);
272      }
273    }
274  }
275  fn out(&self) -> Value { self.sink.to_value() }
276  fn to_string(&self) -> String { format!("{:#?}", self) }
277}
278
279
280macro_rules! sub_assign_2d_vector_all_mat {
281  ($source:expr, $ix:expr, $sink:expr) => {
282
283  };}
284
285macro_rules! sub_assign_2d_vector_all_mat_b {
286  ($source:expr, $ix:expr, $sink:expr) => {
287    for (i,rix) in (&$ix).iter().enumerate() {
288      if *rix == true {
289        let mut row = ($sink).row_mut(i);
290        row -= ($source).row(i);
291      }
292    }
293  };} 
294
295impl_sub_assign_fxn!(SubAssign2DRAMD,DMatrix,T,sub_assign_2d_vector_all,usize);
296impl_sub_assign_fxn!(SubAssign2DRAM4,Matrix4,T,sub_assign_2d_vector_all,usize);
297impl_sub_assign_fxn!(SubAssign2DRAM3,Matrix3,T,sub_assign_2d_vector_all,usize);
298impl_sub_assign_fxn!(SubAssign2DRAM2,Matrix2,T,sub_assign_2d_vector_all,usize);
299impl_sub_assign_fxn!(SubAssign2DRAM1,Matrix1,T,sub_assign_2d_vector_all,usize);
300impl_sub_assign_fxn!(SubAssign2DRAM2x3,Matrix2x3,T,sub_assign_2d_vector_all,usize);
301impl_sub_assign_fxn!(SubAssign2DRAM3x2,Matrix3x2,T,sub_assign_2d_vector_all,usize);
302
303//impl_sub_assign_fxn!(SubAssign2DRAMDMD,DMatrix,DMatrix<T>,sub_assign_2d_vector_all_mat,usize);
304impl_sub_assign_fxn!(SubAssign2DRAMDM2,DMatrix,Matrix2<T>,sub_assign_2d_vector_all_mat,usize);
305impl_sub_assign_fxn!(SubAssign2DRAMDM2x3,DMatrix,Matrix2x3<T>,sub_assign_2d_vector_all_mat,usize);
306impl_sub_assign_fxn!(SubAssign2DRAMDM3,DMatrix,Matrix3<T>,sub_assign_2d_vector_all_mat,usize);
307impl_sub_assign_fxn!(SubAssign2DRAMDM3x2,DMatrix,Matrix3x2<T>,sub_assign_2d_vector_all_mat,usize);
308impl_sub_assign_fxn!(SubAssign2DRAMDM4,DMatrix,Matrix4<T>,sub_assign_2d_vector_all_mat,usize);
309
310impl_sub_assign_fxn!(SubAssign2DRAM2M2,Matrix2,Matrix2<T>,sub_assign_2d_vector_all_mat,usize);
311impl_sub_assign_fxn!(SubAssign2DRAM2M3x2,Matrix2,Matrix3x2<T>,sub_assign_2d_vector_all_mat,usize);
312impl_sub_assign_fxn!(SubAssign2DRAM2MD,Matrix2,DMatrix<T>,sub_assign_2d_vector_all_mat,usize);
313
314impl_sub_assign_fxn!(SubAssign2DRAM3M3,Matrix3,Matrix3<T>,sub_assign_2d_vector_all_mat,usize);
315impl_sub_assign_fxn!(SubAssign2DRAM3M2x3,Matrix3,Matrix2x3<T>,sub_assign_2d_vector_all_mat,usize);
316impl_sub_assign_fxn!(SubAssign2DRAM3MD,Matrix3,DMatrix<T>,sub_assign_2d_vector_all_mat,usize);
317
318impl_sub_assign_fxn!(SubAssign2DRAM3x2M3x2,Matrix3x2,Matrix3x2<T>,sub_assign_2d_vector_all_mat,usize);
319impl_sub_assign_fxn!(SubAssign2DRAM3x2M2,Matrix3x2,Matrix2<T>,sub_assign_2d_vector_all_mat,usize);
320impl_sub_assign_fxn!(SubAssign2DRAM3x2MD,Matrix3x2,DMatrix<T>,sub_assign_2d_vector_all_mat,usize);
321
322impl_sub_assign_fxn!(SubAssign2DRAM2x3M2x3,Matrix2x3,Matrix2x3<T>,sub_assign_2d_vector_all_mat,usize);
323impl_sub_assign_fxn!(SubAssign2DRAM2x3M3,Matrix2x3,Matrix3<T>,sub_assign_2d_vector_all_mat,usize);
324impl_sub_assign_fxn!(SubAssign2DRAM2x3MD,Matrix2x3,DMatrix<T>,sub_assign_2d_vector_all_mat,usize);
325
326impl_sub_assign_fxn!(SubAssign2DRAM4M4,Matrix4,Matrix4<T>,sub_assign_2d_vector_all_mat,usize);
327impl_sub_assign_fxn!(SubAssign2DRAM4MD,Matrix4,DMatrix<T>,sub_assign_2d_vector_all_mat,usize);
328
329impl_sub_assign_fxn!(SubAssign2DRAMDB,DMatrix,T,sub_assign_2d_vector_all_b,bool);
330impl_sub_assign_fxn!(SubAssign2DRAM4B,Matrix4,T,sub_assign_2d_vector_all_b,bool);
331impl_sub_assign_fxn!(SubAssign2DRAM3B,Matrix3,T,sub_assign_2d_vector_all_b,bool);
332impl_sub_assign_fxn!(SubAssign2DRAM2B,Matrix2,T,sub_assign_2d_vector_all_b,bool);
333impl_sub_assign_fxn!(SubAssign2DRAM1B,Matrix1,T,sub_assign_2d_vector_all_b,bool);
334impl_sub_assign_fxn!(SubAssign2DRAM2x3B,Matrix2x3,T,sub_assign_2d_vector_all_b,bool);
335impl_sub_assign_fxn!(SubAssign2DRAM3x2B,Matrix3x2,T,sub_assign_2d_vector_all_b,bool);
336
337impl_sub_assign_fxn!(SubAssign2DRAMDMDB,DMatrix,DMatrix<T>,sub_assign_2d_vector_all_mat_b,bool);
338impl_sub_assign_fxn!(SubAssign2DRAM2M2B,Matrix2,Matrix2<T>,sub_assign_2d_vector_all_mat_b,bool);
339impl_sub_assign_fxn!(SubAssign2DRAM3M3B,Matrix3,Matrix3<T>,sub_assign_2d_vector_all_mat_b,bool);
340impl_sub_assign_fxn!(SubAssign2DRAM4M4B,Matrix4,Matrix4<T>,sub_assign_2d_vector_all_mat_b,bool);
341impl_sub_assign_fxn!(SubAssign2DRAM3x2M3x2B,Matrix3x2,Matrix3x2<T>,sub_assign_2d_vector_all_mat_b,bool);
342impl_sub_assign_fxn!(SubAssign2DRAM2x3M2x3B,Matrix2x3,Matrix2x3<T>,sub_assign_2d_vector_all_mat_b,bool);
343
344fn sub_assign_vec_all_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
345  impl_sub_assign_match_arms!(SubAssign2DRA, range_all, (sink, ixes.as_slice(), source))
346}
347
348pub struct SubAssignRangeAll {}
349impl NativeFunctionCompiler for SubAssignRangeAll {
350  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
351    if arguments.len() <= 1 {
352      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
353    }
354    let sink: Value = arguments[0].clone();
355    let source: Value = arguments[1].clone();
356    let ixes = arguments.clone().split_off(2);
357    match sub_assign_vec_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
358      Ok(fxn) => Ok(fxn),
359      Err(_) => {
360        match (sink,ixes,source) {
361          (Value::MutableReference(sink),ixes,Value::MutableReference(source)) => { sub_assign_vec_all_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
362          (sink,ixes,Value::MutableReference(source)) => { sub_assign_vec_all_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
363          (Value::MutableReference(sink),ixes,source) => { sub_assign_vec_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
364          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
365        }
366      }
367    }
368  }
369}