use super::*; use crate::parser::Token; use crate::Node; fn zero() -> GaussianRational { GaussianRational::new(Rational::new(0, 1), Rational::new(0, 1)) } fn one() -> GaussianRational { GaussianRational::new(Rational::new(1, 1), Rational::new(0, 1)) } fn add(lhs: Vec, rhs: Vec) -> Vec { let mut res = Vec::new(); let mut len = lhs.len(); if rhs.len() > len { len = rhs.len(); } for _ in 0..len { res.push(zero()); } for (i, gr) in lhs.iter().enumerate() { res[i] = res[i] + *gr; } for (i, gr) in rhs.iter().enumerate() { res[i] = res[i] + *gr; } res } fn sub(lhs: Vec, rhs: Vec) -> Vec { let mut res = Vec::new(); let mut len = lhs.len(); if rhs.len() > len { len = rhs.len(); } for _ in 0..len { res.push(zero()); } for (i, gr) in lhs.iter().enumerate() { res[i] = res[i] + *gr; } for (i, gr) in rhs.iter().enumerate() { res[i] = res[i] - *gr; } res } fn mul(lhs: Vec, rhs: &Vec) -> Vec { println!("\nIci ca multiplie {:?} et {:?}", lhs, rhs); let len = lhs.len() + rhs.len() - 1; let mut res = Vec::new(); for _ in 0..len { res.push(zero()); } for (i, lhs) in lhs.iter().enumerate() { for (j, rhs) in rhs.iter().enumerate() { res[i + j] = res[i + j] + *lhs * *rhs; } } res } fn exp(lhs: Vec, rhs: Vec) -> Vec { if rhs.len() != 1 { panic!("Eh t'y es fou mon gate puissance d'inconnu !"); } if rhs[0].imaginary.numerator != 0 { panic!("Diablerie une puissance complexe !"); } if rhs[0].real.denominator != 1 { panic!("MON DIEU UNE PUISSANCE DE RATIONNEL"); } let mut res = Vec::new(); let pow = rhs[0].real.numerator; res.push(one()); for _ in 0..pow { res = mul(res, &lhs); } res } fn check_div(lhs: &Vec, rhs: &Vec) -> bool { for i in 0..(rhs.len() - 1) { if rhs[i] != zero() || lhs[i] != zero() { return false } } true } fn div(lhs: Vec, rhs: Vec) -> Vec { if rhs.len() > lhs.len() { panic!("faut pas diviser par plus grande puissance d'inconnu que sois meme :$"); } if !check_div(&lhs, &rhs) { panic!("Moi je sais pas faire heing"); } let denominator = *rhs.last().unwrap(); let len = lhs.len() - rhs.len() + 1; let mut res = Vec::new(); for _ in 0..len { res.push(zero()); } for i in (rhs.len() - 1)..lhs.len() { let res_i = i - (rhs.len() - 1); res[res_i] = lhs[i] / denominator; } res } fn calculate(operator: Token, lhs: Vec, rhs: Vec) -> Vec { match operator { Token::Addition() => add(lhs, rhs), Token::Substraction() => sub(lhs, rhs), Token::Multiplication() => mul(lhs, &rhs), Token::Division() => div(lhs, rhs), Token::Exponentiation() => exp(lhs, rhs), _ => unreachable!(), } } pub fn evaluate(ast: Node) -> Vec { match ast { Node::Internal { operator, lhs, rhs } => calculate(operator, evaluate(*lhs), evaluate(*rhs)), Node::Leaf(value) => value, } }