test: add tests to binary operator parsing
This commit is contained in:
parent
2a2da32245
commit
68d3e0dba4
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user