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_mutable_symbol(id) {
89 Some(val) => val.borrow().clone(),
90 None => {
91 match state_brrw.contains_symbol(id) {
92 true => return Err(MechError2::new(
93 NotMutableError { id },
94 Some("(!)> Mutable variables are defined with the `~` operator. *e.g.*: {{~x := 123}}".to_string()),
95 ).with_compiler_loc().with_tokens(slc.name.tokens())),
96 false => return Err(MechError2::new(
97 UndefinedVariableError { id },
98 Some("(!)> Variables are defined with the `:=` operator. *e.g.*: {{x := 123}}".to_string()),
99 ).with_compiler_loc().with_tokens(slc.name.tokens())),
100 }
101 }
102 }
103 };
104 match &slc.subscript {
105 Some(sbscrpt) => {
106 for s in sbscrpt {
108 let fxn = match op_assgn.op {
109 #[cfg(feature = "math_add_assign")]
110 OpAssignOp::Add => add_assign(&s, &sink, &source, env, p)?,
111 #[cfg(feature = "math_sub_assign")]
112 OpAssignOp::Sub => sub_assign(&s, &sink, &source, env, p)?,
113 #[cfg(feature = "math_div_assign")]
114 OpAssignOp::Div => div_assign(&s, &sink, &source, env, p)?,
115 #[cfg(feature = "math_mul_assign")]
116 OpAssignOp::Mul => mul_assign(&s, &sink, &source, env, p)?,
117 _ => todo!(),
118 };
119 return Ok(fxn);
120 }
121 }
122 None => {
123 let args = vec![sink,source];
124 let fxn: Box<dyn MechFunction> = match op_assgn.op {
125 #[cfg(feature = "math_add_assign")]
126 OpAssignOp::Add => AddAssignValue{}.compile(&args)?,
127 #[cfg(feature = "math_sub_assign")]
128 OpAssignOp::Sub => SubAssignValue{}.compile(&args)?,
129 #[cfg(feature = "math_div_assign")]
130 OpAssignOp::Div => DivAssignValue{}.compile(&args)?,
131 #[cfg(feature = "math_mul_assign")]
132 OpAssignOp::Mul => MulAssignValue{}.compile(&args)?,
133 _ => todo!(),
134 };
135 fxn.solve();
136 let res = fxn.out();
137 p.state.borrow_mut().add_plan_step(fxn);
138 return Ok(res);
139 }
140 }
141 unreachable!(); }
143
144#[cfg(feature = "variable_assign")]
145pub fn variable_assign(var_assgn: &VariableAssign, env: Option<&Environment>, p: &Interpreter) -> MResult<Value> {
146 let mut source = expression(&var_assgn.expression, env, p)?;
147 let slc = &var_assgn.target;
148 let id = slc.name.hash();
149 let sink = {
150 let symbols = p.symbols();
151 let symbols_brrw = symbols.borrow();
152 match symbols_brrw.get_mutable(id) {
153 Some(val) => val.borrow().clone(),
154 None => {
155 if !symbols_brrw.contains(id) {
156 return Err(MechError2::new(
157 UndefinedVariableError { id },
158 Some("(!)> Variables are defined with the `:=` operator. *e.g.*: {{x := 123}}".to_string()),
159 ).with_compiler_loc().with_tokens(slc.name.tokens()));
160 } else {
161 return Err(MechError2::new(
162 NotMutableError { id },
163 Some("(!)> Mutable variables are defined with the `~` operator. *e.g.*: {{~x := 123}}".to_string()),
164 ).with_compiler_loc().with_tokens(slc.name.tokens()));
165 }
166 }
167 }
168 };
169 match &slc.subscript {
170 Some(sbscrpt) => {
171 #[cfg(feature = "subscript")]
172 for s in sbscrpt {
173 let s_result = subscript_ref(&s, &sink, &source, env, p)?;
174 return Ok(s_result);
175 }
176 }
177 #[cfg(feature = "assign")]
178 None => {
179 let args = vec![sink,source];
180 let fxn = AssignValue{}.compile(&args)?;
181 fxn.solve();
182 let res = fxn.out();
183 p.state.borrow_mut().add_plan_step(fxn);
184 return Ok(res);
185 }
186 _ => return Err(MechError2::new(
187 FeatureNotEnabledError,
188 None
189 ).with_compiler_loc().with_tokens(var_assgn.target.tokens())),
190 }
191 unreachable!(); }
193
194#[cfg(feature = "enum")]
195pub fn enum_define(enm_def: &EnumDefine, p: &Interpreter) -> MResult<()> {
196 let id = enm_def.name.hash();
197 let variants = enm_def.variants.iter().map(|v| (v.name.hash(),None)).collect::<Vec<(u64, Option<Value>)>>();
198 let state = &p.state;
199 let mut state_brrw = state.borrow_mut();
200 let dictionary = state_brrw.dictionary.clone();
201 {
202 let mut dictionary_brrw = dictionary.borrow_mut();
203 dictionary_brrw.insert(enm_def.name.hash(), enm_def.name.to_string());
204 for variant in &enm_def.variants {
205 dictionary_brrw.insert(variant.name.hash(), variant.name.to_string());
206 }
207 }
208 let enm = MechEnum{id, variants, names: dictionary};
209 let val = Value::Enum(Ref::new(enm.clone()));
210 state_brrw.enums.insert(id, enm.clone());
211 state_brrw.kinds.insert(id, val.kind());
212 Ok(())
213}
214
215#[cfg(feature = "kind_define")]
216pub fn kind_define(knd_def: &KindDefine, p: &Interpreter) -> MResult<Value> {
217 let id = knd_def.name.hash();
218 let kind = kind_annotation(&knd_def.kind.kind, p)?;
219 let value_kind = kind.to_value_kind(&p.state.borrow().kinds)?;
220 let functions = p.functions();
221 let mut kinds = &mut p.state.borrow_mut().kinds;
222 kinds.insert(id, value_kind.clone());
223 Ok(Value::Kind(value_kind))
224}
225
226#[cfg(feature = "variable_define")]
227pub fn variable_define(var_def: &VariableDefine, p: &Interpreter) -> MResult<Value> {
228 let var_id = var_def.var.name.hash();
229 let var_name = var_def.var.name.to_string();
230 {
231 let symbols = p.symbols();
232 if symbols.borrow().contains(var_id) {
233 return Err(MechError2::new(
234 VariableAlreadyDefinedError { id: var_id },
235 None
236 ).with_compiler_loc().with_tokens(var_def.var.name.tokens()));
237 }
238 }
239 let mut result = expression(&var_def.expression, None, p)?;
240 #[cfg(all(feature = "kind_annotation", feature = "convert"))]
241 if let Some(knd_anntn) = &var_def.var.kind {
242 let knd = kind_annotation(&knd_anntn.kind,p)?;
243 let mut state_brrw = &mut p.state.borrow_mut();
244 let target_knd = knd.to_value_kind(&mut state_brrw.kinds)?;
245 match (&result, &target_knd) {
247 #[cfg(all(feature = "atom", feature = "enum"))]
249 (Value::Atom(atom_variant), ValueKind::Enum(enum_id, target_enum_variant_name)) => {
250 let atom_variant_brrw = atom_variant.borrow();
251 let enums = &state_brrw.enums;
252 let my_enum = match enums.get(enum_id) {
253 Some(my_enum) => my_enum,
254 None => todo!(),
255 };
256 let dictionary = state_brrw.dictionary.clone();
257 let atom_id = atom_variant_brrw.id();
258 let atom_name = atom_variant_brrw.name();
259 let enum_variant_name = if let Some((enum_name, variant_name)) = atom_name.split_once('/') {
261 if enum_name != target_enum_variant_name {
262 return Err(MechError2::new(
263 UnableToConvertAtomToEnumVariantError { atom_name: atom_name.clone(), target_enum_variant_name: target_enum_variant_name.to_string() },
264 None
265 ).with_compiler_loc().with_tokens(var_def.expression.tokens()));
266 }
267 variant_name.to_string()
268 } else {
269 return Err(MechError2::new(
270 UnableToConvertAtomToEnumVariantError { atom_name: atom_name.clone(), target_enum_variant_name: target_enum_variant_name.clone() },
271 None
272 ).with_compiler_loc().with_tokens(var_def.expression.tokens()));
273 };
274 let variant_id = hash_str(&enum_variant_name);
275 if !my_enum.variants.iter().any(|(known_enum_variant, inner_value)| variant_id == *known_enum_variant) {
277 return Err(MechError2::new(
278 UnableToConvertAtomToEnumVariantError { atom_name: atom_name.clone(), target_enum_variant_name: target_enum_variant_name.clone() },
279 None
280 ).with_compiler_loc().with_tokens(var_def.expression.tokens()));
281 }
282 }
283 #[cfg(feature = "atom")]
285 (Value::Atom(given_variant_id), target_kind) => {
286 return Err(MechError2::new(
287 UnableToConvertAtomError { atom_id: given_variant_id.borrow().0.0},
288 None
289 ).with_compiler_loc().with_tokens(var_def.expression.tokens()));
290 }
291 #[cfg(feature = "record")]
292 (Value::Record(ref rec), ref target_kind @ ValueKind::Record(ref target_rec_knd)) => {
293 let rec_brrw = rec.borrow();
294 let rec_knd = rec_brrw.kind();
295 if &rec_knd != *target_kind {
296 return Err(MechError2::new(
297 UnableToConvertRecordError { source_record_kind: rec_knd.clone(), target_record_kind: (*target_kind).clone() },
298 None
299 ).with_compiler_loc().with_tokens(var_def.expression.tokens()));
300 }
301 }
302 #[cfg(feature = "matrix")]
303 (Value::MutableReference(v), ValueKind::Matrix(box target_matrix_knd,_)) => {
304 let value = v.borrow().clone();
305 if value.is_matrix() {
306 let convert_fxn = ConvertMatToMat{}.compile(&vec![result.clone(), Value::Kind(target_knd.clone())])?;
307 convert_fxn.solve();
308 let converted_result = convert_fxn.out();
309 state_brrw.add_plan_step(convert_fxn);
310 result = converted_result;
311 } else {
312 let value_kind = value.kind();
313 if value_kind.deref_kind() != target_matrix_knd.clone() && value_kind != *target_matrix_knd {
314 let convert_fxn = ConvertKind{}.compile(&vec![result.clone(), Value::Kind(target_matrix_knd.clone())])?;
315 convert_fxn.solve();
316 let converted_result = convert_fxn.out();
317 state_brrw.add_plan_step(convert_fxn);
318 result = converted_result;
319 };
320 let convert_fxn = ConvertScalarToMat{}.compile(&vec![result.clone(), Value::Kind(target_knd.clone())])?;
321 convert_fxn.solve();
322 let converted_result = convert_fxn.out();
323 state_brrw.add_plan_step(convert_fxn);
324 result = converted_result;
325 }
326 }
327 #[cfg(feature = "matrix")]
328 (value, ValueKind::Matrix(box target_matrix_knd,_)) => {
329 if value.is_matrix() {
330 let convert_fxn = ConvertMatToMat{}.compile(&vec![result.clone(), Value::Kind(target_knd.clone())])?;
331 convert_fxn.solve();
332 let converted_result = convert_fxn.out();
333 state_brrw.add_plan_step(convert_fxn);
334 result = converted_result;
335 } else {
336 let value_kind = value.kind();
337 if value_kind.deref_kind() != target_matrix_knd.clone() && value_kind != *target_matrix_knd {
338 let convert_fxn = ConvertKind{}.compile(&vec![result.clone(), Value::Kind(target_matrix_knd.clone())])?;
339 convert_fxn.solve();
340 let converted_result = convert_fxn.out();
341 state_brrw.add_plan_step(convert_fxn);
342 result = converted_result;
343 };
344 let convert_fxn = ConvertScalarToMat{}.compile(&vec![result.clone(), Value::Kind(target_knd.clone())])?;
345 convert_fxn.solve();
346 let converted_result = convert_fxn.out();
347 state_brrw.add_plan_step(convert_fxn);
348 result = converted_result;
349 }
350 }
351 x => {
353 let convert_fxn = ConvertKind{}.compile(&vec![result.clone(), Value::Kind(target_knd)])?;
354 convert_fxn.solve();
355 let converted_result = convert_fxn.out();
356 state_brrw.add_plan_step(convert_fxn);
357 result = converted_result;
358 },
359 };
360 let val_ref = state_brrw.save_symbol(var_id, var_name.clone(), result.clone(), var_def.mutable);
362 let var_def_fxn = VarDefine{}.compile(&vec![result.clone(), Value::String(Ref::new(var_name.clone())), Value::Bool(Ref::new(var_def.mutable))])?;
364 state_brrw.add_plan_step(var_def_fxn);
365 return Ok(result);
366 }
367 let mut state_brrw = p.state.borrow_mut();
368 let val_ref = state_brrw.save_symbol(var_id,var_name.clone(),result.clone(),var_def.mutable);
370 let var_def_fxn = VarDefine{}.compile(&vec![result.clone(), Value::String(Ref::new(var_name.clone())), Value::Bool(Ref::new(var_def.mutable))])?;
372 state_brrw.add_plan_step(var_def_fxn);
373 return Ok(result);
374}
375
376macro_rules! op_assign {
377 ($fxn_name:ident, $op:tt) => {
378 paste!{
379 pub fn $fxn_name(sbscrpt: &Subscript, sink: &Value, source: &Value, env: Option<&Environment>, p: &Interpreter) -> MResult<Value> {
380 let plan = p.plan();
381 match sbscrpt {
382 Subscript::Dot(x) => {
383 todo!()
384 },
385 Subscript::DotInt(x) => {
386 todo!()
387 },
388 Subscript::Swizzle(x) => {
389 todo!()
390 },
391 Subscript::Bracket(subs) => {
392 let mut fxn_input = vec![sink.clone()];
393 match &subs[..] {
394 [Subscript::Formula(ix)] => {
395 fxn_input.push(source.clone());
396 let ixes = subscript_formula_ix(&subs[0], env, p)?;
397 let shape = ixes.shape();
398 fxn_input.push(ixes);
399 match shape[..] {
400 [1,1] => plan.borrow_mut().push(MatrixAssignScalar{}.compile(&fxn_input)?),
401 [1,n] => plan.borrow_mut().push([<$op AssignRange>]{}.compile(&fxn_input)?),
402 [n,1] => plan.borrow_mut().push([<$op AssignRange>]{}.compile(&fxn_input)?),
403 _ => todo!(),
404 }
405 },
406 [Subscript::Formula(ix1),Subscript::All] => {
407 fxn_input.push(source.clone());
408 let ix = subscript_formula_ix(&subs[0], env, p)?;
409 let shape = ix.shape();
410 fxn_input.push(ix);
411 fxn_input.push(Value::IndexAll);
412 match shape[..] {
413 [1,1] => plan.borrow_mut().push(MatrixAssignScalarAll{}.compile(&fxn_input)?),
414 [1,n] => plan.borrow_mut().push([<$op AssignRangeAll>]{}.compile(&fxn_input)?),
415 [n,1] => plan.borrow_mut().push([<$op AssignRangeAll>]{}.compile(&fxn_input)?),
416 _ => todo!(),
417 }
418 },
419 [Subscript::Range(ix)] => {
420 fxn_input.push(source.clone());
421 let ixes = subscript_range(&subs[0], env, p)?;
422 fxn_input.push(ixes);
423 plan.borrow_mut().push([<$op AssignRange>]{}.compile(&fxn_input)?);
424 },
425 [Subscript::Range(ix), Subscript::All] => {
426 fxn_input.push(source.clone());
427 let ixes = subscript_range(&subs[0], env, p)?;
428 fxn_input.push(ixes);
429 fxn_input.push(Value::IndexAll);
430 plan.borrow_mut().push([<$op AssignRangeAll>]{}.compile(&fxn_input)?);
431 },
432 x => todo!("{:?}", x),
433 };
434 let plan_brrw = plan.borrow();
435 let mut new_fxn = &plan_brrw.last().unwrap();
436 new_fxn.solve();
437 let res = new_fxn.out();
438 return Ok(res);
439 },
440 Subscript::Brace(x) => todo!(),
441 x => todo!("{:?}", x),
442 }
443 }
444 }}}
445
446#[cfg(feature = "math_add_assign")]
447op_assign!(add_assign, Add);
448#[cfg(feature = "math_sub_assign")]
449op_assign!(sub_assign, Sub);
450#[cfg(feature = "math_div_assign")]
451op_assign!(mul_assign, Mul);
452#[cfg(feature = "math_mul_assign")]
453op_assign!(div_assign, Div);
454#[cfg(all(feature = "subscript", feature = "assign"))]
458pub fn subscript_ref(sbscrpt: &Subscript, sink: &Value, source: &Value, env: Option<&Environment>, p: &Interpreter) -> MResult<Value> {
459 let plan = p.plan();
460 let symbols = p.symbols();
461 let functions = p.functions();
462 match sbscrpt {
463 Subscript::Dot(x) => {
464 let key = x.hash();
465 let fxn_input: Vec<Value> = vec![sink.clone(), source.clone(), Value::Id(key)];
466 let new_fxn = AssignColumn{}.compile(&fxn_input)?;
467 new_fxn.solve();
468 let res = new_fxn.out();
469 plan.borrow_mut().push(new_fxn);
470 return Ok(res);
471 },
472 #[cfg(feature = "tuple")]
473 Subscript::DotInt(x) => {
474 let ix = real(x).as_index()?;
475 let mut fxn_input: Vec<Value> = vec![sink.clone(), source.clone(), ix.clone()];
476 let new_fxn = TupleAssignScalar{}.compile(&fxn_input)?;
477 new_fxn.solve();
478 let res = new_fxn.out();
479 plan.borrow_mut().push(new_fxn);
480 return Ok(res);
481 },
482 Subscript::Swizzle(x) => {
483 unreachable!()
484 },
485 Subscript::Bracket(subs) => {
486 let mut fxn_input = vec![sink.clone()];
487 match &subs[..] {
488 #[cfg(feature = "subscript_formula")]
489 [Subscript::Formula(ix)] => {
490 fxn_input.push(source.clone());
491 let ixes = subscript_formula_ix(&subs[0], env, p)?;
492 let shape = ixes.shape();
493 fxn_input.push(ixes);
494 match shape[..] {
495 #[cfg(feature = "matrix")]
496 [1,1] => plan.borrow_mut().push(MatrixAssignScalar{}.compile(&fxn_input)?),
497 #[cfg(all(feature = "matrix", feature = "subscript_range", feature = "assign"))]
498 [1,n] => plan.borrow_mut().push(MatrixAssignRange{}.compile(&fxn_input)?),
499 #[cfg(all(feature = "matrix", feature = "subscript_range", feature = "assign"))]
500 [n,1] => plan.borrow_mut().push(MatrixAssignRange{}.compile(&fxn_input)?),
501 _ => todo!(),
502 }
503 },
504 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
505 [Subscript::Range(ix)] => {
506 fxn_input.push(source.clone());
507 let ixes = subscript_range(&subs[0], env, p)?;
508 fxn_input.push(ixes);
509 plan.borrow_mut().push(MatrixAssignRange{}.compile(&fxn_input)?);
510 },
511 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
512 [Subscript::All] => {
513 fxn_input.push(source.clone());
514 fxn_input.push(Value::IndexAll);
515 plan.borrow_mut().push(MatrixAssignAll{}.compile(&fxn_input)?);
516 },
517 [Subscript::All,Subscript::All] => todo!(),
518 #[cfg(feature = "subscript_formula")]
519 [Subscript::Formula(ix1),Subscript::Formula(ix2)] => {
520 fxn_input.push(source.clone());
521 let result1 = subscript_formula_ix(&subs[0], env, p)?;
522 let result2 = subscript_formula_ix(&subs[1], env, p)?;
523 let shape1 = result1.shape();
524 let shape2 = result2.shape();
525 fxn_input.push(result1);
526 fxn_input.push(result2);
527 match ((shape1[0],shape1[1]),(shape2[0],shape2[1])) {
528 #[cfg(feature = "matrix")]
529 ((1,1),(1,1)) => plan.borrow_mut().push(MatrixAssignScalarScalar{}.compile(&fxn_input)?),
530 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
531 ((1,1),(m,1)) => plan.borrow_mut().push(MatrixAssignScalarRange{}.compile(&fxn_input)?),
532 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
533 ((n,1),(1,1)) => plan.borrow_mut().push(MatrixAssignRangeScalar{}.compile(&fxn_input)?),
534 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
535 ((n,1),(m,1)) => plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?),
536 _ => unreachable!(),
537 }
538 },
539 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
540 [Subscript::Range(ix1),Subscript::Range(ix2)] => {
541 fxn_input.push(source.clone());
542 let result = subscript_range(&subs[0], env, p)?;
543 fxn_input.push(result);
544 let result = subscript_range(&subs[1], env, p)?;
545 fxn_input.push(result);
546 plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?);
547 },
548 #[cfg(all(feature = "matrix", feature = "subscript_formula"))]
549 [Subscript::All,Subscript::Formula(ix2)] => {
550 fxn_input.push(source.clone());
551 fxn_input.push(Value::IndexAll);
552 let ix = subscript_formula_ix(&subs[1], env, p)?;
553 let shape = ix.shape();
554 fxn_input.push(ix);
555 match shape[..] {
556 #[cfg(feature = "matrix")]
557 [1,1] => plan.borrow_mut().push(MatrixAssignAllScalar{}.compile(&fxn_input)?),
558 #[cfg(feature = "matrix")]
559 [1,n] => plan.borrow_mut().push(MatrixAssignAllRange{}.compile(&fxn_input)?),
560 #[cfg(feature = "matrix")]
561 [n,1] => plan.borrow_mut().push(MatrixAssignAllRange{}.compile(&fxn_input)?),
562 _ => todo!(),
563 }
564 }
565 #[cfg(feature = "subscript_formula")]
566 [Subscript::Formula(ix1),Subscript::All] => {
567 fxn_input.push(source.clone());
568 let ix = subscript_formula_ix(&subs[0], env, p)?;
569 let shape = ix.shape();
570 fxn_input.push(ix);
571 fxn_input.push(Value::IndexAll);
572 match shape[..] {
573 #[cfg(feature = "matrix")]
574 [1,1] => plan.borrow_mut().push(MatrixAssignScalarAll{}.compile(&fxn_input)?),
575 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
576 [1,n] => plan.borrow_mut().push(MatrixAssignRangeAll{}.compile(&fxn_input)?),
577 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
578 [n,1] => plan.borrow_mut().push(MatrixAssignRangeAll{}.compile(&fxn_input)?),
579 _ => todo!(),
580 }
581 },
582 #[cfg(all(feature = "subscript_formula", feature = "subscript_range"))]
583 [Subscript::Range(ix1),Subscript::Formula(ix2)] => {
584 fxn_input.push(source.clone());
585 let result = subscript_range(&subs[0], env, p)?;
586 fxn_input.push(result);
587 let result = subscript_formula_ix(&subs[1], env, p)?;
588 let shape = result.shape();
589 fxn_input.push(result);
590 match &shape[..] {
591 #[cfg(feature = "matrix")]
592 [1,1] => plan.borrow_mut().push(MatrixAssignRangeScalar{}.compile(&fxn_input)?),
593 #[cfg(feature = "matrix")]
594 [1,n] => plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?),
595 #[cfg(feature = "matrix")]
596 [n,1] => plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?),
597 _ => todo!(),
598 }
599 },
600 #[cfg(all(feature = "subscript_formula", feature = "subscript_range"))]
601 [Subscript::Formula(ix1),Subscript::Range(ix2)] => {
602 fxn_input.push(source.clone());
603 let result = subscript_formula_ix(&subs[0], env, p)?;
604 let shape = result.shape();
605 fxn_input.push(result);
606 let result = subscript_range(&subs[1], env, p)?;
607 fxn_input.push(result);
608 match &shape[..] {
609 #[cfg(feature = "matrix")]
610 [1,1] => plan.borrow_mut().push(MatrixAssignScalarRange{}.compile(&fxn_input)?),
611 #[cfg(feature = "matrix")]
612 [1,n] => plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?),
613 #[cfg(feature = "matrix")]
614 [n,1] => plan.borrow_mut().push(MatrixAssignRangeRange{}.compile(&fxn_input)?),
615 _ => todo!(),
616 }
617 },
618 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
619 [Subscript::All,Subscript::Range(ix2)] => {
620 fxn_input.push(source.clone());
621 fxn_input.push(Value::IndexAll);
622 let result = subscript_range(&subs[1], env, p)?;
623 fxn_input.push(result);
624 plan.borrow_mut().push(MatrixAssignAllRange{}.compile(&fxn_input)?);
625 },
626 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
627 [Subscript::Range(ix1),Subscript::All] => {
628 fxn_input.push(source.clone());
629 let result = subscript_range(&subs[0], env, p)?;
630 fxn_input.push(result);
631 fxn_input.push(Value::IndexAll);
632 plan.borrow_mut().push(MatrixAssignRangeAll{}.compile(&fxn_input)?);
633 },
634 _ => unreachable!(),
635 };
636 let plan_brrw = plan.borrow();
637 let mut new_fxn = &plan_brrw.last().unwrap();
638 new_fxn.solve();
639 let res = new_fxn.out();
640 return Ok(res);
641 },
642 Subscript::Brace(subs) => {
643 let mut fxn_input = vec![sink.clone()];
644 match &subs[..] {
645 #[cfg(feature = "subscript_formula")]
646 [Subscript::Formula(ix)] => {
647 fxn_input.push(source.clone());
648 let ixes = subscript_formula(&subs[0], env, p)?;
649 let shape = ixes.shape();
650 fxn_input.push(ixes);
651 match shape[..] {
652 #[cfg(feature = "map")]
653 [1,1] => plan.borrow_mut().push(MapAssignScalar{}.compile(&fxn_input)?),
654 _ => todo!(),
659 }
660 },
661 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
662 [Subscript::Range(ix)] => {
663 todo!();
664 },
669 #[cfg(all(feature = "matrix", feature = "subscript_range"))]
670 [Subscript::All] => {
671 todo!();
672 },
676 _ => unreachable!(),
677 };
678 let plan_brrw = plan.borrow();
679 let mut new_fxn = &plan_brrw.last().unwrap();
680 new_fxn.solve();
681 let res = new_fxn.out();
682 return Ok(res);
683 }
684 _ => unreachable!(),
685 }
686}
687
688#[derive(Debug, Clone)]
689pub struct UnableToConvertAtomToEnumVariantError {
690 pub atom_name: String,
691 pub target_enum_variant_name: String,
692}
693impl MechErrorKind2 for UnableToConvertAtomToEnumVariantError {
694 fn name(&self) -> &str {
695 "UnableToConvertAtomToEnumVariant"
696 }
697 fn message(&self) -> String {
698 format!("Unable to convert atom variant `{} to enum <{}>", self.atom_name, self.target_enum_variant_name)
699 }
700}
701
702#[derive(Debug, Clone)]
703pub struct UnableToConvertAtomError {
704 pub atom_id: u64,
705}
706impl MechErrorKind2 for UnableToConvertAtomError {
707 fn name(&self) -> &str {
708 "UnableToConvertAtom"
709 }
710 fn message(&self) -> String {
711 format!("Unable to atom {}", self.atom_id)
712 }
713}
714
715#[derive(Debug, Clone)]
716pub struct VariableAlreadyDefinedError {
717 pub id: u64,
718}
719impl MechErrorKind2 for VariableAlreadyDefinedError {
720 fn name(&self) -> &str { "VariableAlreadyDefined" }
721 fn message(&self) -> String {
722 format!("Variable already defined: {}", self.id)
723 }
724}
725
726#[derive(Debug, Clone)]
727pub struct UndefinedVariableError {
728 pub id: u64,
729}
730impl MechErrorKind2 for UndefinedVariableError {
731 fn name(&self) -> &str { "UndefinedVariable" }
732
733 fn message(&self) -> String {
734 format!("Undefined variable: {}", self.id)
735 }
736}
737
738#[derive(Debug, Clone)]
739pub struct NotMutableError {
740 pub id: u64,
741}
742impl MechErrorKind2 for NotMutableError {
743 fn name(&self) -> &str { "NotMutable" }
744 fn message(&self) -> String {
745 format!("Variable is not mutable: {}", self.id)
746 }
747}
748
749#[cfg(feature = "record")]
750#[derive(Debug, Clone)]
751pub struct UnableToConvertRecordError {
752 pub source_record_kind: ValueKind,
753 pub target_record_kind: ValueKind,
754}
755#[cfg(feature = "record")]
756impl MechErrorKind2 for UnableToConvertRecordError {
757 fn name(&self) -> &str {
758 "UnableToConvertRecord"
759 }
760 fn message(&self) -> String {
761 format!("Unable to convert record of kind `{:?}` to record of kind `{:?}`", self.source_record_kind, self.target_record_kind)
762 }
763}
764