diff --git a/src/maths/evaluator.rs b/src/maths/evaluator.rs index be6ffdb..1b0ee7d 100644 --- a/src/maths/evaluator.rs +++ b/src/maths/evaluator.rs @@ -10,6 +10,10 @@ fn one() -> GaussianRational { GaussianRational::new(Rational::new(1, 1), Rational::new(0, 1)) } +fn minus_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(); @@ -123,13 +127,23 @@ fn calculate(operator: Token, lhs: Vec, rhs: Vec mul(lhs, &rhs), Token::Division() => div(lhs, rhs), Token::Exponentiation() => exp(lhs, rhs), + Token::Equal() => sub(lhs, rhs), + _ => unreachable!(), + } +} + +fn calculate_unary(operator: Token, operand: Vec) -> Vec { + match operator { + Token::Addition() => operand, + Token::Substraction() => mul(vec![minus_one()], &operand), _ => unreachable!(), } } pub fn evaluate(ast: Node) -> Vec { match ast { - Node::Internal { operator, lhs, rhs } => calculate(operator, evaluate(*lhs), evaluate(*rhs)), + Node::Binary { operator, lhs, rhs } => calculate(operator, evaluate(*lhs), evaluate(*rhs)), + Node::Unary { operator, operand } => calculate_unary(operator, evaluate(*operand)), Node::Leaf(value) => value, } -} \ No newline at end of file +} diff --git a/src/parser/ast_builder.rs b/src/parser/ast_builder.rs index c462265..4f1cf96 100644 --- a/src/parser/ast_builder.rs +++ b/src/parser/ast_builder.rs @@ -4,10 +4,14 @@ use crate::maths::{GaussianRational, Rational}; #[derive(Debug, PartialEq, Clone)] pub enum Node { Leaf(Vec), - Internal { + Binary { operator: Token, lhs: Box, rhs: Box, + }, + Unary { + operator: Token, + operand: Box, } } @@ -55,7 +59,7 @@ fn minus_x() -> Vec { fn insert_operator_node(mut tokens: Vec, position: usize) -> Node { let tokens_right = tokens.split_off(position + 1); let token = tokens.pop().unwrap(); - Node::Internal { + Node::Binary { operator: token, lhs: Box::new(build_ast(tokens)), rhs: Box::new(build_ast(tokens_right)), @@ -133,14 +137,12 @@ pub fn build_ast(mut tokens: Vec) -> Node { let tokens_right = tokens.split_off(position + 1); let token = tokens.pop().unwrap(); if tokens.len() == 0 { - match &tokens_right[0] { - Token::Number(n) => return Node::Leaf(vec![parse_number(n, -1)]), - Token::ImaginaryUnit() => return Node::Leaf(vec![minus_i()]), - Token::Variable(_) => return Node::Leaf(minus_x()), - _ => (), + return Node::Unary { + operator: token, + operand: Box::new(build_ast(tokens_right)), } } - return Node::Internal { + return Node::Binary { operator: token, lhs: Box::new(build_ast(tokens)), rhs: Box::new(build_ast(tokens_right)), @@ -223,7 +225,7 @@ mod tests { #[test] fn one_equals_one() { let tokens = vec![one_token(), equals(), one_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: Token::Equal(), lhs: Box::new(Node::Leaf(vec![one()])), rhs: Box::new(Node::Leaf(vec![one()])) @@ -236,7 +238,7 @@ mod tests { #[test] fn one_plus_one() { let tokens = vec![one_token(), plus(), one_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: plus(), lhs: Box::new(Node::Leaf(vec![one()])), rhs: Box::new(Node::Leaf(vec![one()])) @@ -245,7 +247,7 @@ mod tests { assert_eq!(build_ast(tokens), results); let tokens = vec![one_token(), minus(), one_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: minus(), lhs: Box::new(Node::Leaf(vec![one()])), rhs: Box::new(Node::Leaf(vec![one()])) @@ -257,7 +259,7 @@ mod tests { #[test] fn one_times_one() { let tokens = vec![one_token(), times(), one_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: times(), lhs: Box::new(Node::Leaf(vec![one()])), rhs: Box::new(Node::Leaf(vec![one()])) @@ -265,7 +267,7 @@ mod tests { assert_eq!(build_ast(tokens), results); let tokens = vec![one_token(), divided_by(), one_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: divided_by(), lhs: Box::new(Node::Leaf(vec![one()])), rhs: Box::new(Node::Leaf(vec![one()])) @@ -273,7 +275,7 @@ mod tests { assert_eq!(build_ast(tokens), results); let tokens = vec![one_token(), modulo(), one_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: modulo(), lhs: Box::new(Node::Leaf(vec![one()])), rhs: Box::new(Node::Leaf(vec![one()])) @@ -284,7 +286,7 @@ mod tests { #[test] fn one_power_one() { let tokens = vec![one_token(), power(), one_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: power(), lhs: Box::new(Node::Leaf(vec![one()])), rhs: Box::new(Node::Leaf(vec![one()])) @@ -295,9 +297,9 @@ mod tests { #[test] fn left_priority() { let tokens = vec![one_token(), plus(), one_token(), minus(), one_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: minus(), - lhs: Box::new(Node::Internal { + lhs: Box::new(Node::Binary { operator: plus(), lhs: Box::new(Node::Leaf(vec![one()])), rhs: Box::new(Node::Leaf(vec![one()])) @@ -310,10 +312,10 @@ mod tests { #[test] fn operation_priority() { let tokens = vec![one_token(), plus(), one_token(), times(), one_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: plus(), lhs: Box::new(Node::Leaf(vec![one()])), - rhs: Box::new(Node::Internal { + rhs: Box::new(Node::Binary { operator: times(), lhs: Box::new(Node::Leaf(vec![one()])), rhs: Box::new(Node::Leaf(vec![one()])) @@ -325,7 +327,7 @@ mod tests { #[test] fn i_plus_i() { let tokens = vec![i_token(), plus(), i_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: plus(), lhs: Box::new(Node::Leaf(vec![i()])), rhs: Box::new(Node::Leaf(vec![i()])) @@ -337,7 +339,7 @@ mod tests { #[test] fn x_plus_x() { let tokens = vec![x_token(), plus(), x_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: plus(), lhs: Box::new(Node::Leaf(x())), rhs: Box::new(Node::Leaf(x())) @@ -349,10 +351,10 @@ mod tests { #[test] fn parentheses() { let tokens = vec![one_token(), times(), open(), one_token(), plus(), one_token(), close()]; - let results = Node::Internal { + let results = Node::Binary { operator: times(), lhs: Box::new(Node::Leaf(vec![one()])), - rhs: Box::new(Node::Internal { + rhs: Box::new(Node::Binary { operator: plus(), lhs: Box::new(Node::Leaf(vec![one()])), rhs: Box::new(Node::Leaf(vec![one()])) @@ -366,7 +368,7 @@ mod tests { let two = GaussianRational::new(Rational::new(2, 1), rational_zero()); let tokens = vec![two_token(), plus(), two_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: plus(), lhs: Box::new(Node::Leaf(vec![two])), rhs: Box::new(Node::Leaf(vec![two])) @@ -375,7 +377,7 @@ mod tests { assert_eq!(build_ast(tokens), results); let tokens = vec![two_token(), minus(), one_token()]; - let results = Node::Internal { + let results = Node::Binary { operator: minus(), lhs: Box::new(Node::Leaf(vec![two])), rhs: Box::new(Node::Leaf(vec![one()]))