1use crate::*;
2use std::collections::HashMap;
3
4pub type Environment = HashMap<u64, Value>;
8
9pub fn expression(expr: &Expression, env: Option<&Environment>, p: &Interpreter) -> MResult<Value> {
10 match &expr {
11 #[cfg(feature = "variables")]
12 Expression::Var(v) => var(v, env, p),
13 #[cfg(feature = "range")]
14 Expression::Range(rng) => range(&rng, env, p),
15 #[cfg(all(feature = "subscript_slice", feature = "access"))]
16 Expression::Slice(slc) => slice(&slc, env, p),
17 #[cfg(feature = "formulas")]
18 Expression::Formula(fctr) => factor(fctr, env, p),
19 Expression::Structure(strct) => structure(strct, env, p),
20 Expression::Literal(ltrl) => literal(<rl, p),
21 #[cfg(feature = "functions")]
22 Expression::FunctionCall(fxn_call) => function_call(fxn_call, p),
23 #[cfg(feature = "set_comprehensions")]
24 Expression::SetComprehension(set_comp) => set_comprehension(set_comp, p),
25 x => Err(MechError2::new(
27 FeatureNotEnabledError,
28 None
29 ).with_compiler_loc().with_tokens(x.tokens())),
30 }
31}
32
33pub fn match_value(pattern: &Pattern,value: &Value,env: &mut Environment) -> MResult<()> {
34 match pattern {
35 Pattern::Wildcard => Ok(()),
36 Pattern::Expression(expr) => match expr {
37 Expression::Var(var) => {
38 let id = &var.name.hash();
39 match env.get(id) {
40 Some(existing) if existing == value => Ok(()),
41 Some(_) => todo!(),
42 None => {
43 env.insert(id.clone(), value.clone());
44 Ok(())
45 }
46 }
47 },
48 _ => todo!("Unsupported expression in pattern"),
49 },
50 #[cfg(feature = "tuple")]
51 Pattern::Tuple(pat_tuple) => {
52 match value {
53 Value::Tuple(values) => {
54 let values_brrw = values.borrow();
55 if pat_tuple.0.len() != values_brrw.elements.len() {
56 return Err(MechError2::new(
57 ArityMismatchError{
58 expected: pat_tuple.0.len(),
59 found: values_brrw.elements.len(),
60 },
61 None
62 ).with_compiler_loc());
63 }
64 for (pat, val) in pat_tuple.0.iter().zip(values_brrw.elements.iter()) {
65 match_value(pat, val, env)?;
66 }
67 Ok(())
68 }
69 _ => Err(MechError2::new(
70 PatternExpectedTupleError{
71 found: value.kind(),
72 },
73 None
74 ).with_compiler_loc()),
75 }
76 },
77 Pattern::TupleStruct(pat_struct) => {
78 todo!("Implement tuple struct pattern matching")
79 },
80 _ => {
81 Err(MechError2::new(
82 FeatureNotEnabledError,
83 None
84 ).with_compiler_loc())
85 }
86 }
87}
88
89#[cfg(feature = "set_comprehensions")]
90pub fn set_comprehension(set_comp: &SetComprehension,p: &Interpreter) -> MResult<Value> {
91 let mut envs: Vec<Environment> = vec![HashMap::new()];
92 for qual in &set_comp.qualifiers {
94 envs = match qual {
95 ComprehensionQualifier::Generator((pattern, expr)) => {
96 let mut new_envs = Vec::new();
97 for env in &envs {
98 let collection = expression(expr, Some(env), p)?;
100 match collection {
101 Value::Set(mset) => {
102 let set_brrw = mset.borrow();
103
104 for element in set_brrw.set.iter() {
105 let mut new_env = env.clone();
106
107 if match_value(pattern, element, &mut new_env).is_ok() {
109 new_envs.push(new_env);
110 }
111 }
113 }
114 Value::MutableReference(ref_set) => {
115 let ref_set_brrw = ref_set.borrow();
116 match &*ref_set_brrw {
117 Value::Set(mset) => {
118 let set_brrw = mset.borrow();
119
120 for element in set_brrw.set.iter() {
121 let mut new_env = env.clone();
122
123 if match_value(pattern, element, &mut new_env).is_ok() {
125 new_envs.push(new_env);
126 }
127 }
129 }
130 x => return Err(MechError2::new(
131 SetComprehensionGeneratorError{
132 found: x.kind(),
133 },
134 None
135 ).with_compiler_loc()),
136 }
137 }
138 x => return Err(MechError2::new(
139 SetComprehensionGeneratorError{
140 found: x.kind(),
141 },
142 None
143 ).with_compiler_loc()),
144 }
145 }
146 new_envs
147 }
148 ComprehensionQualifier::Filter(expr) => {
149 envs
151 .into_iter()
152 .filter(|env| {
153 println!("Evaluating filter in env: {:#?}", env);
154 match expression(expr, Some(env), p) {
155 Ok(Value::Bool(v)) => v.borrow().clone(),
156 x => {
157 println!("Filter did not evaluate to bool: {:?}", x);
158 false
159 }
160 Err(_) => false,
161 }
162 })
163 .collect()
164 }
165 ComprehensionQualifier::Let(var_def) => {
166 envs.into_iter()
167 .map(|mut env| -> MResult<_> {
168 let val = expression(&var_def.expression, Some(&env), p)?;
169 env.insert(var_def.var.name.hash(), val);
170 Ok(env)
171 })
172 .collect::<MResult<Vec<_>>>()?
173 }
174 };
175 }
176 let mut result_set = IndexSet::new();
178 for env in envs {
179 let val = expression(&set_comp.expression, Some(&env), p)?;
180 if !result_set.contains(&val) {
181 result_set.insert(val);
182 }
183 }
184 Ok(Value::Set(Ref::new(MechSet::from_set(result_set))))
185}
186
187
188#[cfg(feature = "range")]
189pub fn range(rng: &RangeExpression, env: Option<&Environment>, p: &Interpreter) -> MResult<Value> {
190 let plan = p.plan();
191 let start = factor(&rng.start, env, p)?;
192 let terminal = factor(&rng.terminal, env, p)?;
193 let new_fxn = match &rng.operator {
194 #[cfg(feature = "range_exclusive")]
195 RangeOp::Exclusive => RangeExclusive{}.compile(&vec![start,terminal])?,
196 #[cfg(feature = "range_inclusive")]
197 RangeOp::Inclusive => RangeInclusive{}.compile(&vec![start,terminal])?,
198 x => unreachable!(),
199 };
200 let mut plan_brrw = plan.borrow_mut();
201 plan_brrw.push(new_fxn);
202 let step = plan_brrw.last().unwrap();
203 step.solve();
204 let res = step.out();
205 Ok(res)
206}
207
208#[cfg(all(feature = "subscript_slice", feature = "access"))]
209pub fn slice(slc: &Slice, env: Option<&Environment>,p: &Interpreter) -> MResult<Value> {
210 let id = slc.name.hash();
211 let val: Value = if let Some(env) = env {
212 if let Some(val) = env.get(&id) {
213 val.clone()
214 } else {
215 match p.symbols().borrow().get(id) {
217 Some(val) => Value::MutableReference(val.clone()),
218 None => {
219 return Err(MechError2::new(
220 UndefinedVariableError { id },
221 None,
222 )
223 .with_compiler_loc()
224 .with_tokens(slc.tokens()))
225 }
226 }
227 }
228 } else {
229 match p.symbols().borrow().get(id) {
230 Some(val) => Value::MutableReference(val.clone()),
231 None => {
232 return Err(MechError2::new(
233 UndefinedVariableError { id },
234 None,
235 )
236 .with_compiler_loc()
237 .with_tokens(slc.tokens()))
238 }
239 }
240 };
241 let mut v = val;
242 for s in &slc.subscript {
243 v = subscript(s, &v, env, p)?;
244 }
245 Ok(v)
246}
247
248#[cfg(feature = "subscript_formula")]
249pub fn subscript_formula(sbscrpt: &Subscript, env: Option<&Environment>, p: &Interpreter) -> MResult<Value> {
250 match sbscrpt {
251 Subscript::Formula(fctr) => {
252 let result = factor(fctr, env, p)?;
253 result.as_index()
254 }
255 _ => unreachable!()
256 }
257}
258
259#[cfg(feature = "subscript_range")]
260pub fn subscript_range(sbscrpt: &Subscript, env: Option<&Environment>, p: &Interpreter) -> MResult<Value> {
261 match sbscrpt {
262 Subscript::Range(rng) => {
263 let result = range(rng, env, p)?;
264 match result.as_vecusize() {
265 Ok(v) => Ok(v.to_value()),
266 Err(_) => Err(MechError2::new(
267 InvalidIndexKindError { kind: result.kind() },
268 None
269 ).with_compiler_loc().with_tokens(rng.tokens())
270 ),
271 }
272 }
273 _ => unreachable!()
274 }
275}
276
277#[cfg(all(feature = "subscript", feature = "access"))]
278pub fn subscript(sbscrpt: &Subscript, val: &Value, env: Option<&Environment>, p: &Interpreter) -> MResult<Value> {
279 let plan = p.plan();
280 match sbscrpt {
281 #[cfg(feature = "table")]
282 Subscript::Dot(x) => {
283 let key = x.hash();
284 let fxn_input: Vec<Value> = vec![val.clone(), Value::Id(key)];
285 let new_fxn = AccessColumn{}.compile(&fxn_input)?;
286 new_fxn.solve();
287 let res = new_fxn.out();
288 plan.borrow_mut().push(new_fxn);
289 return Ok(res);
290 },
291 Subscript::DotInt(x) => {
292 let mut fxn_input = vec![val.clone()];
293 let result = real(&x.clone());
294 fxn_input.push(result.as_index()?);
295 match val.deref_kind() {
296 #[cfg(feature = "matrix")]
297 ValueKind::Matrix(..) => {
298 let new_fxn = MatrixAccessScalar{}.compile(&fxn_input)?;
299 new_fxn.solve();
300 let res = new_fxn.out();
301 plan.borrow_mut().push(new_fxn);
302 return Ok(res);
303 },
304 #[cfg(feature = "tuple")]
305 ValueKind::Tuple(..) => {
306 let new_fxn = TupleAccess{}.compile(&fxn_input)?;
307 new_fxn.solve();
308 let res = new_fxn.out();
309 plan.borrow_mut().push(new_fxn);
310 return Ok(res);
311 },
312 _ => todo!("Implement access for dot int"),
320 }
321 },
322 #[cfg(feature = "swizzle")]
323 Subscript::Swizzle(x) => {
324 let mut keys = x.iter().map(|x| Value::Id(x.hash())).collect::<Vec<Value>>();
325 let mut fxn_input: Vec<Value> = vec![val.clone()];
326 fxn_input.append(&mut keys);
327 let new_fxn = AccessSwizzle{}.compile(&fxn_input)?;
328 new_fxn.solve();
329 let res = new_fxn.out();
330 plan.borrow_mut().push(new_fxn);
331 return Ok(res);
332 },
333 #[cfg(feature = "subscript_slice")]
334 Subscript::Brace(subs) |
335 Subscript::Bracket(subs) => {
336 let mut fxn_input = vec![val.clone()];
337 match &subs[..] {
338 #[cfg(feature = "subscript_formula")]
339 [Subscript::Formula(ix)] => {
340 let result = subscript_formula(&subs[0], env, p)?;
341 let shape = result.shape();
342 fxn_input.push(result);
343 match shape[..] {
344 [1,1] => plan.borrow_mut().push(AccessScalar{}.compile(&fxn_input)?),
345 #[cfg(feature = "subscript_range")]
346 [1,n] => plan.borrow_mut().push(AccessRange{}.compile(&fxn_input)?),
347 #[cfg(feature = "subscript_range")]
348 [n,1] => plan.borrow_mut().push(AccessRange{}.compile(&fxn_input)?),
349 _ => todo!(),
350 }
351 },
352 #[cfg(feature = "subscript_range")]
353 [Subscript::Range(ix)] => {
354 let result = subscript_range(&subs[0], env, p)?;
355 fxn_input.push(result);
356 plan.borrow_mut().push(AccessRange{}.compile(&fxn_input)?);
357 },
358 #[cfg(feature = "subscript_range")]
359 [Subscript::All] => {
360 fxn_input.push(Value::IndexAll);
361 #[cfg(feature = "matrix")]
362 plan.borrow_mut().push(MatrixAccessAll{}.compile(&fxn_input)?);
363 },
364 [Subscript::All,Subscript::All] => todo!(),
365 #[cfg(feature = "subscript_formula")]
366 [Subscript::Formula(ix1),Subscript::Formula(ix2)] => {
367 let result = subscript_formula(&subs[0], env, p)?;
368 let shape1 = result.shape();
369 fxn_input.push(result);
370 let result = subscript_formula(&subs[1], env, p)?;
371 let shape2 = result.shape();
372 fxn_input.push(result);
373 match ((shape1[0],shape1[1]),(shape2[0],shape2[1])) {
374 #[cfg(feature = "matrix")]
375 ((1,1),(1,1)) => plan.borrow_mut().push(MatrixAccessScalarScalar{}.compile(&fxn_input)?),
376 #[cfg(feature = "matrix")]
377 ((1,1),(m,1)) => plan.borrow_mut().push(MatrixAccessScalarRange{}.compile(&fxn_input)?),
378 #[cfg(feature = "matrix")]
379 ((n,1),(1,1)) => plan.borrow_mut().push(MatrixAccessRangeScalar{}.compile(&fxn_input)?),
380 #[cfg(feature = "matrix")]
381 ((n,1),(m,1)) => plan.borrow_mut().push(MatrixAccessRangeRange{}.compile(&fxn_input)?),
382 _ => unreachable!(),
383 }
384 },
385 #[cfg(feature = "subscript_range")]
386 [Subscript::Range(ix1),Subscript::Range(ix2)] => {
387 let result = subscript_range(&subs[0], env, p)?;
388 fxn_input.push(result);
389 let result = subscript_range(&subs[1], env, p)?;
390 fxn_input.push(result);
391 #[cfg(feature = "matrix")]
392 plan.borrow_mut().push(MatrixAccessRangeRange{}.compile(&fxn_input)?);
393 },
394 #[cfg(all(feature = "subscript_range", feature = "subscript_formula"))]
395 [Subscript::All,Subscript::Formula(ix2)] => {
396 fxn_input.push(Value::IndexAll);
397 let result = subscript_formula(&subs[1], env, p)?;
398 let shape = result.shape();
399 fxn_input.push(result);
400 match &shape[..] {
401 #[cfg(feature = "matrix")]
402 [1,1] => plan.borrow_mut().push(MatrixAccessAllScalar{}.compile(&fxn_input)?),
403 #[cfg(feature = "matrix")]
404 [1,n] => plan.borrow_mut().push(MatrixAccessAllRange{}.compile(&fxn_input)?),
405 #[cfg(feature = "matrix")]
406 [n,1] => plan.borrow_mut().push(MatrixAccessAllRange{}.compile(&fxn_input)?),
407 _ => todo!(),
408 }
409 },
410 #[cfg(all(feature = "subscript_range", feature = "subscript_formula"))]
411 [Subscript::Formula(ix1),Subscript::All] => {
412 let result = subscript_formula(&subs[0], env, p)?;
413 let shape = result.shape();
414 fxn_input.push(result);
415 fxn_input.push(Value::IndexAll);
416 match &shape[..] {
417 #[cfg(feature = "matrix")]
418 [1,1] => plan.borrow_mut().push(MatrixAccessScalarAll{}.compile(&fxn_input)?),
419 #[cfg(feature = "matrix")]
420 [1,n] => plan.borrow_mut().push(MatrixAccessRangeAll{}.compile(&fxn_input)?),
421 #[cfg(feature = "matrix")]
422 [n,1] => plan.borrow_mut().push(MatrixAccessRangeAll{}.compile(&fxn_input)?),
423 _ => todo!(),
424 }
425 },
426 #[cfg(all(feature = "subscript_range", feature = "subscript_formula"))]
427 [Subscript::Range(ix1),Subscript::Formula(ix2)] => {
428 let result = subscript_range(&subs[0], env, p)?;
429 fxn_input.push(result);
430 let result = subscript_formula(&subs[1], env, p)?;
431 let shape = result.shape();
432 fxn_input.push(result);
433 match &shape[..] {
434 #[cfg(feature = "matrix")]
435 [1,1] => plan.borrow_mut().push(MatrixAccessRangeScalar{}.compile(&fxn_input)?),
436 #[cfg(feature = "matrix")]
437 [1,n] => plan.borrow_mut().push(MatrixAccessRangeRange{}.compile(&fxn_input)?),
438 #[cfg(feature = "matrix")]
439 [n,1] => plan.borrow_mut().push(MatrixAccessRangeRange{}.compile(&fxn_input)?),
440 _ => todo!(),
441 }
442 },
443 #[cfg(all(feature = "subscript_range", feature = "subscript_formula"))]
444 [Subscript::Formula(ix1),Subscript::Range(ix2)] => {
445 let result = subscript_formula(&subs[0], env, p)?;
446 let shape = result.shape();
447 fxn_input.push(result);
448 let result = subscript_range(&subs[1], env, p)?;
449 fxn_input.push(result);
450 match &shape[..] {
451 #[cfg(feature = "matrix")]
452 [1,1] => plan.borrow_mut().push(MatrixAccessScalarRange{}.compile(&fxn_input)?),
453 #[cfg(feature = "matrix")]
454 [1,n] => plan.borrow_mut().push(MatrixAccessRangeRange{}.compile(&fxn_input)?),
455 #[cfg(feature = "matrix")]
456 [n,1] => plan.borrow_mut().push(MatrixAccessRangeRange{}.compile(&fxn_input)?),
457 _ => todo!(),
458 }
459 },
460 #[cfg(feature = "subscript_range")]
461 [Subscript::All,Subscript::Range(ix2)] => {
462 fxn_input.push(Value::IndexAll);
463 let result = subscript_range(&subs[1], env, p)?;
464 fxn_input.push(result);
465 #[cfg(feature = "matrix")]
466 plan.borrow_mut().push(MatrixAccessAllRange{}.compile(&fxn_input)?);
467 },
468 #[cfg(feature = "subscript_range")]
469 [Subscript::Range(ix1),Subscript::All] => {
470 let result = subscript_range(&subs[0], env, p)?;
471 fxn_input.push(result);
472 fxn_input.push(Value::IndexAll);
473 #[cfg(feature = "matrix")]
474 plan.borrow_mut().push(MatrixAccessRangeAll{}.compile(&fxn_input)?);
475 },
476 _ => unreachable!(),
477 };
478 let plan_brrw = plan.borrow();
479 let mut new_fxn = &plan_brrw.last().unwrap();
480 new_fxn.solve();
481 let res = new_fxn.out();
482 return Ok(res);
483 },
484 _ => unreachable!(),
485 }
486}
487
488#[cfg(feature = "symbol_table")]
489pub fn var(v: &Var, env: Option<&Environment>, p: &Interpreter) -> MResult<Value> {
490 let state_brrw = p.state.borrow();
491 let symbols_brrw = state_brrw.symbol_table.borrow();
492 let id = v.name.hash();
493 println!("Looking up variable with id: {} in env: {:?}", id, env);
494 match env {
495 Some(env) => {
496 match env.get(&id) {
497 Some(value) => {
498 return Ok(value.clone())
499 }
500 None => {
501 match symbols_brrw.get(id) {
502 Some(value) => {
503 return Ok(Value::MutableReference(value.clone()))
504 }
505 None => {
506 return Err(MechError2::new(
507 UndefinedVariableError { id },
508 None
509 ).with_compiler_loc().with_tokens(v.tokens())
510 )
511 }
512 }
513 }
514 }
515 }
516 None => {
517 match symbols_brrw.get(id) {
518 Some(value) => {
519 return Ok(Value::MutableReference(value.clone()))
520 }
521 None => {
522 return Err(MechError2::new(
523 UndefinedVariableError { id },
524 None
525 ).with_compiler_loc().with_tokens(v.tokens())
526 )
527 }
528 }
529 }
530 }
531}
532
533#[cfg(feature = "formulas")]
534pub fn factor(fctr: &Factor, env: Option<&Environment>, p: &Interpreter) -> MResult<Value> {
535 match fctr {
536 Factor::Term(trm) => {
537 let result = term(trm, env, p)?;
538 Ok(result)
539 },
540 Factor::Parenthetical(paren) => factor(&*paren, env, p),
541 Factor::Expression(expr) => expression(expr, env, p),
542 #[cfg(feature = "math_neg")]
543 Factor::Negate(neg) => {
544 let value = factor(neg, env, p)?;
545 let new_fxn = MathNegate{}.compile(&vec![value])?;
546 new_fxn.solve();
547 let out = new_fxn.out();
548 p.state.borrow_mut().add_plan_step(new_fxn);
549 Ok(out)
550 },
551 #[cfg(feature = "logic_not")]
552 Factor::Not(neg) => {
553 let value = factor(neg, env, p)?;
554 let new_fxn = LogicNot{}.compile(&vec![value])?;
555 new_fxn.solve();
556 let out = new_fxn.out();
557 p.state.borrow_mut().add_plan_step(new_fxn);
558 Ok(out)
559 },
560 #[cfg(feature = "matrix_transpose")]
561 Factor::Transpose(fctr) => {
562 use mech_matrix::MatrixTranspose;
563 let value = factor(fctr, env, p)?;
564 let new_fxn = MatrixTranspose{}.compile(&vec![value])?;
565 new_fxn.solve();
566 let out = new_fxn.out();
567 p.state.borrow_mut().add_plan_step(new_fxn);
568 Ok(out)
569 }
570 _ => todo!(),
571 }
572}
573
574#[cfg(feature = "formulas")]
575pub fn term(trm: &Term, env: Option<&Environment>, p: &Interpreter) -> MResult<Value> {
576 let plan = p.plan();
577 let mut lhs = factor(&trm.lhs, env, p)?;
578 let mut term_plan: Vec<Box<dyn MechFunction>> = vec![];
579 for (op,rhs) in &trm.rhs {
580 let rhs = factor(&rhs, env, p)?;
581 let new_fxn: Box<dyn MechFunction> = match op {
582 #[cfg(feature = "math_add")]
584 FormulaOperator::AddSub(AddSubOp::Add) => MathAdd{}.compile(&vec![lhs,rhs])?,
585 #[cfg(feature = "math_sub")]
586 FormulaOperator::AddSub(AddSubOp::Sub) => MathSub{}.compile(&vec![lhs,rhs])?,
587 #[cfg(feature = "math_mul")]
588 FormulaOperator::MulDiv(MulDivOp::Mul) => MathMul{}.compile(&vec![lhs,rhs])?,
589 #[cfg(feature = "math_div")]
590 FormulaOperator::MulDiv(MulDivOp::Div) => MathDiv{}.compile(&vec![lhs,rhs])?,
591 #[cfg(feature = "math_mod")]
592 FormulaOperator::MulDiv(MulDivOp::Mod) => MathMod{}.compile(&vec![lhs,rhs])?,
593 #[cfg(feature = "math_pow")]
594 FormulaOperator::Power(PowerOp::Pow) => MathPow{}.compile(&vec![lhs,rhs])?,
595
596 #[cfg(feature = "matrix_matmul")]
598 FormulaOperator::Vec(VecOp::MatMul) => {
599 use mech_matrix::MatrixMatMul;
600 MatrixMatMul{}.compile(&vec![lhs,rhs])?
601 }
602 #[cfg(feature = "matrix_solve")]
603 FormulaOperator::Vec(VecOp::Solve) => MatrixSolve{}.compile(&vec![lhs,rhs])?,
604 #[cfg(feature = "matrix_cross")]
605 FormulaOperator::Vec(VecOp::Cross) => todo!(),
606 #[cfg(feature = "matrix_dot")]
607 FormulaOperator::Vec(VecOp::Dot) => MatrixDot{}.compile(&vec![lhs,rhs])?,
608
609 #[cfg(feature = "compare_eq")]
611 FormulaOperator::Comparison(ComparisonOp::Equal) => CompareEqual{}.compile(&vec![lhs,rhs])?,
612 #[cfg(feature = "compare_seq")]
613 FormulaOperator::Comparison(ComparisonOp::StrictEqual) => todo!(), #[cfg(feature = "compare_neq")]
615 FormulaOperator::Comparison(ComparisonOp::NotEqual) => CompareNotEqual{}.compile(&vec![lhs,rhs])?,
616 #[cfg(feature = "compare_sneq")]
617 FormulaOperator::Comparison(ComparisonOp::StrictNotEqual) => todo!(), #[cfg(feature = "compare_lte")]
619 FormulaOperator::Comparison(ComparisonOp::LessThanEqual) => CompareLessThanEqual{}.compile(&vec![lhs,rhs])?,
620 #[cfg(feature = "compare_gte")]
621 FormulaOperator::Comparison(ComparisonOp::GreaterThanEqual) => CompareGreaterThanEqual{}.compile(&vec![lhs,rhs])?,
622 #[cfg(feature = "compare_lt")]
623 FormulaOperator::Comparison(ComparisonOp::LessThan) => CompareLessThan{}.compile(&vec![lhs,rhs])?,
624 #[cfg(feature = "compare_gt")]
625 FormulaOperator::Comparison(ComparisonOp::GreaterThan) => CompareGreaterThan{}.compile(&vec![lhs,rhs])?,
626
627 #[cfg(feature = "logic_and")]
629 FormulaOperator::Logic(LogicOp::And) => LogicAnd{}.compile(&vec![lhs,rhs])?,
630 #[cfg(feature = "logic_or")]
631 FormulaOperator::Logic(LogicOp::Or) => LogicOr{}.compile(&vec![lhs,rhs])?,
632 #[cfg(feature = "logic_not")]
633 FormulaOperator::Logic(LogicOp::Not) => LogicNot{}.compile(&vec![lhs,rhs])?,
634 #[cfg(feature = "logic_xor")]
635 FormulaOperator::Logic(LogicOp::Xor) => LogicXor{}.compile(&vec![lhs,rhs])?,
636
637 #[cfg(feature = "table_inner_join")]
639 FormulaOperator::Table(TableOp::InnerJoin) => todo!(),
640 #[cfg(feature = "table_left_outer_join")]
641 FormulaOperator::Table(TableOp::LeftOuterJoin) => todo!(),
642 #[cfg(feature = "table_right_outer_join")]
643 FormulaOperator::Table(TableOp::RightOuterJoin) => todo!(),
644 #[cfg(feature = "table_full_outer_join")]
645 FormulaOperator::Table(TableOp::FullOuterJoin) => todo!(),
646 #[cfg(feature = "table_left_semi_join")]
647 FormulaOperator::Table(TableOp::LeftSemiJoin) => todo!(),
648 #[cfg(feature = "table_left_anti_join")]
649 FormulaOperator::Table(TableOp::LeftAntiJoin) => todo!(),
650
651 #[cfg(feature = "set_union")]
653 FormulaOperator::Set(SetOp::Union) => SetUnion{}.compile(&vec![lhs,rhs])?,
654 #[cfg(feature = "set_intersection")]
655 FormulaOperator::Set(SetOp::Intersection) => SetIntersection{}.compile(&vec![lhs,rhs])?,
656 #[cfg(feature = "set_difference")]
657 FormulaOperator::Set(SetOp::Difference) => SetDifference{}.compile(&vec![lhs,rhs])?,
658 #[cfg(feature = "set_symmetric_difference")]
659 FormulaOperator::Set(SetOp::SymmetricDifference) => SetSymmetricDifference{}.compile(&vec![lhs,rhs])?,
660 #[cfg(feature = "set_complement")]
661 FormulaOperator::Set(SetOp::Complement) => todo!(),
662 #[cfg(feature = "set_subset")]
663 FormulaOperator::Set(SetOp::Subset) => SetSubset{}.compile(&vec![lhs,rhs])?,
664 #[cfg(feature = "set_superset")]
665 FormulaOperator::Set(SetOp::Superset) => SetSuperset{}.compile(&vec![lhs,rhs])?,
666 #[cfg(feature = "set_proper_subset")]
667 FormulaOperator::Set(SetOp::ProperSubset) => SetProperSubset{}.compile(&vec![lhs,rhs])?,
668 #[cfg(feature = "set_proper_superset")]
669 FormulaOperator::Set(SetOp::ProperSuperset) => SetProperSuperset{}.compile(&vec![lhs,rhs])?,
670 #[cfg(feature = "set_element_of")]
671 FormulaOperator::Set(SetOp::ElementOf) => SetElementOf{}.compile(&vec![lhs,rhs])?,
672 #[cfg(feature = "set_not_element_of")]
673 FormulaOperator::Set(SetOp::NotElementOf) => SetNotElementOf{}.compile(&vec![lhs,rhs])?,
674 x => return Err(MechError2::new(
675 UnhandledFormulaOperatorError { operator: x.clone() },
676 None
677 ).with_compiler_loc().with_tokens(trm.tokens())
678 ),
679 };
680 new_fxn.solve();
681 let res = new_fxn.out();
682 term_plan.push(new_fxn);
683 lhs = res;
684 }
685 let mut plan_brrw = plan.borrow_mut();
686 plan_brrw.append(&mut term_plan);
687 return Ok(lhs);
688}
689
690#[derive(Debug, Clone)]
691pub struct UnhandledFormulaOperatorError {
692 pub operator: FormulaOperator,
693}
694impl MechErrorKind2 for UnhandledFormulaOperatorError {
695 fn name(&self) -> &str { "UnhandledFormulaOperator" }
696 fn message(&self) -> String {
697 format!("Unhandled formula operator: {:#?}", self.operator)
698 }
699}
700
701#[derive(Debug, Clone)]
702pub struct UndefinedVariableError {
703 pub id: u64,
704}
705impl MechErrorKind2 for UndefinedVariableError {
706 fn name(&self) -> &str { "UndefinedVariable" }
707
708 fn message(&self) -> String {
709 format!("Undefined variable: {}", self.id)
710 }
711}
712#[derive(Debug, Clone)]
713pub struct InvalidIndexKindError {
714 kind: ValueKind,
715}
716impl MechErrorKind2 for InvalidIndexKindError {
717 fn name(&self) -> &str {
718 "InvalidIndexKind"
719 }
720 fn message(&self) -> String {
721 "Invalid index kind".to_string()
722 }
723}
724
725#[derive(Debug, Clone)]
726pub struct SetComprehensionGeneratorError{
727 found: ValueKind,
728}
729
730impl MechErrorKind2 for SetComprehensionGeneratorError {
731 fn name(&self) -> &str {
732 "SetComprehensionGenerator"
733 }
734 fn message(&self) -> String {
735 format!("Set comprehension generator must produce a set, found kind: {:?}", self.found)
736 }
737}
738
739#[derive(Debug, Clone)]
740pub struct PatternExpectedTupleError{
741 found: ValueKind,
742}
743impl MechErrorKind2 for PatternExpectedTupleError {
744 fn name(&self) -> &str {
745 "PatternExpectedTuple"
746 }
747 fn message(&self) -> String {
748 format!("Pattern expected a tuple, found kind: {:?}", self.found)
749 }
750}
751
752#[derive(Debug, Clone)]
753pub struct ArityMismatchError {
754 expected: usize,
755 found: usize,
756}
757impl MechErrorKind2 for ArityMismatchError {
758 fn name(&self) -> &str {
759 "ArityMismatch"
760 }
761 fn message(&self) -> String {
762 format!("Arity mismatch: expected {}, found {}", self.expected, self.found)
763 }
764}