1
0
Fork 0

Add support for all left-associative binary ops

This commit is contained in:
Vili Sinervä 2025-01-31 13:19:40 +02:00
parent 04e390c6f9
commit 0691c22487
No known key found for this signature in database
GPG key ID: DF8FEAF54EFAC996
2 changed files with 33 additions and 1 deletions

View file

@ -27,7 +27,14 @@ fn parse_expression<'source>(
pos: &mut usize, pos: &mut usize,
tokens: &[Token<'source>], tokens: &[Token<'source>],
) -> Expression<'source> { ) -> Expression<'source> {
const LEFT_ASSOC_BIN_OPS: [&[&str]; 2] = [&["+", "-"], &["*", "/"]]; const LEFT_ASSOC_BIN_OPS: [&[&str]; 6] = [
&["or"],
&["and"],
&["==", "!="],
&["<", "<=", "=>", ">"],
&["+", "-"],
&["*", "/", "%"],
];
if level == LEFT_ASSOC_BIN_OPS.len() { if level == LEFT_ASSOC_BIN_OPS.len() {
parse_term(pos, tokens) parse_term(pos, tokens)

View file

@ -64,6 +64,31 @@ fn test_binary_op_basic() {
assert_eq!(result, BinaryOp(int_ast!(1), "/", int_ast!(2))); assert_eq!(result, BinaryOp(int_ast!(1), "/", int_ast!(2)));
} }
#[test]
fn test_binary_op_all_levels() {
let result = parse(&tokenize("1 * 2 + 3 < 4 == 5 and 6 or 7"));
assert_eq!(
result,
BinaryOp(
bin_ast!(
bin_ast!(
bin_ast!(
bin_ast!(bin_ast!(int_ast!(1), "*", int_ast!(2)), "+", int_ast!(3)),
"<",
int_ast!(4)
),
"==",
int_ast!(5)
),
"and",
int_ast!(6)
),
"or",
int_ast!(7)
)
);
}
#[test] #[test]
fn test_binary_op_identifier() { fn test_binary_op_identifier() {
let result = parse(&tokenize("a + 1")); let result = parse(&tokenize("a + 1"));