Skip to content

Commit

Permalink
Fixed parser tests to use comp_or_sexpr
Browse files Browse the repository at this point in the history
  • Loading branch information
mortenhaahr committed Jan 3, 2025
1 parent 4e65898 commit deaac4d
Showing 1 changed file with 65 additions and 59 deletions.
124 changes: 65 additions & 59 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,15 +471,15 @@ mod tests {
#[test]
fn test_sexpr() -> Result<(), ErrMode<ContextError>> {
assert_eq!(
sexpr(&mut (*"1 + 2".to_string()).into())?,
comp_or_sexpr(&mut (*"1 + 2".to_string()).into())?,
SExpr::BinOp(
Box::new(SExpr::Val(Value::Int(1))),
Box::new(SExpr::Val(Value::Int(2))),
SBinOp::IOp(IntBinOp::Add),
),
);
assert_eq!(
sexpr(&mut (*"1 + 2 * 3".to_string()).into())?,
comp_or_sexpr(&mut (*"1 + 2 * 3".to_string()).into())?,
SExpr::BinOp(
Box::new(SExpr::Val(Value::Int(1))),
Box::new(SExpr::BinOp(
Expand All @@ -491,7 +491,7 @@ mod tests {
),
);
assert_eq!(
sexpr(&mut (*"x + (y + 2)".to_string()).into())?,
comp_or_sexpr(&mut (*"x + (y + 2)".to_string()).into())?,
SExpr::BinOp(
Box::new(SExpr::Var(VarName("x".into()))),
Box::new(SExpr::BinOp(
Expand All @@ -503,19 +503,19 @@ mod tests {
),
);
assert_eq!(
sexpr(&mut (*"if true then 1 else 2".to_string()).into())?,
comp_or_sexpr(&mut (*"if true then 1 else 2".to_string()).into())?,
SExpr::If(
Box::new(SExpr::Val(true.into())),
Box::new(SExpr::Val(Value::Int(1))),
Box::new(SExpr::Val(Value::Int(2))),
),
);
assert_eq!(
sexpr(&mut (*"(x)[-1, 0]".to_string()).into())?,
comp_or_sexpr(&mut (*"(x)[-1, 0]".to_string()).into())?,
SExpr::Index(Box::new(SExpr::Var(VarName("x".into()))), -1, Value::Int(0),),
);
assert_eq!(
sexpr(&mut (*"(x + y)[-3, 2]".to_string()).into())?,
comp_or_sexpr(&mut (*"(x + y)[-3, 2]".to_string()).into())?,
SExpr::Index(
Box::new(SExpr::BinOp(
Box::new(SExpr::Var(VarName("x".into()))),
Expand All @@ -527,7 +527,7 @@ mod tests {
),
);
assert_eq!(
sexpr(&mut (*"1 + (x)[-1, 0]".to_string()).into())?,
comp_or_sexpr(&mut (*"1 + (x)[-1, 0]".to_string()).into())?,
SExpr::BinOp(
Box::new(SExpr::Val(Value::Int(1))),
Box::new(SExpr::Index(
Expand All @@ -539,7 +539,7 @@ mod tests {
)
);
assert_eq!(
sexpr(&mut (*"\"test\"".to_string()).into())?,
comp_or_sexpr(&mut (*"\"test\"".to_string()).into())?,
SExpr::Val(Value::Str("test".to_string())),
);
assert_eq!(
Expand All @@ -553,7 +553,7 @@ mod tests {
}

#[test]
fn test_comp_or_sexpr() -> Result<(), ErrMode<ContextError>> {
fn test_comp_or_comp_or_sexpr() -> Result<(), ErrMode<ContextError>> {
assert_eq!(
comp_or_sexpr(&mut (*"stage == \"m\"").into())?,
SExpr::Eq(
Expand Down Expand Up @@ -769,155 +769,161 @@ mod tests {
#[test]
fn test_iexpr() {
// Add
assert_eq!(presult_to_string(&sexpr(&mut "0")), "Ok(Val(Int(0)))");
assert_eq!(
presult_to_string(&sexpr(&mut " 1 +2 ")),
presult_to_string(&comp_or_sexpr(&mut "0")),
"Ok(Val(Int(0)))"
);
assert_eq!(
presult_to_string(&comp_or_sexpr(&mut " 1 +2 ")),
"Ok(BinOp(Val(Int(1)), Val(Int(2)), IOp(Add)))"
);
assert_eq!(
presult_to_string(&sexpr(&mut " 1 + 2 +3")),
presult_to_string(&comp_or_sexpr(&mut " 1 + 2 +3")),
"Ok(BinOp(BinOp(Val(Int(1)), Val(Int(2)), IOp(Add)), Val(Int(3)), IOp(Add)))"
);
// Sub
assert_eq!(
presult_to_string(&sexpr(&mut " 1 -2 ")),
presult_to_string(&comp_or_sexpr(&mut " 1 -2 ")),
"Ok(BinOp(Val(Int(1)), Val(Int(2)), IOp(Sub)))"
);
assert_eq!(
presult_to_string(&sexpr(&mut " 1 - 2 -3")),
presult_to_string(&comp_or_sexpr(&mut " 1 - 2 -3")),
"Ok(BinOp(BinOp(Val(Int(1)), Val(Int(2)), IOp(Sub)), Val(Int(3)), IOp(Sub)))"
);
// Mul
assert_eq!(
presult_to_string(&sexpr(&mut " 1 *2 ")),
presult_to_string(&comp_or_sexpr(&mut " 1 *2 ")),
"Ok(BinOp(Val(Int(1)), Val(Int(2)), IOp(Mul)))"
);
assert_eq!(
presult_to_string(&sexpr(&mut " 1 * 2 *3")),
presult_to_string(&comp_or_sexpr(&mut " 1 * 2 *3")),
"Ok(BinOp(BinOp(Val(Int(1)), Val(Int(2)), IOp(Mul)), Val(Int(3)), IOp(Mul)))"
);
// Div
assert_eq!(
presult_to_string(&sexpr(&mut " 1 /2 ")),
presult_to_string(&comp_or_sexpr(&mut " 1 /2 ")),
"Ok(BinOp(Val(Int(1)), Val(Int(2)), IOp(Div)))"
);
assert_eq!(
presult_to_string(&sexpr(&mut " 1 / 2 /3")),
presult_to_string(&comp_or_sexpr(&mut " 1 / 2 /3")),
"Ok(BinOp(BinOp(Val(Int(1)), Val(Int(2)), IOp(Div)), Val(Int(3)), IOp(Div)))"
);
// Var
assert_eq!(
presult_to_string(&sexpr(&mut " x ")),
presult_to_string(&comp_or_sexpr(&mut " x ")),
r#"Ok(Var(VarName("x")))"#
);
assert_eq!(
presult_to_string(&sexpr(&mut " xsss ")),
presult_to_string(&comp_or_sexpr(&mut " xsss ")),
r#"Ok(Var(VarName("xsss")))"#
);
// Time index
assert_eq!(
presult_to_string(&sexpr(&mut "x [-1, 0 ]")),
presult_to_string(&comp_or_sexpr(&mut "x [-1, 0 ]")),
r#"Ok(Index(Var(VarName("x")), -1, Int(0)))"#
);
assert_eq!(
presult_to_string(&sexpr(&mut "x[1,0]")),
presult_to_string(&comp_or_sexpr(&mut "x[1,0]")),
r#"Ok(Index(Var(VarName("x")), 1, Int(0)))"#
);
// Paren
assert_eq!(presult_to_string(&sexpr(&mut " (1) ")), "Ok(Val(Int(1)))");
assert_eq!(
presult_to_string(&comp_or_sexpr(&mut " (1) ")),
"Ok(Val(Int(1)))"
);
// Don't care about order of eval; care about what the AST looks like
assert_eq!(
presult_to_string(&sexpr(&mut " 2 + (2 + 3)")),
presult_to_string(&comp_or_sexpr(&mut " 2 + (2 + 3)")),
"Ok(BinOp(Val(Int(2)), BinOp(Val(Int(2)), Val(Int(3)), IOp(Add)), IOp(Add)))"
);
// If then else
assert_eq!(
presult_to_string(&sexpr(&mut "if true then 1 else 2")),
presult_to_string(&comp_or_sexpr(&mut "if true then 1 else 2")),
"Ok(If(Val(Bool(true)), Val(Int(1)), Val(Int(2))))"
);
assert_eq!(
presult_to_string(&sexpr(&mut "if true then x+x else y+y")),
presult_to_string(&comp_or_sexpr(&mut "if true then x+x else y+y")),
r#"Ok(If(Val(Bool(true)), BinOp(Var(VarName("x")), Var(VarName("x")), IOp(Add)), BinOp(Var(VarName("y")), Var(VarName("y")), IOp(Add))))"#
);

// ChatGPT generated tests with mixed arithmetic and parentheses iexprs. It only had knowledge of the tests above.
// Basic mixed addition and multiplication
assert_eq!(
presult_to_string(&sexpr(&mut "1 + 2 * 3")),
presult_to_string(&comp_or_sexpr(&mut "1 + 2 * 3")),
"Ok(BinOp(Val(Int(1)), BinOp(Val(Int(2)), Val(Int(3)), IOp(Mul)), IOp(Add)))"
);
assert_eq!(
presult_to_string(&sexpr(&mut "1 * 2 + 3")),
presult_to_string(&comp_or_sexpr(&mut "1 * 2 + 3")),
"Ok(BinOp(BinOp(Val(Int(1)), Val(Int(2)), IOp(Mul)), Val(Int(3)), IOp(Add)))"
);
// Mixed addition, subtraction, and multiplication
assert_eq!(presult_to_string(&sexpr(&mut "1 + 2 * 3 - 4")),
assert_eq!(presult_to_string(&comp_or_sexpr(&mut "1 + 2 * 3 - 4")),
"Ok(BinOp(BinOp(Val(Int(1)), BinOp(Val(Int(2)), Val(Int(3)), IOp(Mul)), IOp(Add)), Val(Int(4)), IOp(Sub)))");
assert_eq!(presult_to_string(&sexpr(&mut "1 * 2 + 3 - 4")),
assert_eq!(presult_to_string(&comp_or_sexpr(&mut "1 * 2 + 3 - 4")),
"Ok(BinOp(BinOp(BinOp(Val(Int(1)), Val(Int(2)), IOp(Mul)), Val(Int(3)), IOp(Add)), Val(Int(4)), IOp(Sub)))");
// Mixed addition and division
assert_eq!(
presult_to_string(&sexpr(&mut "10 + 20 / 5")),
presult_to_string(&comp_or_sexpr(&mut "10 + 20 / 5")),
"Ok(BinOp(Val(Int(10)), BinOp(Val(Int(20)), Val(Int(5)), IOp(Div)), IOp(Add)))"
);
// Nested parentheses with mixed operations
assert_eq!(presult_to_string(&sexpr(&mut "(1 + 2) * (3 - 4)")),
assert_eq!(presult_to_string(&comp_or_sexpr(&mut "(1 + 2) * (3 - 4)")),
"Ok(BinOp(BinOp(Val(Int(1)), Val(Int(2)), IOp(Add)), BinOp(Val(Int(3)), Val(Int(4)), IOp(Sub)), IOp(Mul)))");
assert_eq!(presult_to_string(&sexpr(&mut "1 + (2 * (3 + 4))")),
assert_eq!(presult_to_string(&comp_or_sexpr(&mut "1 + (2 * (3 + 4))")),
"Ok(BinOp(Val(Int(1)), BinOp(Val(Int(2)), BinOp(Val(Int(3)), Val(Int(4)), IOp(Add)), IOp(Mul)), IOp(Add)))");
// Complex nested expressions
assert_eq!(presult_to_string(&sexpr(&mut "((1 + 2) * 3) + (4 / (5 - 6))")),
assert_eq!(presult_to_string(&comp_or_sexpr(&mut "((1 + 2) * 3) + (4 / (5 - 6))")),
"Ok(BinOp(BinOp(BinOp(Val(Int(1)), Val(Int(2)), IOp(Add)), Val(Int(3)), IOp(Mul)), BinOp(Val(Int(4)), BinOp(Val(Int(5)), Val(Int(6)), IOp(Sub)), IOp(Div)), IOp(Add)))"
);
assert_eq!(presult_to_string(&sexpr(&mut "(1 + (2 * (3 - (4 / 5))))")),
assert_eq!(presult_to_string(&comp_or_sexpr(&mut "(1 + (2 * (3 - (4 / 5))))")),
"Ok(BinOp(Val(Int(1)), BinOp(Val(Int(2)), BinOp(Val(Int(3)), BinOp(Val(Int(4)), Val(Int(5)), IOp(Div)), IOp(Sub)), IOp(Mul)), IOp(Add)))"
);
// More complex expressions with deep nesting
assert_eq!(presult_to_string(&sexpr(&mut "((1 + 2) * (3 + 4))")),
assert_eq!(presult_to_string(&comp_or_sexpr(&mut "((1 + 2) * (3 + 4))")),
"Ok(BinOp(BinOp(Val(Int(1)), Val(Int(2)), IOp(Add)), BinOp(Val(Int(3)), Val(Int(4)), IOp(Add)), IOp(Mul)))"
);
assert_eq!(presult_to_string(&sexpr(&mut "((1 * 2) + (3 * 4)) / 5")),
assert_eq!(presult_to_string(&comp_or_sexpr(&mut "((1 * 2) + (3 * 4)) / 5")),
"Ok(BinOp(BinOp(BinOp(Val(Int(1)), Val(Int(2)), IOp(Mul)), BinOp(Val(Int(3)), Val(Int(4)), IOp(Mul)), IOp(Add)), Val(Int(5)), IOp(Div)))"
);
// Multiple levels of nested expressions
assert_eq!(presult_to_string(&sexpr(&mut "1 + (2 * (3 + (4 / (5 - 6))))")),
assert_eq!(presult_to_string(&comp_or_sexpr(&mut "1 + (2 * (3 + (4 / (5 - 6))))")),
"Ok(BinOp(Val(Int(1)), BinOp(Val(Int(2)), BinOp(Val(Int(3)), BinOp(Val(Int(4)), BinOp(Val(Int(5)), Val(Int(6)), IOp(Sub)), IOp(Div)), IOp(Add)), IOp(Mul)), IOp(Add)))"
);

// ChatGPT generated tests with mixed iexprs. It only had knowledge of the tests above.
// Mixing addition, subtraction, and variables
assert_eq!(
presult_to_string(&sexpr(&mut "x + 2 - y")),
presult_to_string(&comp_or_sexpr(&mut "x + 2 - y")),
r#"Ok(BinOp(BinOp(Var(VarName("x")), Val(Int(2)), IOp(Add)), Var(VarName("y")), IOp(Sub)))"#
);
assert_eq!(
presult_to_string(&sexpr(&mut "(x + y) * 3")),
presult_to_string(&comp_or_sexpr(&mut "(x + y) * 3")),
r#"Ok(BinOp(BinOp(Var(VarName("x")), Var(VarName("y")), IOp(Add)), Val(Int(3)), IOp(Mul)))"#
);
// Nested arithmetic with variables and parentheses
assert_eq!(
presult_to_string(&sexpr(&mut "(a + b) / (c - d)")),
presult_to_string(&comp_or_sexpr(&mut "(a + b) / (c - d)")),
r#"Ok(BinOp(BinOp(Var(VarName("a")), Var(VarName("b")), IOp(Add)), BinOp(Var(VarName("c")), Var(VarName("d")), IOp(Sub)), IOp(Div)))"#
);
assert_eq!(
presult_to_string(&sexpr(&mut "x * (y + 3) - z / 2")),
presult_to_string(&comp_or_sexpr(&mut "x * (y + 3) - z / 2")),
r#"Ok(BinOp(BinOp(Var(VarName("x")), BinOp(Var(VarName("y")), Val(Int(3)), IOp(Add)), IOp(Mul)), BinOp(Var(VarName("z")), Val(Int(2)), IOp(Div)), IOp(Sub)))"#
);
// If-then-else with mixed arithmetic
assert_eq!(presult_to_string(&sexpr(&mut "if true then 1 + 2 else 3 * 4")),
assert_eq!(presult_to_string(&comp_or_sexpr(&mut "if true then 1 + 2 else 3 * 4")),
"Ok(If(Val(Bool(true)), BinOp(Val(Int(1)), Val(Int(2)), IOp(Add)), BinOp(Val(Int(3)), Val(Int(4)), IOp(Mul))))");
// Time index in arithmetic expression
assert_eq!(
presult_to_string(&sexpr(&mut "x[0, 1] + y[-1, 0]")),
presult_to_string(&comp_or_sexpr(&mut "x[0, 1] + y[-1, 0]")),
r#"Ok(BinOp(Index(Var(VarName("x")), 0, Int(1)), Index(Var(VarName("y")), -1, Int(0)), IOp(Add)))"#
);
assert_eq!(
presult_to_string(&sexpr(&mut "x[1, 2] * (y + 3)")),
presult_to_string(&comp_or_sexpr(&mut "x[1, 2] * (y + 3)")),
r#"Ok(BinOp(Index(Var(VarName("x")), 1, Int(2)), BinOp(Var(VarName("y")), Val(Int(3)), IOp(Add)), IOp(Mul)))"#
);
// Complex expression with nested if-then-else and mixed operations
assert_eq!(
presult_to_string(&sexpr(&mut "(1 + x) * if y then 3 else z / 2")),
presult_to_string(&comp_or_sexpr(&mut "(1 + x) * if y then 3 else z / 2")),
r#"Ok(BinOp(BinOp(Val(Int(1)), Var(VarName("x")), IOp(Add)), If(Var(VarName("y")), Val(Int(3)), BinOp(Var(VarName("z")), Val(Int(2)), IOp(Div))), IOp(Mul)))"#
);
}
Expand Down Expand Up @@ -945,29 +951,29 @@ mod tests {
#[test]
fn parse_empty_string() {
assert_eq!(
presult_to_string(&sexpr(&mut "")),
presult_to_string(&comp_or_sexpr(&mut "")),
"Err(Backtrack(ContextError { context: [], cause: None }))"
);
}

#[test]
fn parse_invalid_expression() {
// TODO: Bug here in parser. It should be able to handle these cases.
// assert_eq!(presult_to_string(&sexpr(&mut "1 +")), "Err(Backtrack(ContextError { context: [], cause: None }))");
// assert_eq!(presult_to_string(&comp_or_sexpr(&mut "1 +")), "Err(Backtrack(ContextError { context: [], cause: None }))");
assert_eq!(
presult_to_string(&sexpr(&mut "&& true")),
presult_to_string(&comp_or_sexpr(&mut "&& true")),
"Err(Backtrack(ContextError { context: [], cause: None }))"
);
}

#[test]
fn parse_boolean_expressions() {
assert_eq!(
presult_to_string(&sexpr(&mut "true && false")),
presult_to_string(&comp_or_sexpr(&mut "true && false")),
"Ok(BinOp(Val(Bool(true)), Val(Bool(false)), BOp(And)))"
);
assert_eq!(
presult_to_string(&sexpr(&mut "true || false")),
presult_to_string(&comp_or_sexpr(&mut "true || false")),
"Ok(BinOp(Val(Bool(true)), Val(Bool(false)), BOp(Or)))"
);
}
Expand All @@ -976,43 +982,43 @@ mod tests {
fn parse_mixed_boolean_and_arithmetic() {
// Expressions do not make sense but parser should allow it
assert_eq!(
presult_to_string(&sexpr(&mut "1 + 2 && 3")),
presult_to_string(&comp_or_sexpr(&mut "1 + 2 && 3")),
"Ok(BinOp(BinOp(Val(Int(1)), Val(Int(2)), IOp(Add)), Val(Int(3)), BOp(And)))"
);
assert_eq!(
presult_to_string(&sexpr(&mut "true || 1 * 2")),
presult_to_string(&comp_or_sexpr(&mut "true || 1 * 2")),
"Ok(BinOp(Val(Bool(true)), BinOp(Val(Int(1)), Val(Int(2)), IOp(Mul)), BOp(Or)))"
);
}
#[test]
fn parse_string_concatenation() {
assert_eq!(
presult_to_string(&sexpr(&mut r#""foo" ++ "bar""#)),
presult_to_string(&comp_or_sexpr(&mut r#""foo" ++ "bar""#)),
r#"Ok(BinOp(Val(Str("foo")), Val(Str("bar")), SOp(Concat)))"#
);
assert_eq!(
presult_to_string(&sexpr(&mut r#""hello" ++ " " ++ "world""#)),
presult_to_string(&comp_or_sexpr(&mut r#""hello" ++ " " ++ "world""#)),
r#"Ok(BinOp(BinOp(Val(Str("hello")), Val(Str(" ")), SOp(Concat)), Val(Str("world")), SOp(Concat)))"#
);
assert_eq!(
presult_to_string(&sexpr(&mut r#""a" ++ "b" ++ "c""#)),
presult_to_string(&comp_or_sexpr(&mut r#""a" ++ "b" ++ "c""#)),
r#"Ok(BinOp(BinOp(Val(Str("a")), Val(Str("b")), SOp(Concat)), Val(Str("c")), SOp(Concat)))"#
);
}

#[test]
fn parse_defer() {
assert_eq!(
presult_to_string(&sexpr(&mut r#"defer(x)"#)),
presult_to_string(&comp_or_sexpr(&mut r#"defer(x)"#)),
r#"Ok(Defer(Var(VarName("x"))))"#
)
}

#[test]
fn parse_update() {
assert_eq!(
presult_to_string(&sexpr(&mut r#"update(0, x)"#)),
r#"Ok(Update(Val(Int(0)), Var(VarName("x"))))"#
presult_to_string(&comp_or_sexpr(&mut r#"update(x, y)"#)),
r#"Ok(Update(Var(VarName("x")), Var(VarName("y"))))"#
)
}
}

0 comments on commit deaac4d

Please sign in to comment.