refacto(*): manage errors without panics

This commit is contained in:
gbrochar 2023-08-11 16:36:17 +02:00
parent c4f2288861
commit 258a4189c0
3 changed files with 29 additions and 19 deletions

View File

@ -3,13 +3,20 @@ use std::process;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("Error: You need to run this program with exactly 1 argument");
process::exit(1);
}
let equation = computorv1::parse(&args[1]).unwrap_or_else(|e| {
println!("Error during parsing: {e}");
process::exit(1);
});
println!("{:?}", equation);
let is_equation = computorv1::maths::evaluator::is_equation(&equation);
let evaluated = computorv1::maths::evaluator::evaluate(equation);
let evaluated = computorv1::maths::evaluator::evaluate(equation).unwrap_or_else(|e| {
println!("Error during evaluation: {e}");
process::exit(1);
});
computorv1::pretty(&evaluated);
if is_equation {
computorv1::maths::solver::solve(evaluated);

View File

@ -69,15 +69,15 @@ fn mul(lhs: Vec<GaussianRational>, rhs: &Vec<GaussianRational>) -> Vec<GaussianR
res
}
fn exp(lhs: Vec<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRational> {
fn exp(lhs: Vec<GaussianRational>, rhs: Vec<GaussianRational>) -> Result<Vec<GaussianRational>, String> {
if rhs.len() != 1 {
panic!("Eh t'y es fou mon gate puissance d'inconnu !");
return Err(format!("exponential only supports natural exponents, unknown exponents aren't supported"));
}
if rhs[0].imaginary.numerator != 0 {
panic!("Diablerie une puissance complexe !");
return Err(format!("exponential only supports natural exponents, complex exponents aren't supported"));
}
if rhs[0].real.denominator != 1 {
panic!("MON DIEU UNE PUISSANCE DE RATIONNEL");
return Err(format!("exponential only supports natural exponents, rational exponents aren't supported"));
}
let mut res = Vec::new();
let pow = rhs[0].real.numerator;
@ -85,7 +85,7 @@ fn exp(lhs: Vec<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRa
for _ in 0..pow {
res = mul(res, &lhs);
}
res
Ok(res)
}
fn check_div(lhs: &Vec<GaussianRational>, rhs: &Vec<GaussianRational>) -> bool {
@ -97,12 +97,12 @@ fn check_div(lhs: &Vec<GaussianRational>, rhs: &Vec<GaussianRational>) -> bool {
true
}
fn div(lhs: Vec<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRational> {
fn div(lhs: Vec<GaussianRational>, rhs: Vec<GaussianRational>) -> Result<Vec<GaussianRational>, String> {
if rhs.len() > lhs.len() {
panic!("faut pas diviser par plus grande puissance d'inconnu que sois meme :$");
return Err(format!("division supported if the divisor to be of same or smaller degree than the dividend."));
}
if !check_div(&lhs, &rhs) {
panic!("Moi je sais pas faire heing");
return Err(format!("division supported if the divisor has only one non zero coefficient"));
}
let denominator = *rhs.last().unwrap();
@ -117,17 +117,18 @@ fn div(lhs: Vec<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRa
res[res_i] = lhs[i] / denominator;
}
res
Ok(res)
}
fn calculate(operator: Token, lhs: Vec<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRational> {
fn calculate(operator: Token, lhs: Vec<GaussianRational>, rhs: Vec<GaussianRational>) -> Result<Vec<GaussianRational>, String> {
match operator {
Token::Addition() => add(lhs, rhs),
Token::Substraction() => sub(lhs, rhs),
Token::Multiplication() => mul(lhs, &rhs),
Token::Addition() => Ok(add(lhs, rhs)),
Token::Substraction() => Ok(sub(lhs, rhs)),
Token::Multiplication() => Ok(mul(lhs, &rhs)),
Token::Division() => div(lhs, rhs),
Token::Exponentiation() => exp(lhs, rhs),
Token::Equal() => sub(lhs, rhs),
Token::Equal() => Ok(sub(lhs, rhs)),
Token::Modulo() => Err(format!("modulo isn't suported yet by this program.")),
_ => unreachable!(),
}
}
@ -140,11 +141,11 @@ fn calculate_unary(operator: Token, operand: Vec<GaussianRational>) -> Vec<Gauss
}
}
pub fn evaluate(ast: Node) -> Vec<GaussianRational> {
pub fn evaluate(ast: Node) -> Result<Vec<GaussianRational>, String> {
match ast {
Node::Binary { operator, lhs, rhs } => calculate(operator, evaluate(*lhs), evaluate(*rhs)),
Node::Unary { operator, operand } => calculate_unary(operator, evaluate(*operand)),
Node::Leaf(value) => value,
Node::Binary { operator, lhs, rhs } => calculate(operator, evaluate(*lhs)?, evaluate(*rhs)?),
Node::Unary { operator, operand } => Ok(calculate_unary(operator, evaluate(*operand)?)),
Node::Leaf(value) => Ok(value),
}
}

View File

@ -35,6 +35,8 @@ pub fn solve(mut equation: Vec<GaussianRational>) -> Vec<GaussianRational> {
for i in (1..equation.len()).rev() {
if equation[i] == zero() {
equation.pop();
} else {
break;
}
}
crate::pretty(&equation);