fix(parser::ast_builder): unary op one leaf bug

This commit is contained in:
gbrochar 2023-08-07 05:37:25 +02:00
parent 5a305e1246
commit 5fdc0a1231
2 changed files with 43 additions and 27 deletions

View File

@ -10,6 +10,10 @@ fn one() -> GaussianRational {
GaussianRational::new(Rational::new(1, 1), Rational::new(0, 1)) 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<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRational> { fn add(lhs: Vec<GaussianRational>, rhs: Vec<GaussianRational>) -> Vec<GaussianRational> {
let mut res = Vec::new(); let mut res = Vec::new();
let mut len = lhs.len(); let mut len = lhs.len();
@ -123,13 +127,23 @@ fn calculate(operator: Token, lhs: Vec<GaussianRational>, rhs: Vec<GaussianRatio
Token::Multiplication() => mul(lhs, &rhs), Token::Multiplication() => mul(lhs, &rhs),
Token::Division() => div(lhs, rhs), Token::Division() => div(lhs, rhs),
Token::Exponentiation() => exp(lhs, rhs), Token::Exponentiation() => exp(lhs, rhs),
Token::Equal() => sub(lhs, rhs),
_ => unreachable!(),
}
}
fn calculate_unary(operator: Token, operand: Vec<GaussianRational>) -> Vec<GaussianRational> {
match operator {
Token::Addition() => operand,
Token::Substraction() => mul(vec![minus_one()], &operand),
_ => unreachable!(), _ => unreachable!(),
} }
} }
pub fn evaluate(ast: Node) -> Vec<GaussianRational> { pub fn evaluate(ast: Node) -> Vec<GaussianRational> {
match ast { 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, Node::Leaf(value) => value,
} }
} }

View File

@ -4,10 +4,14 @@ use crate::maths::{GaussianRational, Rational};
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum Node { pub enum Node {
Leaf(Vec<GaussianRational>), Leaf(Vec<GaussianRational>),
Internal { Binary {
operator: Token, operator: Token,
lhs: Box<Node>, lhs: Box<Node>,
rhs: Box<Node>, rhs: Box<Node>,
},
Unary {
operator: Token,
operand: Box<Node>,
} }
} }
@ -55,7 +59,7 @@ fn minus_x() -> Vec<GaussianRational> {
fn insert_operator_node(mut tokens: Vec<Token>, position: usize) -> Node { fn insert_operator_node(mut tokens: Vec<Token>, position: usize) -> Node {
let tokens_right = tokens.split_off(position + 1); let tokens_right = tokens.split_off(position + 1);
let token = tokens.pop().unwrap(); let token = tokens.pop().unwrap();
Node::Internal { Node::Binary {
operator: token, operator: token,
lhs: Box::new(build_ast(tokens)), lhs: Box::new(build_ast(tokens)),
rhs: Box::new(build_ast(tokens_right)), rhs: Box::new(build_ast(tokens_right)),
@ -133,14 +137,12 @@ pub fn build_ast(mut tokens: Vec<Token>) -> Node {
let tokens_right = tokens.split_off(position + 1); let tokens_right = tokens.split_off(position + 1);
let token = tokens.pop().unwrap(); let token = tokens.pop().unwrap();
if tokens.len() == 0 { if tokens.len() == 0 {
match &tokens_right[0] { return Node::Unary {
Token::Number(n) => return Node::Leaf(vec![parse_number(n, -1)]), operator: token,
Token::ImaginaryUnit() => return Node::Leaf(vec![minus_i()]), operand: Box::new(build_ast(tokens_right)),
Token::Variable(_) => return Node::Leaf(minus_x()),
_ => (),
} }
} }
return Node::Internal { return Node::Binary {
operator: token, operator: token,
lhs: Box::new(build_ast(tokens)), lhs: Box::new(build_ast(tokens)),
rhs: Box::new(build_ast(tokens_right)), rhs: Box::new(build_ast(tokens_right)),
@ -223,7 +225,7 @@ mod tests {
#[test] #[test]
fn one_equals_one() { fn one_equals_one() {
let tokens = vec![one_token(), equals(), one_token()]; let tokens = vec![one_token(), equals(), one_token()];
let results = Node::Internal { let results = Node::Binary {
operator: Token::Equal(), operator: Token::Equal(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: Box::new(Node::Leaf(vec![one()])) rhs: Box::new(Node::Leaf(vec![one()]))
@ -236,7 +238,7 @@ mod tests {
#[test] #[test]
fn one_plus_one() { fn one_plus_one() {
let tokens = vec![one_token(), plus(), one_token()]; let tokens = vec![one_token(), plus(), one_token()];
let results = Node::Internal { let results = Node::Binary {
operator: plus(), operator: plus(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: 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); assert_eq!(build_ast(tokens), results);
let tokens = vec![one_token(), minus(), one_token()]; let tokens = vec![one_token(), minus(), one_token()];
let results = Node::Internal { let results = Node::Binary {
operator: minus(), operator: minus(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: Box::new(Node::Leaf(vec![one()])) rhs: Box::new(Node::Leaf(vec![one()]))
@ -257,7 +259,7 @@ mod tests {
#[test] #[test]
fn one_times_one() { fn one_times_one() {
let tokens = vec![one_token(), times(), one_token()]; let tokens = vec![one_token(), times(), one_token()];
let results = Node::Internal { let results = Node::Binary {
operator: times(), operator: times(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: 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); assert_eq!(build_ast(tokens), results);
let tokens = vec![one_token(), divided_by(), one_token()]; let tokens = vec![one_token(), divided_by(), one_token()];
let results = Node::Internal { let results = Node::Binary {
operator: divided_by(), operator: divided_by(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: 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); assert_eq!(build_ast(tokens), results);
let tokens = vec![one_token(), modulo(), one_token()]; let tokens = vec![one_token(), modulo(), one_token()];
let results = Node::Internal { let results = Node::Binary {
operator: modulo(), operator: modulo(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: Box::new(Node::Leaf(vec![one()])) rhs: Box::new(Node::Leaf(vec![one()]))
@ -284,7 +286,7 @@ mod tests {
#[test] #[test]
fn one_power_one() { fn one_power_one() {
let tokens = vec![one_token(), power(), one_token()]; let tokens = vec![one_token(), power(), one_token()];
let results = Node::Internal { let results = Node::Binary {
operator: power(), operator: power(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: Box::new(Node::Leaf(vec![one()])) rhs: Box::new(Node::Leaf(vec![one()]))
@ -295,9 +297,9 @@ mod tests {
#[test] #[test]
fn left_priority() { fn left_priority() {
let tokens = vec![one_token(), plus(), one_token(), minus(), one_token()]; let tokens = vec![one_token(), plus(), one_token(), minus(), one_token()];
let results = Node::Internal { let results = Node::Binary {
operator: minus(), operator: minus(),
lhs: Box::new(Node::Internal { lhs: Box::new(Node::Binary {
operator: plus(), operator: plus(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: Box::new(Node::Leaf(vec![one()])) rhs: Box::new(Node::Leaf(vec![one()]))
@ -310,10 +312,10 @@ mod tests {
#[test] #[test]
fn operation_priority() { fn operation_priority() {
let tokens = vec![one_token(), plus(), one_token(), times(), one_token()]; let tokens = vec![one_token(), plus(), one_token(), times(), one_token()];
let results = Node::Internal { let results = Node::Binary {
operator: plus(), operator: plus(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: Box::new(Node::Internal { rhs: Box::new(Node::Binary {
operator: times(), operator: times(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: Box::new(Node::Leaf(vec![one()])) rhs: Box::new(Node::Leaf(vec![one()]))
@ -325,7 +327,7 @@ mod tests {
#[test] #[test]
fn i_plus_i() { fn i_plus_i() {
let tokens = vec![i_token(), plus(), i_token()]; let tokens = vec![i_token(), plus(), i_token()];
let results = Node::Internal { let results = Node::Binary {
operator: plus(), operator: plus(),
lhs: Box::new(Node::Leaf(vec![i()])), lhs: Box::new(Node::Leaf(vec![i()])),
rhs: Box::new(Node::Leaf(vec![i()])) rhs: Box::new(Node::Leaf(vec![i()]))
@ -337,7 +339,7 @@ mod tests {
#[test] #[test]
fn x_plus_x() { fn x_plus_x() {
let tokens = vec![x_token(), plus(), x_token()]; let tokens = vec![x_token(), plus(), x_token()];
let results = Node::Internal { let results = Node::Binary {
operator: plus(), operator: plus(),
lhs: Box::new(Node::Leaf(x())), lhs: Box::new(Node::Leaf(x())),
rhs: Box::new(Node::Leaf(x())) rhs: Box::new(Node::Leaf(x()))
@ -349,10 +351,10 @@ mod tests {
#[test] #[test]
fn parentheses() { fn parentheses() {
let tokens = vec![one_token(), times(), open(), one_token(), plus(), one_token(), close()]; let tokens = vec![one_token(), times(), open(), one_token(), plus(), one_token(), close()];
let results = Node::Internal { let results = Node::Binary {
operator: times(), operator: times(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: Box::new(Node::Internal { rhs: Box::new(Node::Binary {
operator: plus(), operator: plus(),
lhs: Box::new(Node::Leaf(vec![one()])), lhs: Box::new(Node::Leaf(vec![one()])),
rhs: 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 two = GaussianRational::new(Rational::new(2, 1), rational_zero());
let tokens = vec![two_token(), plus(), two_token()]; let tokens = vec![two_token(), plus(), two_token()];
let results = Node::Internal { let results = Node::Binary {
operator: plus(), operator: plus(),
lhs: Box::new(Node::Leaf(vec![two])), lhs: Box::new(Node::Leaf(vec![two])),
rhs: 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); assert_eq!(build_ast(tokens), results);
let tokens = vec![two_token(), minus(), one_token()]; let tokens = vec![two_token(), minus(), one_token()];
let results = Node::Internal { let results = Node::Binary {
operator: minus(), operator: minus(),
lhs: Box::new(Node::Leaf(vec![two])), lhs: Box::new(Node::Leaf(vec![two])),
rhs: Box::new(Node::Leaf(vec![one()])) rhs: Box::new(Node::Leaf(vec![one()]))