feat(maths): creation + clean maths in parser
This commit is contained in:
		
							parent
							
								
									b1eb997703
								
							
						
					
					
						commit
						8e3ebcd2a5
					
				
							
								
								
									
										16
									
								
								src/lib.rs
								
								
								
								
							
							
						
						
									
										16
									
								
								src/lib.rs
								
								
								
								
							|  | @ -4,16 +4,7 @@ use crate::parser::sanitizer::sanitize_tokens; | |||
| use crate::parser::ast_builder::{build_ast, Node}; | ||||
| 
 | ||||
| pub mod parser; | ||||
| 
 | ||||
| struct _Rational { | ||||
|     numerator: i128, | ||||
|     denominator: i128, | ||||
| } | ||||
| 
 | ||||
| struct _GaussianRational { | ||||
|     real: _Rational, | ||||
|     imaginary: _Rational, | ||||
| } | ||||
| pub mod maths; | ||||
| 
 | ||||
| pub fn parse(query: &str) -> Result<Node, Box<dyn Error>> { | ||||
|     let tokens = tokenize(query)?; | ||||
|  | @ -109,8 +100,3 @@ pub fn solve(equation: Vec<f64>) { | |||
|         _ => unreachable!(), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,101 @@ | |||
| use std::ops; | ||||
| 
 | ||||
| //TODO slow ? check Stein's algorithm (binaryGCD)
 | ||||
| fn gcd(a: i128, b: i128) -> i128 { | ||||
|     if b == 0 { | ||||
|         a | ||||
|     } else { | ||||
|         gcd(b, a % b) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, PartialEq, Clone)] | ||||
| pub struct Rational { | ||||
|     numerator: i128, | ||||
|     denominator: i128, | ||||
| } | ||||
| 
 | ||||
| impl Rational { | ||||
|     pub fn new(numerator: i128, denominator: i128) -> Self { | ||||
|         Self { | ||||
|             numerator, | ||||
|             denominator, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn reduce(&self) -> Self { | ||||
|         let gcd = gcd(self.numerator, self.denominator); | ||||
|         Rational::new(self.numerator / gcd, self.denominator / gcd) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ops::Add<Rational> for Rational { | ||||
|     type Output = Rational; | ||||
| 
 | ||||
|     fn add(self, rhs: Rational) -> Rational { | ||||
|         Rational::new(self.numerator * rhs.denominator + rhs.numerator * self.denominator, self.denominator * rhs.denominator).reduce() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ops::Add<i128> for Rational { | ||||
|     type Output = Rational; | ||||
| 
 | ||||
|     fn add(self, rhs: i128) -> Rational { | ||||
|         Rational::new(self.numerator + rhs * self.denominator, self.denominator).reduce() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ops::Add<Rational> for i128 { | ||||
|     type Output = Rational; | ||||
| 
 | ||||
|     fn add(self, rhs: Rational) -> Rational { | ||||
|         Rational::new(self * rhs.denominator + rhs.numerator, rhs.denominator).reduce() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ops::Sub<Rational> for Rational { | ||||
|     type Output = Rational; | ||||
| 
 | ||||
|     fn sub(self, rhs: Rational) -> Rational { | ||||
|         Rational::new(self.numerator * rhs.denominator - rhs.numerator * self.denominator, self.denominator * rhs.denominator).reduce() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ops::Mul<Rational> for Rational { | ||||
|     type Output = Rational; | ||||
| 
 | ||||
|     fn mul(self, rhs: Rational) -> Rational { | ||||
|         Rational::new(self.numerator * rhs.numerator, self.denominator * rhs.denominator).reduce() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ops::Mul<i128> for Rational { | ||||
|     type Output = Rational; | ||||
| 
 | ||||
|     fn mul(self, rhs: i128) -> Rational { | ||||
|         Rational::new(self.numerator * rhs, self.denominator).reduce() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ops::Mul<Rational> for i128 { | ||||
|     type Output = Rational; | ||||
| 
 | ||||
|     fn mul(self, rhs: Rational) -> Rational { | ||||
|         Rational::new(self * rhs.numerator, rhs.denominator).reduce() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, PartialEq, Clone)] | ||||
| pub struct GaussianRational { | ||||
|     real: Rational, | ||||
|     imaginary: Rational, | ||||
| } | ||||
| 
 | ||||
| impl GaussianRational { | ||||
|     pub fn new(real: Rational, imaginary: Rational) -> Self { | ||||
|         Self { | ||||
|             real, | ||||
|             imaginary, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,17 +1,5 @@ | |||
| use super::Token; | ||||
| 
 | ||||
| #[derive(Debug, PartialEq, Clone)] | ||||
| pub struct Rational { | ||||
|     numerator: i128, | ||||
|     denominator: i128, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, PartialEq, Clone)] | ||||
| pub struct GaussianRational { | ||||
|     real: Rational, | ||||
|     imaginary: Rational, | ||||
| } | ||||
| 
 | ||||
| use crate::maths::{GaussianRational, Rational}; | ||||
| 
 | ||||
| #[derive(Debug, PartialEq, Clone)] | ||||
| pub enum Node { | ||||
|  | @ -23,76 +11,37 @@ pub enum Node { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| /* | ||||
|    pub struct Node { | ||||
|    _lhs: Option<Box<Node>>, | ||||
|    _rhs: Option<Box<Node>>, | ||||
|    } | ||||
|    */ | ||||
| 
 | ||||
| fn zero() -> GaussianRational { | ||||
|     GaussianRational { | ||||
|         real: Rational { | ||||
|             numerator: 0, | ||||
|             denominator: 1, | ||||
|         }, | ||||
|         imaginary: Rational { | ||||
|             numerator: 0, | ||||
|             denominator: 1, | ||||
|         } | ||||
|     } | ||||
| fn rational_zero() -> Rational { | ||||
|     Rational::new(0, 1) | ||||
| } | ||||
| 
 | ||||
| fn minus_one() -> GaussianRational { | ||||
|     GaussianRational { | ||||
|         real: Rational { | ||||
|             numerator: -1, | ||||
|             denominator: 1, | ||||
|         }, | ||||
|         imaginary: Rational { | ||||
|             numerator: 0, | ||||
|             denominator: 1, | ||||
|         } | ||||
|     } | ||||
| fn rational_one() -> Rational { | ||||
|     Rational::new(1, 1) | ||||
| } | ||||
| 
 | ||||
| fn rational_minus_one() -> Rational { | ||||
|     Rational::new(-1, 1) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| fn zero() -> GaussianRational { | ||||
|     GaussianRational::new(rational_zero(), rational_zero()) | ||||
| } | ||||
| 
 | ||||
| fn one() -> GaussianRational { | ||||
|     GaussianRational { | ||||
|         real: Rational { | ||||
|             numerator: 1, | ||||
|             denominator: 1, | ||||
|         }, | ||||
|         imaginary: Rational { | ||||
|             numerator: 0, | ||||
|             denominator: 1, | ||||
|         } | ||||
|     } | ||||
|     GaussianRational::new(rational_one(), rational_zero()) | ||||
| } | ||||
| 
 | ||||
| fn minus_one() -> GaussianRational { | ||||
|     GaussianRational::new(rational_minus_one(), rational_zero()) | ||||
| } | ||||
| 
 | ||||
| fn i() -> GaussianRational { | ||||
|     GaussianRational { | ||||
|         real: Rational { | ||||
|             numerator: 0, | ||||
|             denominator: 1, | ||||
|         }, | ||||
|         imaginary: Rational { | ||||
|             numerator: 1, | ||||
|             denominator: 1, | ||||
|         } | ||||
|     } | ||||
|     GaussianRational::new(rational_zero(), rational_one()) | ||||
| } | ||||
| 
 | ||||
| fn minus_i() -> GaussianRational { | ||||
|     GaussianRational { | ||||
|         real: Rational { | ||||
|             numerator: 0, | ||||
|             denominator: 1, | ||||
|         }, | ||||
|         imaginary: Rational { | ||||
|             numerator: -1, | ||||
|             denominator: 1, | ||||
|         } | ||||
|     } | ||||
|     GaussianRational::new(rational_zero(), rational_minus_one()) | ||||
| } | ||||
| 
 | ||||
| fn x() -> Vec<GaussianRational> { | ||||
|  | @ -128,34 +77,25 @@ fn get_parentheses_map(tokens: &Vec<Token>) -> Vec<usize> { | |||
| } | ||||
| 
 | ||||
| fn parse_number(string: &String, sign: i128) -> GaussianRational { | ||||
|     let mut number = Rational { | ||||
|         numerator: 0, | ||||
|         denominator: 1, | ||||
|     }; | ||||
|     let mut number = rational_zero(); | ||||
|     let mut is_floating = false; | ||||
| 
 | ||||
|     for c in string.chars() { | ||||
|         match c { | ||||
|             '.' => is_floating = true, | ||||
|             '0'..='9' => { | ||||
|                 number.numerator = 10 * number.numerator + String::from(c).parse::<i128>().unwrap(); | ||||
|                 number = 10 * number + String::from(c).parse::<i128>().unwrap(); | ||||
|                 if is_floating == true { | ||||
|                     number.denominator *= 10; | ||||
|                     number = number * Rational::new(1, 10); | ||||
|                 } | ||||
|             } | ||||
|             _ => unreachable!(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     number.numerator *= sign; | ||||
|     number = number * sign; | ||||
| 
 | ||||
|     GaussianRational { | ||||
|         real: number, | ||||
|         imaginary: Rational { | ||||
|             numerator: 0, | ||||
|             denominator: 1, | ||||
|         } | ||||
|     } | ||||
|     GaussianRational::new(number, rational_zero()) | ||||
| } | ||||
| 
 | ||||
| fn check_parentheses(tokens: &Vec<Token>) -> bool { | ||||
|  | @ -432,8 +372,7 @@ mod tests { | |||
| 
 | ||||
|     #[test] | ||||
|     fn two_plus_two() { | ||||
|         let mut two = one(); | ||||
|         two.real.numerator = 2; | ||||
|         let two = GaussianRational::new(Rational::new(2, 1), rational_zero()); | ||||
| 
 | ||||
|         let tokens = vec![two_token(), plus(), two_token()]; | ||||
|         let results = Node::Internal { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue