1
0
Fork 0

Add tests for while loops

This commit is contained in:
Vili Sinervä 2025-01-31 20:06:13 +02:00
parent 56281008e4
commit eb44a88121
No known key found for this signature in database
GPG key ID: DF8FEAF54EFAC996
2 changed files with 60 additions and 0 deletions

View file

@ -21,6 +21,11 @@ pub enum Expression<'source> {
Box<Expression<'source>>,
Option<Box<Expression<'source>>>,
),
While(
CodeLocation,
Box<Expression<'source>>,
Box<Expression<'source>>,
),
FunCall(CodeLocation, &'source str, Vec<Expression<'source>>),
Block(CodeLocation, Vec<Expression<'source>>),
}
@ -36,6 +41,7 @@ impl<'source> Expression<'source> {
Expression::VarDeclaration(loc, _, _) => *loc,
Expression::BinaryOp(loc, _, _, _) => *loc,
Expression::Conditional(loc, _, _, _) => *loc,
Expression::While(loc, _, _) => *loc,
Expression::FunCall(loc, _, _) => *loc,
Expression::Block(loc, _) => *loc,
}
@ -51,6 +57,7 @@ impl<'source> Expression<'source> {
Expression::VarDeclaration(..) => "Variable declaration",
Expression::BinaryOp(..) => "Binary operation",
Expression::Conditional(..) => "Conditional",
Expression::While(_, _, _) => "While loop",
Expression::FunCall(..) => "Function call",
Expression::Block(..) => "Block",
}
@ -66,6 +73,7 @@ impl<'source> Expression<'source> {
Expression::VarDeclaration(_, name, _) => name.to_string(),
Expression::BinaryOp(_, _, op, _) => op.to_string(),
Expression::Conditional(_, condition, _, _) => format!("if {}", condition),
Expression::While(_, condition, _) => format!("while {}", condition),
Expression::FunCall(_, name, args) => format!("{} with {} args", name, args.len()),
Expression::Block(_, expressions) => format!("with {} expressions", expressions.len()),
}

View file

@ -109,6 +109,18 @@ macro_rules! var_ast {
};
}
macro_rules! while_ast {
($x:expr, $y:expr) => {
While(CodeLocation::new(usize::MAX, usize::MAX), $x, $y)
};
}
macro_rules! while_ast_b {
($x:expr, $y:expr) => {
Box::new(while_ast!($x, $y))
};
}
#[test]
#[should_panic]
fn test_empty() {
@ -599,3 +611,43 @@ fn test_omitting_semicolons() {
fn test_omitting_semicolons_invalid() {
parse(&tokenize("{ if true then { a } b c }"));
}
#[test]
fn test_while_do() {
let result = parse(&tokenize("while 1 + 2 do 3"));
assert_eq!(
result,
while_ast!(bin_ast_b!(int_ast_b!(1), "+", int_ast_b!(2)), int_ast_b!(3))
);
}
#[test]
fn test_while_do_embedded() {
let result = parse(&tokenize("1 + while true do 2"));
assert_eq!(
result,
bin_ast!(
int_ast_b!(1),
"+",
while_ast_b!(bool_ast_b!(true), int_ast_b!(2))
)
);
}
#[test]
fn test_while_do_nested() {
let result = parse(&tokenize("while true do while false do 1"));
assert_eq!(
result,
while_ast!(
bool_ast_b!(true),
while_ast_b!(bool_ast_b!(false), int_ast_b!(1))
)
);
}
#[test]
#[should_panic]
fn test_while_no_do() {
parse(&tokenize("while true"));
}