1
0
dust/dust-lang/tests/control_flow.rs

480 lines
16 KiB
Rust
Raw Normal View History

use dust_lang::*;
#[test]
fn equality_assignment_long() {
let source = "let a = if 4 == 4 { true } else { false }; a";
assert_eq!(
2024-11-06 20:40:37 +00:00
compile(source),
Ok(Chunk::with_data(
None,
2024-11-16 10:16:51 +00:00
FunctionType {
type_parameters: None,
value_parameters: None,
return_type: Box::new(Type::Boolean)
},
vec![
(
*Instruction::equal(true, 0, 0)
.set_b_is_constant()
.set_c_is_constant(),
Span(13, 15)
),
2024-11-06 19:46:23 +00:00
(Instruction::jump(1, true), Span(18, 19)),
(Instruction::load_boolean(0, true, true), Span(20, 24)),
(Instruction::load_boolean(0, false, false), Span(34, 39)),
(Instruction::define_local(0, 0, false), Span(4, 5)),
(Instruction::get_local(1, 0), Span(43, 44)),
(Instruction::r#return(true), Span(44, 44)),
],
2024-11-16 06:29:21 +00:00
vec![ConcreteValue::Integer(4), ConcreteValue::string("a")],
vec![Local::new(1, Type::Boolean, false, Scope::default(),)]
)),
);
2024-11-16 06:29:21 +00:00
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true))));
}
#[test]
fn equality_assignment_short() {
let source = "let a = 4 == 4 a";
assert_eq!(
2024-11-06 20:40:37 +00:00
compile(source),
Ok(Chunk::with_data(
None,
2024-11-16 10:16:51 +00:00
FunctionType {
type_parameters: None,
value_parameters: None,
return_type: Box::new(Type::Boolean)
},
vec![
(
*Instruction::equal(true, 0, 0)
.set_b_is_constant()
.set_c_is_constant(),
Span(10, 12)
),
2024-10-30 18:48:30 +00:00
(Instruction::jump(1, true), Span(10, 12)),
(Instruction::load_boolean(0, true, true), Span(10, 12)),
(Instruction::load_boolean(0, false, false), Span(10, 12)),
(Instruction::define_local(0, 0, false), Span(4, 5)),
(Instruction::get_local(1, 0), Span(15, 16)),
(Instruction::r#return(true), Span(16, 16)),
],
2024-11-16 06:29:21 +00:00
vec![ConcreteValue::Integer(4), ConcreteValue::string("a")],
vec![Local::new(1, Type::Boolean, false, Scope::default())]
)),
);
2024-11-16 06:29:21 +00:00
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true))));
}
#[test]
2024-11-06 19:46:23 +00:00
fn if_else_assigment_false() {
let source = r#"
let a = if 4 == 3 {
2024-11-16 10:16:51 +00:00
panic();
0
2024-11-06 19:46:23 +00:00
} else {
1; 2; 3; 4;
42
};
a"#;
assert_eq!(
2024-11-06 20:40:37 +00:00
compile(source),
2024-11-06 19:46:23 +00:00
Ok(Chunk::with_data(
None,
2024-11-16 10:16:51 +00:00
FunctionType {
type_parameters: None,
value_parameters: None,
return_type: Box::new(Type::Integer)
},
2024-11-06 19:46:23 +00:00
vec![
(
*Instruction::equal(true, 0, 1)
.set_b_is_constant()
.set_c_is_constant(),
Span(22, 24)
),
2024-11-16 10:16:51 +00:00
(Instruction::jump(3, true), Span(27, 28)),
2024-11-06 19:46:23 +00:00
(
2024-11-16 10:16:51 +00:00
Instruction::call_native(0, NativeFunction::Panic, 0),
Span(41, 48)
2024-11-06 19:46:23 +00:00
),
2024-11-16 10:16:51 +00:00
(Instruction::load_constant(0, 2, false), Span(62, 63)),
(Instruction::jump(5, true), Span(129, 130)),
(Instruction::load_constant(1, 3, false), Span(93, 94)),
(Instruction::load_constant(2, 4, false), Span(96, 97)),
(Instruction::load_constant(3, 1, false), Span(99, 100)),
(Instruction::load_constant(4, 0, false), Span(102, 103)),
(Instruction::load_constant(5, 5, false), Span(117, 119)),
(Instruction::r#move(5, 0), Span(129, 130)),
(Instruction::define_local(5, 0, false), Span(13, 14)),
(Instruction::get_local(6, 0), Span(139, 140)),
(Instruction::r#return(true), Span(140, 140)),
2024-11-06 19:46:23 +00:00
],
vec![
2024-11-16 06:29:21 +00:00
ConcreteValue::Integer(4),
ConcreteValue::Integer(3),
2024-11-16 10:16:51 +00:00
ConcreteValue::Integer(0),
2024-11-16 06:29:21 +00:00
ConcreteValue::Integer(1),
ConcreteValue::Integer(2),
ConcreteValue::Integer(42),
ConcreteValue::string("a")
2024-11-06 19:46:23 +00:00
],
2024-11-16 10:16:51 +00:00
vec![Local::new(6, Type::Integer, false, Scope::default())]
2024-11-06 19:46:23 +00:00
)),
);
2024-11-16 06:29:21 +00:00
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(42))));
2024-11-06 19:46:23 +00:00
}
#[test]
fn if_else_assigment_true() {
let source = r#"
let a = if 4 == 4 {
1; 2; 3; 4;
42
} else {
2024-11-16 10:16:51 +00:00
panic();
0
};
a"#;
assert_eq!(
2024-11-06 20:40:37 +00:00
compile(source),
Ok(Chunk::with_data(
None,
2024-11-16 10:16:51 +00:00
FunctionType {
type_parameters: None,
value_parameters: None,
return_type: Box::new(Type::Integer)
},
vec![
(
*Instruction::equal(true, 0, 0)
.set_b_is_constant()
.set_c_is_constant(),
Span(22, 24)
),
2024-11-06 19:46:23 +00:00
(Instruction::jump(6, true), Span(27, 28)),
(Instruction::load_constant(0, 1, false), Span(41, 42)),
(Instruction::load_constant(1, 2, false), Span(44, 45)),
(Instruction::load_constant(2, 3, false), Span(47, 48)),
(Instruction::load_constant(3, 0, false), Span(50, 51)),
(Instruction::load_constant(4, 4, false), Span(65, 67)),
2024-11-16 10:16:51 +00:00
(Instruction::jump(2, true), Span(129, 130)),
(
Instruction::call_native(5, NativeFunction::Panic, 0),
2024-11-16 10:16:51 +00:00
Span(97, 104)
),
2024-11-16 10:16:51 +00:00
(Instruction::load_constant(5, 5, false), Span(118, 119)),
(Instruction::r#move(5, 4), Span(129, 130)),
(Instruction::define_local(5, 0, false), Span(13, 14)),
(Instruction::get_local(6, 0), Span(139, 140)),
(Instruction::r#return(true), Span(140, 140)),
],
vec![
2024-11-16 06:29:21 +00:00
ConcreteValue::Integer(4),
ConcreteValue::Integer(1),
ConcreteValue::Integer(2),
ConcreteValue::Integer(3),
ConcreteValue::Integer(42),
2024-11-16 10:16:51 +00:00
ConcreteValue::Integer(0),
2024-11-16 06:29:21 +00:00
ConcreteValue::string("a")
],
2024-11-16 10:16:51 +00:00
vec![Local::new(6, Type::Integer, false, Scope::default())]
)),
);
2024-11-16 06:29:21 +00:00
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(42))));
}
#[test]
fn if_else_complex() {
let source = "
if 1 == 1 {
1; 2; 3; 4;
} else {
1; 2; 3; 4;
}";
assert_eq!(
2024-11-06 20:40:37 +00:00
compile(source),
Ok(Chunk::with_data(
None,
2024-11-16 10:16:51 +00:00
FunctionType {
type_parameters: None,
value_parameters: None,
return_type: Box::new(Type::None)
},
vec![
(
*Instruction::equal(true, 0, 0)
.set_b_is_constant()
.set_c_is_constant(),
Span(14, 16)
),
2024-11-06 19:46:23 +00:00
(Instruction::jump(5, true), Span(19, 20)),
(Instruction::load_constant(0, 0, false), Span(33, 34)),
(Instruction::load_constant(1, 1, false), Span(36, 37)),
(Instruction::load_constant(2, 2, false), Span(39, 40)),
(Instruction::load_constant(3, 3, false), Span(42, 43)),
2024-10-30 18:48:30 +00:00
(Instruction::jump(4, true), Span(95, 95)),
(Instruction::load_constant(4, 0, false), Span(74, 75)),
(Instruction::load_constant(5, 1, false), Span(77, 78)),
(Instruction::load_constant(6, 2, false), Span(80, 81)),
(Instruction::load_constant(7, 3, false), Span(83, 84)),
(Instruction::r#move(7, 3), Span(95, 95)),
(Instruction::r#return(false), Span(95, 95)),
],
vec![
2024-11-16 06:29:21 +00:00
ConcreteValue::Integer(1),
ConcreteValue::Integer(2),
ConcreteValue::Integer(3),
ConcreteValue::Integer(4),
],
vec![]
))
);
assert_eq!(run(source), Ok(None));
}
// #[test]
// fn if_else_nested() {
// let source = r#"
// if 0 == 1 {
// if 0 == 2 {
// 1;
// } else {
// 2;
// }
// } else {
// if 0 == 3 {
// 3;
// } else {
// 4;
// }
// }"#;
// assert_eq!(
// parse(source),
// Ok(Chunk::with_data(
// None,
// vec![
// (
// *Instruction::equal(true, 0, 1)
// .set_b_is_constant()
// .set_c_is_constant(),
// Span(14, 16)
// ),
2024-10-30 18:48:30 +00:00
// (Instruction::jump(7, true), Span(14, 16)),
// (
// *Instruction::equal(true, 0, 2)
// .set_b_is_constant()
// .set_c_is_constant(),
// Span(38, 41)
// ),
2024-10-30 18:48:30 +00:00
// (Instruction::jump(3, true), Span(38, 41)),
// (Instruction::load_constant(0, 1, false), Span(61, 62)),
2024-10-30 18:48:30 +00:00
// (Instruction::jump(1, true1), Span(95, 95)),
// (
// *Instruction::equal(true, 0, 3)
// .set_b_is_constant()
// .set_c_is_constant(),
// Span(77, 79)
// ),
2024-10-30 18:48:30 +00:00
// (Instruction::jump(3, true), Span(77, 79)),
// (Instruction::load_constant(0, 2, false), Span(94, 95)),
2024-10-30 18:48:30 +00:00
// (Instruction::jump(1, true1), Span(95, 95)),
// (Instruction::load_constant(0, 3, false), Span(114, 115)),
2024-10-30 18:48:30 +00:00
// (Instruction::jump(1, true1), Span(95, 95)),
// (Instruction::load_constant(0, 4, false), Span(134, 135)),
// (Instruction::r#return(true), Span(146, 146)),
// ],
// vec![
2024-11-16 06:29:21 +00:00
// ConcreteValue::integer(0),
// ConcreteValue::integer(1),
// ConcreteValue::integer(0),
// ConcreteValue::integer(2),
// ConcreteValue::integer(1),
// ConcreteValue::integer(0),
// ConcreteValue::integer(3),
// ConcreteValue::integer(3),
// ConcreteValue::integer(4)
// ],
// vec![]
// ))
// );
2024-11-16 06:29:21 +00:00
// assert_eq!(run(source), Ok(Some(ConcreteValue::integer(4))));
// }
#[test]
fn if_else_false() {
let source = "if 1 == 2 { panic(); 0 } else { 42 }";
assert_eq!(
2024-11-06 20:40:37 +00:00
compile(source),
Ok(Chunk::with_data(
None,
2024-11-16 10:16:51 +00:00
FunctionType {
type_parameters: None,
value_parameters: None,
return_type: Box::new(Type::Integer)
},
vec![
(
*Instruction::equal(true, 0, 1)
.set_b_is_constant()
.set_c_is_constant(),
Span(5, 7)
),
2024-11-16 10:40:31 +00:00
(Instruction::jump(2, true), Span(10, 11)),
(
Instruction::call_native(0, NativeFunction::Panic, 0),
Span(12, 19)
),
2024-11-16 10:40:31 +00:00
(Instruction::load_constant(0, 2, true), Span(21, 22)),
(Instruction::load_constant(1, 3, false), Span(32, 34)),
(Instruction::r#move(1, 0), Span(36, 36)),
(Instruction::r#return(true), Span(36, 36)),
],
2024-11-11 00:28:21 +00:00
vec![
2024-11-16 06:29:21 +00:00
ConcreteValue::Integer(1),
ConcreteValue::Integer(2),
2024-11-16 10:40:31 +00:00
ConcreteValue::Integer(0),
2024-11-16 06:29:21 +00:00
ConcreteValue::Integer(42)
2024-11-11 00:28:21 +00:00
],
vec![]
)),
);
2024-11-16 06:29:21 +00:00
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(42))));
}
#[test]
fn if_else_true() {
let source = "if 1 == 1 { 42 } else { panic(); 0 }";
assert_eq!(
2024-11-06 20:40:37 +00:00
compile(source),
Ok(Chunk::with_data(
None,
2024-11-16 10:16:51 +00:00
FunctionType {
type_parameters: None,
value_parameters: None,
return_type: Box::new(Type::Integer)
},
vec![
(
*Instruction::equal(true, 0, 0)
.set_b_is_constant()
.set_c_is_constant(),
Span(5, 7)
),
2024-11-16 10:40:31 +00:00
(Instruction::jump(2, true), Span(10, 11)),
(Instruction::load_constant(0, 1, false), Span(12, 14)),
(Instruction::jump(2, true), Span(36, 36)),
(
Instruction::call_native(1, NativeFunction::Panic, 0),
Span(24, 31)
),
2024-11-16 10:40:31 +00:00
(Instruction::load_constant(1, 2, false), Span(33, 34)),
(Instruction::r#move(1, 0), Span(36, 36)),
(Instruction::r#return(true), Span(36, 36))
],
vec![
ConcreteValue::Integer(1),
ConcreteValue::Integer(42),
ConcreteValue::Integer(0)
],
vec![]
)),
);
2024-11-16 06:29:21 +00:00
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(42))));
}
#[test]
fn if_false() {
let source = "if 1 == 2 { panic() }";
assert_eq!(
2024-11-06 20:40:37 +00:00
compile(source),
Ok(Chunk::with_data(
None,
2024-11-16 10:16:51 +00:00
FunctionType {
type_parameters: None,
value_parameters: None,
return_type: Box::new(Type::None)
},
vec![
(
*Instruction::equal(true, 0, 1)
.set_b_is_constant()
.set_c_is_constant(),
Span(5, 7)
),
2024-11-06 19:46:23 +00:00
(Instruction::jump(1, true), Span(10, 11)),
(
Instruction::call_native(0, NativeFunction::Panic, 0),
Span(12, 19)
),
(Instruction::r#return(false), Span(21, 21))
],
2024-11-16 06:29:21 +00:00
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)],
vec![]
)),
);
assert_eq!(run(source), Ok(None));
}
#[test]
fn if_true() {
let source = "if 1 == 1 { panic() }";
assert_eq!(
2024-11-06 20:40:37 +00:00
compile(source),
Ok(Chunk::with_data(
None,
2024-11-16 10:16:51 +00:00
FunctionType {
type_parameters: None,
value_parameters: None,
return_type: Box::new(Type::None)
},
vec![
(
*Instruction::equal(true, 0, 0)
.set_b_is_constant()
.set_c_is_constant(),
Span(5, 7)
),
2024-11-06 19:46:23 +00:00
(Instruction::jump(1, true), Span(10, 11)),
(
Instruction::call_native(0, NativeFunction::Panic, 0),
Span(12, 19)
),
(Instruction::r#return(false), Span(21, 21))
],
2024-11-16 06:29:21 +00:00
vec![ConcreteValue::Integer(1)],
vec![]
)),
);
assert_eq!(
run(source),
Err(DustError::Runtime {
error: VmError::NativeFunction(NativeFunctionError::Panic {
message: None,
position: Span(12, 19)
}),
source
})
);
}