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))
}
fn minus_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();
@ -123,13 +127,23 @@ fn calculate(operator: Token, lhs: Vec<GaussianRational>, rhs: Vec<GaussianRatio
Token::Multiplication() => 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<GaussianRational>) -> Vec<GaussianRational> {
match operator {
Token::Addition() => operand,
Token::Substraction() => mul(vec![minus_one()], &operand),
_ => unreachable!(),
}
}
pub fn evaluate(ast: Node) -> Vec<GaussianRational> {
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,
}
}

View File

@ -4,10 +4,14 @@ use crate::maths::{GaussianRational, Rational};
#[derive(Debug, PartialEq, Clone)]
pub enum Node {
Leaf(Vec<GaussianRational>),
Internal {
Binary {
operator: Token,
lhs: 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 {
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<Token>) -> 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()]))