Add tests for while loops
This commit is contained in:
parent
56281008e4
commit
eb44a88121
2 changed files with 60 additions and 0 deletions
|
@ -21,6 +21,11 @@ pub enum Expression<'source> {
|
||||||
Box<Expression<'source>>,
|
Box<Expression<'source>>,
|
||||||
Option<Box<Expression<'source>>>,
|
Option<Box<Expression<'source>>>,
|
||||||
),
|
),
|
||||||
|
While(
|
||||||
|
CodeLocation,
|
||||||
|
Box<Expression<'source>>,
|
||||||
|
Box<Expression<'source>>,
|
||||||
|
),
|
||||||
FunCall(CodeLocation, &'source str, Vec<Expression<'source>>),
|
FunCall(CodeLocation, &'source str, Vec<Expression<'source>>),
|
||||||
Block(CodeLocation, Vec<Expression<'source>>),
|
Block(CodeLocation, Vec<Expression<'source>>),
|
||||||
}
|
}
|
||||||
|
@ -36,6 +41,7 @@ impl<'source> Expression<'source> {
|
||||||
Expression::VarDeclaration(loc, _, _) => *loc,
|
Expression::VarDeclaration(loc, _, _) => *loc,
|
||||||
Expression::BinaryOp(loc, _, _, _) => *loc,
|
Expression::BinaryOp(loc, _, _, _) => *loc,
|
||||||
Expression::Conditional(loc, _, _, _) => *loc,
|
Expression::Conditional(loc, _, _, _) => *loc,
|
||||||
|
Expression::While(loc, _, _) => *loc,
|
||||||
Expression::FunCall(loc, _, _) => *loc,
|
Expression::FunCall(loc, _, _) => *loc,
|
||||||
Expression::Block(loc, _) => *loc,
|
Expression::Block(loc, _) => *loc,
|
||||||
}
|
}
|
||||||
|
@ -51,6 +57,7 @@ impl<'source> Expression<'source> {
|
||||||
Expression::VarDeclaration(..) => "Variable declaration",
|
Expression::VarDeclaration(..) => "Variable declaration",
|
||||||
Expression::BinaryOp(..) => "Binary operation",
|
Expression::BinaryOp(..) => "Binary operation",
|
||||||
Expression::Conditional(..) => "Conditional",
|
Expression::Conditional(..) => "Conditional",
|
||||||
|
Expression::While(_, _, _) => "While loop",
|
||||||
Expression::FunCall(..) => "Function call",
|
Expression::FunCall(..) => "Function call",
|
||||||
Expression::Block(..) => "Block",
|
Expression::Block(..) => "Block",
|
||||||
}
|
}
|
||||||
|
@ -66,6 +73,7 @@ impl<'source> Expression<'source> {
|
||||||
Expression::VarDeclaration(_, name, _) => name.to_string(),
|
Expression::VarDeclaration(_, name, _) => name.to_string(),
|
||||||
Expression::BinaryOp(_, _, op, _) => op.to_string(),
|
Expression::BinaryOp(_, _, op, _) => op.to_string(),
|
||||||
Expression::Conditional(_, condition, _, _) => format!("if {}", condition),
|
Expression::Conditional(_, condition, _, _) => format!("if {}", condition),
|
||||||
|
Expression::While(_, condition, _) => format!("while {}", condition),
|
||||||
Expression::FunCall(_, name, args) => format!("{} with {} args", name, args.len()),
|
Expression::FunCall(_, name, args) => format!("{} with {} args", name, args.len()),
|
||||||
Expression::Block(_, expressions) => format!("with {} expressions", expressions.len()),
|
Expression::Block(_, expressions) => format!("with {} expressions", expressions.len()),
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_empty() {
|
fn test_empty() {
|
||||||
|
@ -599,3 +611,43 @@ fn test_omitting_semicolons() {
|
||||||
fn test_omitting_semicolons_invalid() {
|
fn test_omitting_semicolons_invalid() {
|
||||||
parse(&tokenize("{ if true then { a } b c }"));
|
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"));
|
||||||
|
}
|
||||||
|
|
Reference in a new issue