feat(maths::evaluator): ast evaluation v1
This commit is contained in:
parent
06a998666f
commit
b92bdf74ee
|
@ -3,9 +3,9 @@ use std::process;
|
|||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let _equation = computorv1::parse(&args[1]).unwrap_or_else(|e| {
|
||||
let equation = computorv1::parse(&args[1]).unwrap_or_else(|e| {
|
||||
println!("Error during parsing: {e}");
|
||||
process::exit(1);
|
||||
});
|
||||
//computorv1::solve(equation);
|
||||
let evaluated = computorv1::maths::evaluator::evaluate(equation);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use std::ops;
|
||||
|
||||
pub mod evaluator;
|
||||
|
||||
//TODO slow ? check Stein's algorithm (binaryGCD)
|
||||
fn gcd(a: i128, b: i128) -> i128 {
|
||||
if b == 0 {
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
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<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRational> {
|
||||
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<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRational> {
|
||||
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<GaussianRational>, rhs: &Vec<GaussianRational>) -> Vec<GaussianRational> {
|
||||
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<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRational> {
|
||||
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<GaussianRational>, rhs: &Vec<GaussianRational>) -> bool {
|
||||
for i in 0..(rhs.len() - 1) {
|
||||
if rhs[i] != zero() || lhs[i] != zero() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn div(lhs: Vec<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRational> {
|
||||
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<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRational> {
|
||||
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<GaussianRational> {
|
||||
match ast {
|
||||
Node::Internal { operator, lhs, rhs } => calculate(operator, evaluate(*lhs), evaluate(*rhs)),
|
||||
Node::Leaf(value) => value,
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue