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