diff --git a/src/main.rs b/src/main.rs index 08fbf2f..7bd7a72 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,13 +3,20 @@ use std::process; fn main() { let args: Vec = 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); diff --git a/src/maths/evaluator.rs b/src/maths/evaluator.rs index 6c863df..2db1a4b 100644 --- a/src/maths/evaluator.rs +++ b/src/maths/evaluator.rs @@ -69,15 +69,15 @@ fn mul(lhs: Vec, rhs: &Vec) -> Vec, rhs: Vec) -> Vec { +fn exp(lhs: Vec, rhs: Vec) -> Result, 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, rhs: Vec) -> Vec, rhs: &Vec) -> bool { @@ -97,12 +97,12 @@ fn check_div(lhs: &Vec, rhs: &Vec) -> bool { true } -fn div(lhs: Vec, rhs: Vec) -> Vec { +fn div(lhs: Vec, rhs: Vec) -> Result, 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, rhs: Vec) -> Vec, rhs: Vec) -> Vec { +fn calculate(operator: Token, lhs: Vec, rhs: Vec) -> Result, 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) -> Vec Vec { +pub fn evaluate(ast: Node) -> Result, 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), } } diff --git a/src/maths/solver.rs b/src/maths/solver.rs index cef3e36..289cdcc 100644 --- a/src/maths/solver.rs +++ b/src/maths/solver.rs @@ -35,6 +35,8 @@ pub fn solve(mut equation: Vec) -> Vec { for i in (1..equation.len()).rev() { if equation[i] == zero() { equation.pop(); + } else { + break; } } crate::pretty(&equation);