1use crate::*;
2use paste::paste;
3
4#[cfg(feature = "variable_define")]
5use crate::stdlib::define::*;
6
7pub fn statement(stmt: &Statement, p: &Interpreter) -> MResult<Value> {
11 match stmt {
12 #[cfg(feature = "tuple")]
13 Statement::TupleDestructure(tpl_dstrct) => tuple_destructure(&tpl_dstrct, p),
14 #[cfg(feature = "variable_define")]
15 Statement::VariableDefine(var_def) => variable_define(&var_def, p),
16 #[cfg(feature = "variable_assign")]
17 Statement::VariableAssign(var_assgn) => variable_assign(&var_assgn, p),
18 #[cfg(feature = "kind_define")]
19 Statement::KindDefine(knd_def) => kind_define(&knd_def, p),
20 #[cfg(feature = "enum")]
21 Statement::EnumDefine(enm_def) => enum_define(&enm_def, p),
22 #[cfg(feature = "math")]
23 Statement::OpAssign(op_assgn) => op_assign(&op_assgn, p),
24 x => return Err(MechError2::new(
28 FeatureNotEnabledError,
29 None
30 ).with_compiler_loc().with_tokens(x.tokens())
31 ),
32 }
33}
34
35#[cfg(feature = "tuple")]
36pub fn tuple_destructure(tpl_dstrct: &TupleDestructure, p: &Interpreter) -> MResult<Value> {
37 let source = expression(&tpl_dstrct.expression, p)?;
38 let tpl = match &source {
39 Value::Tuple(tpl) => tpl,
40 Value::MutableReference(ref r) => {
41 let r_brrw = r.borrow();
42 &match &*r_brrw {
43 Value::Tuple(tpl) => tpl.clone(),
44 _ => return Err(MechError2::new(
45 DestructureExpectedTupleError{ value: source.kind() },
46 None
47 ).with_compiler_loc().with_tokens(tpl_dstrct.expression.tokens())),
48 }
49 },
50 _ => return Err(MechError2::new(
51 DestructureExpectedTupleError{ value: source.kind() },
52 None
53 ).with_compiler_loc().with_tokens(tpl_dstrct.expression.tokens())),
54 };
55 let symbols = p.symbols();
56 let mut symbols_brrw = symbols.borrow_mut();
57 for (i, var) in tpl_dstrct.vars.iter().enumerate() {
58 let id = var.hash();
59 if symbols_brrw.contains(id) {
60 return Err(MechError2::new(
61 VariableAlreadyDefinedError { id },
62 None
63 ).with_compiler_loc().with_tokens(var.tokens()));
64 }
65 if let Some(element) = tpl.borrow().get(i) {
66 symbols_brrw.insert(id, element.clone(), true);
67 symbols_brrw.dictionary.borrow_mut().insert(id, var.name.to_string());
68 } else {
69 return Err(MechError2::new(
70 TupleDestructureTooManyVarsError{ value: source.kind() },
71 None
72 ).with_compiler_loc().with_tokens(var.tokens()));
73 }
74 }
75 Ok(source)
76}
77
78#[cfg(feature = "math")]
79pub fn op_assign(op_assgn: &OpAssign, p: &Interpreter) -> MResult<Value> {
80 let mut source = expression(&op_assgn.expression, p)?;
81 let slc = &op_assgn.target;
82 let id = slc.name.hash();
83 let sink = {
84 let mut state_brrw = p.state.borrow_mut();
85 match state_brrw.get_symbol(id) {
86 Some(val) => val.borrow().clone(),
87 None => {return Err(MechError2::new(
88 UndefinedVariableError { id },
89 None,
90 ).with_compiler_loc().with_tokens(slc.name.tokens()));
91 }
92 }
93 };
94 match &slc.subscript {
95 Some(sbscrpt) => {
96 for s in sbscrpt {
98 let fxn = match op_assgn.op {
99 #[cfg(feature = "math_add_assign")]
100 OpAssignOp::Add => add_assign(&s, &sink, &source, p)?,
101 #[cfg(feature = "math_sub_assign")]
102 OpAssignOp::Sub => sub_assign(&s, &sink, &source, p)?,
103 #[cfg(feature = "math_div_assign")]
104 OpAssignOp::Div => div_assign(&s, &sink, &source, p)?,
105 #[cfg(feature = "math_mul_assign")]
106 OpAssignOp::Mul => mul_assign(&s, &sink, &source, p)?,
107 _ => todo!(),
108 };
109 return Ok(fxn);
110 }
111 }
112 None => {
113 let args = vec![sink,source];
114 let fxn: Box<dyn MechFunction> = match op_assgn.op {
115 #[cfg(feature = "math_add_assign")]
116 OpAssignOp::Add => AddAssignValue{}.compile(&args)?,
117 #[cfg(feature = "math_sub_assign")]
118 OpAssignOp::Sub => SubAssignValue{}.compile(&args)?,
119 #[cfg(feature = "math_div_assign")]
120 OpAssignOp::Div => DivAssignValue{}.compile(&args)?,
121 #[cfg(feature = "math_mul_assign")]
122 OpAssignOp::Mul => MulAssignValue{}.compile(&args)?,
123 _ => todo!(),
124 };
125 fxn.solve();
126 let res = fxn.out();
127 p.state.borrow_mut().add_plan_step(fxn);
128 return Ok(res);
129 }
130 }
131 unreachable!(); }
133
134#[cfg(feature = "variable_assign")]
135pub fn variable_assign(var_assgn: &VariableAssign, p: &Interpreter) -> MResult<Value> {
136 let mut source = expression(&var_assgn.expression, p)?;
137 let slc = &var_assgn.target;
138 let id = slc.name.hash();
139 let sink = {
140 let symbols = p.symbols();
141 let symbols_brrw = symbols.borrow();
142 match symbols_brrw.get_mutable(id) {
143 Some(val) => val.borrow().clone(),
144 None => {
145 if !symbols_brrw.contains(id) {
146 return Err(MechError2::new(
147 UndefinedVariableError { id },
148 Some("(!)> Variables are defined with the `:=` operator. *e.g.*: {{x := 123}}".to_string()),
149 ).with_compiler_loc().with_tokens(slc.name.tokens()));
150 } else {
151 return Err(MechError2::new(
152 NotMutableError { id },
153 Some("(!)> Mutable variables are defined with the `~` operator. *e.g.*: {{~x := 123}}".to_string()),
154 ).with_compiler_loc().with_tokens(slc.name.tokens()));
155 }
156 }
157 }
158 };
159 match &slc.subscript {
160 Some(sbscrpt) => {
161 #[cfg(feature = "subscript")]
162 for s in sbscrpt {
163 let s_result = subscript_ref(&s, &sink, &source, p)?;
164 return Ok(s_result);
165 }
166 }
167 #[cfg(feature = "assign")]
168 None => {
169 let args = vec![sink,source];
170 let fxn = AssignValue{}.compile(&args)?;
171 fxn.solve();
172 let res = fxn.out();
173 p.state.borrow_mut().add_plan_step(fxn);
174 return Ok(res);
175 }
176 _ => return Err(MechError2::new(
177 FeatureNotEnabledError,
178 None
179 ).with_compiler_loc().with_tokens(var_assgn.target.tokens())),
180 }
181 unreachable!(); }
183
184#[cfg(feature = "enum")]
185pub fn enum_define(enm_def: &EnumDefine, p: &Interpreter) -> MResult<Value> {
186 let id = enm_def.name.hash();
187 let variants = enm_def.variants.iter().map(|v| (v.name.hash(),None)).collect::<Vec<(u64, Option<Value>)>>();
188 let state = &p.state;
189 let mut state_brrw = state.borrow_mut();
190 let enm = MechEnum{id, variants};
191 let val = Value::Enum(Ref::new(enm.clone()));
192 state_brrw.enums.insert(id, enm.clone());
193 state_brrw.kinds.insert(id, val.kind());
194 Ok(val)
195}
196
197#[cfg(feature = "kind_define")]
198pub fn kind_define(knd_def: &KindDefine, p: &Interpreter) -> MResult<Value> {
199 let id = knd_def.name.hash();
200 let kind = kind_annotation(&knd_def.kind.kind, p)?;
201 let value_kind = kind.to_value_kind(&p.state.borrow().kinds)?;
202 let functions = p.functions();
203 let mut kinds = &mut p.state.borrow_mut().kinds;
204 kinds.insert(id, value_kind.clone());
205 Ok(Value::Kind(value_kind))
206}
207
208#[cfg(feature = "variable_define")]
209pub fn variable_define(var_def: &VariableDefine, p: &Interpreter) -> MResult<Value> {
210 let var_id = var_def.var.name.hash();
211 let var_name = var_def.var.name.to_string();
212 {
213 let symbols = p.symbols();
214 if symbols.borrow().contains(var_id) {
215 return Err(MechError2::new(
216 VariableAlreadyDefinedError { id: var_id },
217 None
218 ).with_compiler_loc().with_tokens(var_def.var.name.tokens()));
219 }
220 }
221 let mut result = expression(&var_def.expression, p)?;
222 #[cfg(all(feature = "kind_annotation", feature = "convert"))]
223 if let Some(knd_anntn) = &var_def.var.kind {
224 let knd = kind_annotation(&knd_anntn.kind,p)?;
225 let mut state_brrw = &mut p.state.borrow_mut();
226 let target_knd = knd.to_value_kind(&mut state_brrw.kinds)?;
227 match (&result, &target_knd) {
229 #[cfg(all(feature = "atom", feature = "enum"))]
231 (Value::Atom(given_variant_id), ValueKind::Enum(enum_id)) => {
232 let enums = &state_brrw.enums;
233 let my_enum = match enums.get(enum_id) {
234 Some(my_enum) => my_enum,
235 None => todo!(),
236 };
237 if !my_enum.variants.iter().any(|(enum_variant, inner_value)| given_variant_id.borrow().0 == *enum_variant) {
239 return Err(MechError2::new(
240 UnableToConvertAtomToEnumVariantError { atom_id: given_variant_id.borrow().0, target_enum_id: *enum_id },
241 None
242 ).with_compiler_loc().with_tokens(var_def.expression.tokens()));
243 }
244 }
245 #[cfg(feature = "atom")]
247 (Value::Atom(given_variant_id), target_kind) => {
248 return Err(MechError2::new(
249 UnableToConvertAtomError { atom_id: given_variant_id.borrow().0},
250 None
251 ).with_compiler_loc().with_tokens(var_def.expression.tokens()));
252 }
253 #[cfg(feature = "matrix")]
254 (Value::MutableReference(v), ValueKind::Matrix(box target_matrix_knd,_)) => {
255 let value = v.borrow().clone();
256 if value.is_matrix() {
257 let convert_fxn = ConvertMatToMat{}.compile(&vec![result.clone(), Value::Kind(target_knd.clone())])?;
258 convert_fxn.solve();
259 let converted_result = convert_fxn.out();
260 state_brrw.add_plan_step(convert_fxn);
261 result = converted_result;
262 } else {
263 let value_kind = value.kind();
264 if value_kind.deref_kind() != target_matrix_knd.clone() && value_kind != *target_matrix_knd {
265 let convert_fxn = ConvertKind{}.compile(&vec![result.clone(), Value::Kind(target_matrix_knd.clone())])?;
266 convert_fxn.solve();
267 let converted_result = convert_fxn.out();
268 state_brrw.add_plan_step(convert_fxn);
269 result = converted_result;
270 };
271 let convert_fxn = ConvertScalarToMat{}.compile(&vec![result.clone(), Value::Kind(target_knd.clone())])?;
272 convert_fxn.solve();
273 let converted_result = convert_fxn.out();
274 state_brrw.add_plan_step(convert_fxn);
275 result = converted_result;
276 }
277 }
278 #[cfg(feature = "matrix")]
279 (value, ValueKind::Matrix(box target_matrix_knd,_)) => {
280 if value.is_matrix() {
281 let convert_fxn = ConvertMatToMat{}.compile(&vec![result.clone(), Value::Kind(target_knd.clone())])?;
282 convert_fxn.solve();
283 let converted_result = convert_fxn.out();
284 state_brrw.add_plan_step(convert_fxn);
285 result = converted_result;
286 } else {
287 let value_kind = value.kind();
288 if value_kind.deref_kind() != target_matrix_knd.clone() && value_kind != *target_matrix_knd {
289 let convert_fxn = ConvertKind{}.compile(&vec![result.clone(), Value::Kind(target_matrix_knd.clone())])?;
290 convert_fxn.solve();
291 let converted_result = convert_fxn.out();
292 state_brrw.add_plan_step(convert_fxn);
293 result = converted_result;
294 };
295 let convert_fxn = ConvertScalarToMat{}.compile(&vec![result.clone(), Value::Kind(target_knd.clone())])?;
296 convert_fxn.solve();
297 let converted_result = convert_fxn.out();
298 state_brrw.add_plan_step(convert_fxn);
299 result = converted_result;
300 }
301 }
302 x => {
304 let convert_fxn = ConvertKind{}.compile(&vec![result.clone(), Value::Kind(target_knd)])?;
305 convert_fxn.solve();
306 let converted_result = convert_fxn.out();
307 state_brrw.add_plan_step(convert_fxn);
308 result = converted_result;
309 },
310 };
311 let val_ref = state_brrw.save_symbol(var_id, var_name.clone(), result.clone(), var_def.mutable);
313 let var_def_fxn = VarDefine{}.compile(&vec![result.clone(), Value::String(Ref::new(var_name.clone())), Value::Bool(Ref::new(var_def.mutable))])?;
315 state_brrw.add_plan_step(var_def_fxn);
316 return Ok(result);
317 }
318 let mut state_brrw = p.state.borrow_mut();
319 let val_ref = state_brrw.save_symbol(var_id,var_name.clone(),result.clone(),var_def.mutable);
321 let var_def_fxn = VarDefine{}.compile(&vec![result.clone(), Value::String(Ref::new(var_name.clone())), Value::Bool(Ref::new(var_def.mutable))])?;
323 state_brrw.add_plan_step(var_def_fxn);
324 return Ok(result);
325}
326
327macro_rules! op_assign {
328 ($fxn_name:ident, $op:tt) => {
329 paste!{
330 pub fn $fxn_name(sbscrpt: &Subscript, sink: &Value, source: &Value, p: &Interpreter) -> MResult<Value> {
331 let plan = p.plan();
332 match sbscrpt {
333 Subscript::Dot(x) => {
334 todo!()
335 },
336 Subscript::DotInt(x) => {
337 todo!()
338 },
339 Subscript::Swizzle(x) => {
340 todo!()
341 },
342 Subscript::Bracket(subs) => {
343 let mut fxn_input = vec![sink.clone()];
344 match &subs[..] {
345 [Subscript::Formula(ix)] => {
346 fxn_input.push(source.clone());
347 let ixes = subscript_formula(&subs[0], p)?;
348 let shape = ixes.shape();
349 fxn_input.push(ixes);
350 match shape[..] {
351 [1,1] => plan.borrow_mut().push(MatrixAssignScalar{}.compile(&fxn_input)?),
352 [1,n] => plan.borrow_mut().push([<$op AssignRange>]{}.compile(&fxn_input)?),
353 [n,1] => plan.borrow_mut().push([<$op AssignRange>]{}.compile(&fxn_input)?),
354 _ => todo!(),
355 }
356 },
357 [Subscript::Formula(ix1),Subscript::All] => {
358 fxn_input.push(source.clone());
359 let ix = subscript_formula(&subs[0], p)?;
360 let shape = ix.shape();
361 fxn_input.push(ix);
362 fxn_input.push(Value::IndexAll);
363 match shape[..] {
364 [1,1] => plan.borrow_mut().push(MatrixAssignScalarAll{}.compile(&fxn_input)?),
365 [1,n] => plan.borrow_mut().push([<$op AssignRangeAll>]{}.compile(&fxn_input)?),
366 [n,1] => plan.borrow_mut().push([<$op AssignRangeAll>]{}.compile(&fxn_input)?),
367 _ => todo!(),
368 }
369 },
370 [Subscript::Range(ix)] => {
371 fxn_input.push(source.clone());
372 let ixes = subscript_range(&subs[0], p)?;
373 fxn_input.push(ixes);
374 plan.borrow_mut().push([<$op AssignRange>]{}.compile(&fxn_input)?);
375 },
376 [Subscript::Range(ix), Subscript::All] => {
377 fxn_input.push(source.clone());
378 let ixes = subscript_range(&subs[0], p)?;
379 fxn_input.push(ixes);
380 fxn_input.push(Value::IndexAll);
381 plan.borrow_mut().push([<$op AssignRangeAll>]{}.compile(&fxn_input)?);
382 },
383 x => todo!("{:?}", x),
384 };
385 let plan_brrw = plan.borrow();
386 let mut new_fxn = &plan_brrw.last().unwrap();
387 new_fxn.solve();
388 let res = new_fxn.out();
389 return Ok(res);
390 },
391 Subscript::Brace(x) => todo!(),
392 x => todo!("{:?}", x),
393 }
394 }
395 }}}
396
397#[cfg(feature = "math_add_assign")]
398op_assign!(add_assign, Add);
399#[cfg(feature = "math_sub_assign")]
400op_assign!(sub_assign, Sub);
401#[cfg(feature = "math_div_assign")]
402op_assign!(mul_assign, Mul);
403#[cfg(feature = "math_mul_assign")]
404op_assign!(div_assign, Div);
405#[cfg(all(feature = "subscript", feature = "assign"))]
409pub fn subscript_ref(sbscrpt: &Subscript, sink: &Value, source: &Value, p: &Interpreter) -> MResult<Value> {
410 let plan = p.plan();
411 let symbols = p.symbols();
412 let functions = p.functions();
413 match sbscrpt {
414 Subscript::Dot(x) => {
415 let key = x.hash();
416 let fxn_input: Vec<Value> = vec![sink.clone(), source.clone(), Value::Id(key)];
417 let new_fxn = AssignColumn{}.compile(&fxn_input)?;
418 new_fxn.solve();
419 let res = new_fxn.out();
420 plan.borrow_mut().push(new_fxn);
421 return Ok(res);
422 },
423 Subscript::DotInt(x) => {
424 todo!()
425 },
426 Subscript::Swizzle(x) => {
427 unreachable!()
428 },
429 Subscript::Bracket(subs) => {
430 let mut fxn_input = vec![sink.clone()];
431 match &subs[..] {
432 #[cfg(feature = "subscript_formula")]
433 [Subscript::Formula(ix)] => {
434 fxn_input.push(source.clone());
435 let ixes = subscript_formula(&subs[0], p)?;
436 let shape = ixes.shape();
437 fxn_input.push(ixes);
438 match shape[..] {
439 #[cfg(feature = "matrix")]
440 [1,1] => plan.borrow_mut().push(MatrixAssignScalar{}.compile(&fxn_input)?),
441 #[cfg(all(feature = "matrix", feature = "subscript_range", feature = "assign"))]
442 [1,n] => plan.borrow_mut().push(MatrixAssignRange{}.compile(&fxn_input)?),
443 #[cfg(all(feature = "matrix", feature = "subscript_range", feature = "assign"))]
444 [n,1] => plan.borrow_mut().push(MatrixAssignRange{}.compile(&fxn_input)?),
445 _ => todo!(),
446 }
447 },
448 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
449 [Subscript::Range(ix)] => {
450 fxn_input.push(source.clone());
451 let ixes = subscript_range(&subs[0], p)?;
452 fxn_input.push(ixes);
453 plan.borrow_mut().push(MatrixAssignRange{}.compile(&fxn_input)?);
454 },
455 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
456 [Subscript::All] => {
457 fxn_input.push(source.clone());
458 fxn_input.push(Value::IndexAll);
459 plan.borrow_mut().push(MatrixAssignAll{}.compile(&fxn_input)?);
460 },
461 [Subscript::All,Subscript::All] => todo!(),
462 #[cfg(feature = "subscript_formula")]
463 [Subscript::Formula(ix1),Subscript::Formula(ix2)] => {
464 fxn_input.push(source.clone());
465 let result1 = subscript_formula(&subs[0], p)?;
466 let result2 = subscript_formula(&subs[1], p)?;
467 let shape1 = result1.shape();
468 let shape2 = result2.shape();
469 fxn_input.push(result1);
470 fxn_input.push(result2);
471 match ((shape1[0],shape1[1]),(shape2[0],shape2[1])) {
472 #[cfg(feature = "matrix")]
473 ((1,1),(1,1)) => plan.borrow_mut().push(MatrixAssignScalarScalar{}.compile(&fxn_input)?),
474 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
475 ((1,1),(m,1)) => plan.borrow_mut().push(MatrixAssignScalarRange{}.compile(&fxn_input)?),
476 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
477 ((n,1),(1,1)) => plan.borrow_mut().push(MatrixAssignRangeScalar{}.compile(&fxn_input)?),
478 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
479 ((n,1),(m,1)) => plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?),
480 _ => unreachable!(),
481 }
482 },
483 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
484 [Subscript::Range(ix1),Subscript::Range(ix2)] => {
485 fxn_input.push(source.clone());
486 let result = subscript_range(&subs[0],p)?;
487 fxn_input.push(result);
488 let result = subscript_range(&subs[1],p)?;
489 fxn_input.push(result);
490 plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?);
491 },
492 #[cfg(all(feature = "matrix", feature = "subscript_formula"))]
493 [Subscript::All,Subscript::Formula(ix2)] => {
494 fxn_input.push(source.clone());
495 fxn_input.push(Value::IndexAll);
496 let ix = subscript_formula(&subs[1], p)?;
497 let shape = ix.shape();
498 fxn_input.push(ix);
499 match shape[..] {
500 #[cfg(feature = "matrix")]
501 [1,1] => plan.borrow_mut().push(MatrixAssignAllScalar{}.compile(&fxn_input)?),
502 #[cfg(feature = "matrix")]
503 [1,n] => plan.borrow_mut().push(MatrixAssignAllRange{}.compile(&fxn_input)?),
504 #[cfg(feature = "matrix")]
505 [n,1] => plan.borrow_mut().push(MatrixAssignAllRange{}.compile(&fxn_input)?),
506 _ => todo!(),
507 }
508 }
509 #[cfg(feature = "subscript_formula")]
510 [Subscript::Formula(ix1),Subscript::All] => {
511 fxn_input.push(source.clone());
512 let ix = subscript_formula(&subs[0], p)?;
513 let shape = ix.shape();
514 fxn_input.push(ix);
515 fxn_input.push(Value::IndexAll);
516 match shape[..] {
517 #[cfg(feature = "matrix")]
518 [1,1] => plan.borrow_mut().push(MatrixAssignScalarAll{}.compile(&fxn_input)?),
519 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
520 [1,n] => plan.borrow_mut().push(MatrixAssignRangeAll{}.compile(&fxn_input)?),
521 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
522 [n,1] => plan.borrow_mut().push(MatrixAssignRangeAll{}.compile(&fxn_input)?),
523 _ => todo!(),
524 }
525 },
526 #[cfg(all(feature = "subscript_formula", feature = "subscript_range"))]
527 [Subscript::Range(ix1),Subscript::Formula(ix2)] => {
528 fxn_input.push(source.clone());
529 let result = subscript_range(&subs[0],p)?;
530 fxn_input.push(result);
531 let result = subscript_formula(&subs[1], p)?;
532 let shape = result.shape();
533 fxn_input.push(result);
534 match &shape[..] {
535 #[cfg(feature = "matrix")]
536 [1,1] => plan.borrow_mut().push(MatrixAssignRangeScalar{}.compile(&fxn_input)?),
537 #[cfg(feature = "matrix")]
538 [1,n] => plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?),
539 #[cfg(feature = "matrix")]
540 [n,1] => plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?),
541 _ => todo!(),
542 }
543 },
544 #[cfg(all(feature = "subscript_formula", feature = "subscript_range"))]
545 [Subscript::Formula(ix1),Subscript::Range(ix2)] => {
546 fxn_input.push(source.clone());
547 let result = subscript_formula(&subs[0], p)?;
548 let shape = result.shape();
549 fxn_input.push(result);
550 let result = subscript_range(&subs[1],p)?;
551 fxn_input.push(result);
552 match &shape[..] {
553 #[cfg(feature = "matrix")]
554 [1,1] => plan.borrow_mut().push(MatrixAssignScalarRange{}.compile(&fxn_input)?),
555 #[cfg(feature = "matrix")]
556 [1,n] => plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?),
557 #[cfg(feature = "matrix")]
558 [n,1] => plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?),
559 _ => todo!(),
560 }
561 },
562 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
563 [Subscript::All,Subscript::Range(ix2)] => {
564 fxn_input.push(source.clone());
565 fxn_input.push(Value::IndexAll);
566 let result = subscript_range(&subs[1],p)?;
567 fxn_input.push(result);
568 plan.borrow_mut().push(MatrixAssignAllRange{}.compile(&fxn_input)?);
569 },
570 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
571 [Subscript::Range(ix1),Subscript::All] => {
572 fxn_input.push(source.clone());
573 let result = subscript_range(&subs[0],p)?;
574 fxn_input.push(result);
575 fxn_input.push(Value::IndexAll);
576 plan.borrow_mut().push(MatrixAssignRangeAll{}.compile(&fxn_input)?);
577 },
578 _ => unreachable!(),
579 };
580 let plan_brrw = plan.borrow();
581 let mut new_fxn = &plan_brrw.last().unwrap();
582 new_fxn.solve();
583 let res = new_fxn.out();
584 return Ok(res);
585 },
586 Subscript::Brace(x) => todo!(),
587 _ => unreachable!(),
588 }
589}
590
591#[derive(Debug, Clone)]
592pub struct UnableToConvertAtomToEnumVariantError {
593 pub atom_id: u64,
594 pub target_enum_id: u64,
595}
596impl MechErrorKind2 for UnableToConvertAtomToEnumVariantError {
597 fn name(&self) -> &str {
598 "UnableToConvertAtomToEnumVariant"
599 }
600 fn message(&self) -> String {
601 format!("Unable to convert atom variant {} to enum {}", self.atom_id, self.target_enum_id)
602 }
603}
604
605#[derive(Debug, Clone)]
606pub struct UnableToConvertAtomError {
607 pub atom_id: u64,
608}
609impl MechErrorKind2 for UnableToConvertAtomError {
610 fn name(&self) -> &str {
611 "UnableToConvertAtom"
612 }
613 fn message(&self) -> String {
614 format!("Unable to atom {}", self.atom_id)
615 }
616}
617
618#[derive(Debug, Clone)]
619pub struct VariableAlreadyDefinedError {
620 pub id: u64,
621}
622impl MechErrorKind2 for VariableAlreadyDefinedError {
623 fn name(&self) -> &str { "VariableAlreadyDefined" }
624 fn message(&self) -> String {
625 format!("Variable already defined: {}", self.id)
626 }
627}
628
629#[derive(Debug, Clone)]
630pub struct UndefinedVariableError {
631 pub id: u64,
632}
633impl MechErrorKind2 for UndefinedVariableError {
634 fn name(&self) -> &str { "UndefinedVariable" }
635
636 fn message(&self) -> String {
637 format!("Undefined variable: {}", self.id)
638 }
639}
640
641#[derive(Debug, Clone)]
642pub struct NotMutableError {
643 pub id: u64,
644}
645impl MechErrorKind2 for NotMutableError {
646 fn name(&self) -> &str { "NotMutable" }
647 fn message(&self) -> String {
648 format!("Variable is not mutable: {}", self.id)
649 }
650}
651