This commit is contained in:
2023-06-17 19:08:05 -07:00
parent 1495dcd561
commit 73049eeec4
7 changed files with 197 additions and 250 deletions

View File

@ -1,6 +1,5 @@
use std::cmp::Ordering;
use std::collections::VecDeque;
use crate::quantity::Quantity;
use super::Expression;
use super::Function;
@ -29,9 +28,6 @@ pub enum Operator {
Factorial,
Function(Function),
// Not accessible from prompt
Flip,
}
impl PartialEq for Operator {
@ -111,69 +107,6 @@ impl Operator {
}
}
#[inline(always)]
pub fn into_expression(self, mut args: VecDeque<Expression>) -> Expression {
match self {
Operator::Subtract => {
if args.len() != 2 { panic!() }
let a = args.pop_front().unwrap();
let b = args.pop_front().unwrap();
let b_new;
if let Expression::Quantity(q) = b {
b_new = Expression::Quantity(-q);
} else {
b_new = Expression::Operator(Operator::Negative, VecDeque::from(vec!(b)));
}
Expression::Operator(
Operator::Add,
VecDeque::from(vec!(a,b_new))
)
},
Operator::DivideLong |
Operator::Divide => {
if args.len() != 2 { panic!() }
let a = args.pop_front().unwrap();
let b = args.pop_front().unwrap();
let b = Expression::Operator(Operator::Flip, VecDeque::from(vec!(b)));
Expression::Operator(
Operator::Multiply,
VecDeque::from(vec!(a,b))
)
},
Operator::Sqrt => {
if args.len() != 1 { panic!() }
let a = args.pop_front().unwrap();
Expression::Operator(
Operator::Power,
VecDeque::from(vec!(a, Expression::Quantity(Quantity::new_rational_from_string("0.5").unwrap())))
)
},
Operator::ImplicitMultiply
=> { Expression::Operator(Operator::Multiply, args) },
Operator::Function(_)
| Operator::Factorial
| Operator::Negative
| Operator::Flip
| Operator::Add
| Operator::Multiply
| Operator::Modulo
| Operator::Power
| Operator::ModuloLong
| Operator::UnitConvert
| Operator::Define
=> { Expression::Operator(self, args) },
}
}
#[inline(always)]
fn add_parens_to_arg(&self, arg: &Expression) -> String {
let mut astr: String = arg.to_string();
@ -199,11 +132,6 @@ impl Operator {
pub fn print(&self, args: &VecDeque<Expression>) -> String {
match self {
Operator::ImplicitMultiply |
Operator::Sqrt |
Operator::Divide |
Operator::Subtract => { panic!() }
Operator::Define => {
return format!(
"{} = {}",
@ -212,14 +140,17 @@ impl Operator {
);
},
Operator::Flip => {
return format!("{}⁻¹", Operator::Divide.add_parens_to_arg(&args[0]));
},
Operator::Negative => {
return format!("-{}", self.add_parens_to_arg(&args[0]));
},
Operator::Sqrt => {
return format!(
"{}",
self.add_parens_to_arg(&args[0]),
);
},
Operator::ModuloLong => {
return format!(
"{} mod {}",
@ -252,6 +183,14 @@ impl Operator {
);
},
Operator::Subtract => {
return format!(
"{} - {}",
self.add_parens_to_arg(&args[0]),
self.add_parens_to_arg(&args[1])
);
},
Operator::Power => {
return format!(
"{}^{}",
@ -265,50 +204,17 @@ impl Operator {
},
Operator::Add => {
let a = &args[0];
let b; let sub;
if let Expression::Operator(o, ar) = &args[1] {
if let Operator::Negative = o {
sub = true;
b = &ar[0];
} else { sub = false; b = &args[1]; }
} else { sub = false; b = &args[1]; }
if sub {
return format!(
"{} - {}",
self.add_parens_to_arg(a),
self.add_parens_to_arg(b)
);
} else {
return format!(
"{} + {}",
self.add_parens_to_arg(a),
self.add_parens_to_arg(b)
);
}
return format!(
"{} + {}",
self.add_parens_to_arg(&args[0]),
self.add_parens_to_arg(&args[1])
);
},
Operator::ImplicitMultiply |
Operator::Multiply => {
let a = &args[0];
let b; let div;
if let Expression::Operator(o, ar) = &args[1] {
if let Operator::Flip = o {
div = true;
b = &ar[0];
} else { div = false; b = &args[1]; }
} else { div = false; b = &args[1]; }
// Division symbol case
if div {
return format!("{} ÷ {}",
self.add_parens_to_arg_strict(a),
self.add_parens_to_arg_strict(b)
);
}
let b = &args[1];
// Omit times sign when we have a number
// multiplied by a unit (like 10 m)
@ -342,6 +248,24 @@ impl Operator {
}
},
Operator::Divide => {
let a = &args[0];
let b = &args[1];
if let Expression::Quantity(q) = a {
if q.is_one() {
return format!("{}⁻¹",
self.add_parens_to_arg_strict(b)
);
}
}
return format!("{} ÷ {}",
self.add_parens_to_arg_strict(a),
self.add_parens_to_arg_strict(b)
);
},
Operator::Function(s) => {
return format!("{}({})", s.to_string(), args[0].to_string());
}