test: add tests to binary operator parsing

This commit is contained in:
Araozu 2024-10-19 19:48:33 -05:00
parent 2a2da32245
commit 68d3e0dba4
4 changed files with 68 additions and 3 deletions

View File

@ -2,7 +2,6 @@
## TODO ## TODO
- Test correct operator precedence
- Implement functions as first class citizens - Implement functions as first class citizens
- Parse __more__ binary operators - Parse __more__ binary operators
- Parse more complex bindings - Parse more complex bindings
@ -23,6 +22,7 @@
- [ ] Test semantic analysis - [ ] Test semantic analysis
- [ ] Generate php code from current AST - [ ] Generate php code from current AST
- [x] Test correct operator precedence
## v0.1.2 ## v0.1.2

View File

@ -161,7 +161,7 @@ mod tests {
let label = &err.labels[0]; let label = &err.labels[0];
assert_eq!( assert_eq!(
label.message, label.message,
"Expected this expression to be a function, found a `Int`" "Expected this expression to be a function, found a Value(\"Int\")"
); );
assert_eq!(label.start, 0); assert_eq!(label.start, 0);
assert_eq!(label.end, 6); assert_eq!(label.end, 6);

View File

@ -8,7 +8,7 @@ use crate::{
/// Parses a factor expression. /// Parses a factor expression.
/// ///
/// ```ebnf /// ```ebnf
/// factor = unary, (("/" | "*", "%"), unary)*; /// factor = unary, (("/" | "*" | "%"), unary)*;
/// ``` /// ```
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> { pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
let (unary, next_pos) = match super::unary::try_parse(tokens, pos) { let (unary, next_pos) = match super::unary::try_parse(tokens, pos) {
@ -181,4 +181,34 @@ mod tests {
_ => panic!("Expected a binary operator"), _ => panic!("Expected a binary operator"),
} }
} }
#[test]
fn should_parse_mixed_with_unary_ops() {
let tokens = get_tokens(&String::from("2 * -4")).unwrap();
let (result, next) = try_parse(&tokens, 0).unwrap();
assert_eq!(next, 4);
match result {
Expression::BinaryOperator(lexpr, rexpr, op) => {
assert_eq!(op.value, "*");
let Expression::Int(left_value) = *lexpr else {
panic!("Expected an Int expression")
};
assert_eq!(left_value.value, "2");
let Expression::UnaryOperator(op, right_expr) = *rexpr else {
panic!("Expected a unary operator on the right")
};
assert_eq!(op.value, "-");
let Expression::Int(right_value) = *right_expr else {
panic!("Expected an Int expression");
};
assert_eq!(right_value.value, "4");
}
_ => {
panic!("Expected a binary operator, got {:?}", result)
}
}
}
} }

View File

@ -49,6 +49,8 @@ fn parse_many<'a>(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use core::panic;
use super::*; use super::*;
use crate::lexic::get_tokens; use crate::lexic::get_tokens;
use crate::lexic::token::TokenType; use crate::lexic::token::TokenType;
@ -179,4 +181,37 @@ mod tests {
_ => panic!("Expected a binary operator"), _ => panic!("Expected a binary operator"),
} }
} }
#[test]
fn should_parse_correct_precedence() {
let tokens = get_tokens(&String::from("1 + 2 * 3")).unwrap();
let (result, next) = try_parse(&tokens, 0).unwrap();
assert_eq!(next, 5);
match result {
Expression::BinaryOperator(lexpr, rexpr, op) => {
assert_eq!(op.value, "+");
match (*lexpr, *rexpr) {
(Expression::Int(lvalue), Expression::BinaryOperator(llexpr, rrexpr, oop)) => {
assert_eq!(oop.value, "*");
assert_eq!(lvalue.value, "1");
match (*llexpr, *rrexpr) {
(Expression::Int(left), Expression::Int(right)) => {
assert_eq!(left.value, "2");
assert_eq!(right.value, "3");
}
_ => {
panic!("Expected left to be an int, right to be an int")
}
}
}
_ => {
panic!("Expected left to be an int, right to be a binary op")
}
}
}
_ => panic!("Expected a binary op, got {:?}", result),
}
}
} }