Add failing control flow test with new panic function
This commit is contained in:
parent
bd23853657
commit
10abd91c85
@ -346,11 +346,10 @@ impl Instruction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn yields_value(&self) -> bool {
|
pub fn yields_value(&self) -> bool {
|
||||||
matches!(
|
if matches!(
|
||||||
self.operation(),
|
self.operation(),
|
||||||
Operation::Add
|
Operation::Add
|
||||||
| Operation::Call
|
| Operation::Call
|
||||||
| Operation::CallNative
|
|
||||||
| Operation::Divide
|
| Operation::Divide
|
||||||
| Operation::GetLocal
|
| Operation::GetLocal
|
||||||
| Operation::LoadBoolean
|
| Operation::LoadBoolean
|
||||||
@ -362,7 +361,17 @@ impl Instruction {
|
|||||||
| Operation::Negate
|
| Operation::Negate
|
||||||
| Operation::Not
|
| Operation::Not
|
||||||
| Operation::Subtract
|
| Operation::Subtract
|
||||||
)
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if matches!(self.operation(), Operation::CallNative) {
|
||||||
|
let native_function = NativeFunction::from(self.b());
|
||||||
|
|
||||||
|
return native_function.returns_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disassembly_info(&self, chunk: Option<&Chunk>) -> String {
|
pub fn disassembly_info(&self, chunk: Option<&Chunk>) -> String {
|
||||||
@ -582,11 +591,12 @@ impl Instruction {
|
|||||||
let native_function = NativeFunction::from(self.b());
|
let native_function = NativeFunction::from(self.b());
|
||||||
let argument_count = self.c();
|
let argument_count = self.c();
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
|
|
||||||
if native_function.returns_value() {
|
|
||||||
let native_function_name = native_function.as_str();
|
let native_function_name = native_function.as_str();
|
||||||
|
|
||||||
|
if native_function.returns_value() {
|
||||||
output.push_str(&format!("R{} = {}(", to_register, native_function_name));
|
output.push_str(&format!("R{} = {}(", to_register, native_function_name));
|
||||||
|
} else {
|
||||||
|
output.push_str(&format!("{}(", native_function_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
if argument_count != 0 {
|
if argument_count != 0 {
|
||||||
@ -601,9 +611,7 @@ impl Instruction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if native_function.returns_value() {
|
|
||||||
output.push(')');
|
output.push(')');
|
||||||
}
|
|
||||||
|
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
@ -1101,7 +1101,7 @@ impl<'src> Parser<'src> {
|
|||||||
self.allow(Token::Comma)?;
|
self.allow(Token::Comma)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let end = self.current_position.1;
|
let end = self.previous_position.1;
|
||||||
let to_register = self.next_register();
|
let to_register = self.next_register();
|
||||||
let argument_count = to_register - start_register;
|
let argument_count = to_register - start_register;
|
||||||
self.current_is_expression = native_function.returns_value();
|
self.current_is_expression = native_function.returns_value();
|
||||||
|
293
dust-lang/tests/control_flow.rs
Normal file
293
dust-lang/tests/control_flow.rs
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
use dust_lang::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn equality_assignment_long() {
|
||||||
|
let source = "let a = if 4 == 4 { true } else { false }; a";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::equal(true, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(13, 15)
|
||||||
|
),
|
||||||
|
(Instruction::jump(3), Span(13, 15)),
|
||||||
|
(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)),
|
||||||
|
],
|
||||||
|
vec![Value::integer(4), Value::integer(4)],
|
||||||
|
vec![Local::new(Identifier::new("a"), None, false, 0, 0)]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn equality_assignment_short() {
|
||||||
|
let source = "let a = 4 == 4 a";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::equal(true, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(10, 12)
|
||||||
|
),
|
||||||
|
(Instruction::jump(3), 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)),
|
||||||
|
],
|
||||||
|
vec![Value::integer(4), Value::integer(4)],
|
||||||
|
vec![Local::new(Identifier::new("a"), None, false, 0, 0)]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn if_else_complex() {
|
||||||
|
let source = "
|
||||||
|
if 1 == 1 {
|
||||||
|
1; 2; 3; 4;
|
||||||
|
} else {
|
||||||
|
1; 2; 3; 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)
|
||||||
|
),
|
||||||
|
(Instruction::jump(7), Span(14, 16)),
|
||||||
|
(Instruction::load_constant(0, 2, false), Span(33, 34)),
|
||||||
|
(Instruction::load_constant(1, 3, false), Span(36, 37)),
|
||||||
|
(Instruction::load_constant(2, 4, false), Span(39, 40)),
|
||||||
|
(Instruction::load_constant(3, 5, false), Span(42, 43)),
|
||||||
|
(Instruction::jump(11), Span(95, 95)),
|
||||||
|
(Instruction::load_constant(4, 6, false), Span(74, 75)),
|
||||||
|
(Instruction::load_constant(5, 7, false), Span(77, 78)),
|
||||||
|
(Instruction::load_constant(6, 8, false), Span(80, 81)),
|
||||||
|
(Instruction::load_constant(7, 9, false), Span(83, 84)),
|
||||||
|
(Instruction::r#return(true), Span(95, 95)),
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Value::integer(1),
|
||||||
|
Value::integer(1),
|
||||||
|
Value::integer(1),
|
||||||
|
Value::integer(2),
|
||||||
|
Value::integer(3),
|
||||||
|
Value::integer(4),
|
||||||
|
Value::integer(1),
|
||||||
|
Value::integer(2),
|
||||||
|
Value::integer(3),
|
||||||
|
Value::integer(4)
|
||||||
|
],
|
||||||
|
vec![]
|
||||||
|
))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[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)
|
||||||
|
// ),
|
||||||
|
// (Instruction::jump(7), Span(14, 16)),
|
||||||
|
// (
|
||||||
|
// *Instruction::equal(true, 0, 2)
|
||||||
|
// .set_b_is_constant()
|
||||||
|
// .set_c_is_constant(),
|
||||||
|
// Span(38, 41)
|
||||||
|
// ),
|
||||||
|
// (Instruction::jump(3), Span(38, 41)),
|
||||||
|
// (Instruction::load_constant(0, 1, false), Span(61, 62)),
|
||||||
|
// (Instruction::jump(11), Span(95, 95)),
|
||||||
|
// (
|
||||||
|
// *Instruction::equal(true, 0, 3)
|
||||||
|
// .set_b_is_constant()
|
||||||
|
// .set_c_is_constant(),
|
||||||
|
// Span(77, 79)
|
||||||
|
// ),
|
||||||
|
// (Instruction::jump(3), Span(77, 79)),
|
||||||
|
// (Instruction::load_constant(0, 2, false), Span(94, 95)),
|
||||||
|
// (Instruction::jump(11), Span(95, 95)),
|
||||||
|
// (Instruction::load_constant(0, 3, false), Span(114, 115)),
|
||||||
|
// (Instruction::jump(11), Span(95, 95)),
|
||||||
|
// (Instruction::load_constant(0, 4, false), Span(134, 135)),
|
||||||
|
// (Instruction::r#return(true), Span(146, 146)),
|
||||||
|
// ],
|
||||||
|
// vec![
|
||||||
|
// Value::integer(0),
|
||||||
|
// Value::integer(1),
|
||||||
|
// Value::integer(0),
|
||||||
|
// Value::integer(2),
|
||||||
|
// Value::integer(1),
|
||||||
|
// Value::integer(0),
|
||||||
|
// Value::integer(3),
|
||||||
|
// Value::integer(3),
|
||||||
|
// Value::integer(4)
|
||||||
|
// ],
|
||||||
|
// vec![]
|
||||||
|
// ))
|
||||||
|
// );
|
||||||
|
|
||||||
|
// assert_eq!(run(source), Ok(Some(Value::integer(4))));
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn if_else_false() {
|
||||||
|
let source = "if 1 == 2 { panic() } else { 42 }";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::equal(true, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(5, 7)
|
||||||
|
),
|
||||||
|
(Instruction::jump(3), Span(5, 7)),
|
||||||
|
(
|
||||||
|
Instruction::call_native(0, NativeFunction::Panic, 0),
|
||||||
|
Span(12, 19)
|
||||||
|
),
|
||||||
|
(Instruction::load_constant(0, 2, false), Span(29, 31)),
|
||||||
|
(Instruction::r#return(true), Span(33, 33)),
|
||||||
|
],
|
||||||
|
vec![Value::integer(1), Value::integer(2), Value::integer(42)],
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::integer(42))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn if_else_true() {
|
||||||
|
let source = "if 1 == 1 { 42 } else { panic() }";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::equal(true, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(5, 7)
|
||||||
|
),
|
||||||
|
(Instruction::jump(3), Span(5, 7)),
|
||||||
|
(Instruction::load_constant(0, 2, false), Span(12, 14)),
|
||||||
|
(
|
||||||
|
Instruction::call_native(1, NativeFunction::Panic, 0),
|
||||||
|
Span(24, 31)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
vec![Value::integer(1), Value::integer(1), Value::integer(42)],
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::integer(42))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn if_expression_false() {
|
||||||
|
let source = "if 1 == 2 { 2 }";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::equal(true, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(5, 7)
|
||||||
|
),
|
||||||
|
(Instruction::jump(3), Span(5, 7)),
|
||||||
|
(Instruction::load_constant(0, 2, false), Span(12, 13)),
|
||||||
|
],
|
||||||
|
vec![Value::integer(1), Value::integer(2), Value::integer(2)],
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(None));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn if_expression_true() {
|
||||||
|
let source = "if 1 == 1 { 2 }";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::equal(true, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(5, 7)
|
||||||
|
),
|
||||||
|
(Instruction::jump(3), Span(5, 7)),
|
||||||
|
(Instruction::load_constant(0, 2, false), Span(12, 13)),
|
||||||
|
],
|
||||||
|
vec![Value::integer(1), Value::integer(1), Value::integer(2)],
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(None));
|
||||||
|
}
|
@ -271,66 +271,6 @@ fn equal() {
|
|||||||
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn equality_assignment_long() {
|
|
||||||
let source = "let a = if 4 == 4 { true } else { false }; a";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
*Instruction::equal(true, 0, 1)
|
|
||||||
.set_b_is_constant()
|
|
||||||
.set_c_is_constant(),
|
|
||||||
Span(13, 15)
|
|
||||||
),
|
|
||||||
(Instruction::jump(3), Span(13, 15)),
|
|
||||||
(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)),
|
|
||||||
],
|
|
||||||
vec![Value::integer(4), Value::integer(4)],
|
|
||||||
vec![Local::new(Identifier::new("a"), None, false, 0, 0)]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn equality_assignment_short() {
|
|
||||||
let source = "let a = 4 == 4 a";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
*Instruction::equal(true, 0, 1)
|
|
||||||
.set_b_is_constant()
|
|
||||||
.set_c_is_constant(),
|
|
||||||
Span(10, 12)
|
|
||||||
),
|
|
||||||
(Instruction::jump(3), 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)),
|
|
||||||
],
|
|
||||||
vec![Value::integer(4), Value::integer(4)],
|
|
||||||
vec![Local::new(Identifier::new("a"), None, false, 0, 0)]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn function() {
|
fn function() {
|
||||||
let source = "fn(a: int, b: int) -> int { a + b }";
|
let source = "fn(a: int, b: int) -> int { a + b }";
|
||||||
@ -520,210 +460,6 @@ fn greater_than_or_equal() {
|
|||||||
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn if_else_complex() {
|
|
||||||
let source = "
|
|
||||||
if 1 == 1 {
|
|
||||||
1; 2; 3; 4;
|
|
||||||
} else {
|
|
||||||
1; 2; 3; 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)
|
|
||||||
),
|
|
||||||
(Instruction::jump(7), Span(14, 16)),
|
|
||||||
(Instruction::load_constant(0, 2, false), Span(33, 34)),
|
|
||||||
(Instruction::load_constant(1, 3, false), Span(36, 37)),
|
|
||||||
(Instruction::load_constant(2, 4, false), Span(39, 40)),
|
|
||||||
(Instruction::load_constant(3, 5, false), Span(42, 43)),
|
|
||||||
(Instruction::jump(11), Span(95, 95)),
|
|
||||||
(Instruction::load_constant(4, 6, false), Span(74, 75)),
|
|
||||||
(Instruction::load_constant(5, 7, false), Span(77, 78)),
|
|
||||||
(Instruction::load_constant(6, 8, false), Span(80, 81)),
|
|
||||||
(Instruction::load_constant(7, 9, false), Span(83, 84)),
|
|
||||||
(Instruction::r#return(true), Span(95, 95)),
|
|
||||||
],
|
|
||||||
vec![
|
|
||||||
Value::integer(1),
|
|
||||||
Value::integer(1),
|
|
||||||
Value::integer(1),
|
|
||||||
Value::integer(2),
|
|
||||||
Value::integer(3),
|
|
||||||
Value::integer(4),
|
|
||||||
Value::integer(1),
|
|
||||||
Value::integer(2),
|
|
||||||
Value::integer(3),
|
|
||||||
Value::integer(4)
|
|
||||||
],
|
|
||||||
vec![]
|
|
||||||
))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[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)
|
|
||||||
// ),
|
|
||||||
// (Instruction::jump(7), Span(14, 16)),
|
|
||||||
// (
|
|
||||||
// *Instruction::equal(true, 0, 2)
|
|
||||||
// .set_b_is_constant()
|
|
||||||
// .set_c_is_constant(),
|
|
||||||
// Span(38, 41)
|
|
||||||
// ),
|
|
||||||
// (Instruction::jump(3), Span(38, 41)),
|
|
||||||
// (Instruction::load_constant(0, 1, false), Span(61, 62)),
|
|
||||||
// (Instruction::jump(11), Span(95, 95)),
|
|
||||||
// (
|
|
||||||
// *Instruction::equal(true, 0, 3)
|
|
||||||
// .set_b_is_constant()
|
|
||||||
// .set_c_is_constant(),
|
|
||||||
// Span(77, 79)
|
|
||||||
// ),
|
|
||||||
// (Instruction::jump(3), Span(77, 79)),
|
|
||||||
// (Instruction::load_constant(0, 2, false), Span(94, 95)),
|
|
||||||
// (Instruction::jump(11), Span(95, 95)),
|
|
||||||
// (Instruction::load_constant(0, 3, false), Span(114, 115)),
|
|
||||||
// (Instruction::jump(11), Span(95, 95)),
|
|
||||||
// (Instruction::load_constant(0, 4, false), Span(134, 135)),
|
|
||||||
// (Instruction::r#return(true), Span(146, 146)),
|
|
||||||
// ],
|
|
||||||
// vec![
|
|
||||||
// Value::integer(0),
|
|
||||||
// Value::integer(1),
|
|
||||||
// Value::integer(0),
|
|
||||||
// Value::integer(2),
|
|
||||||
// Value::integer(1),
|
|
||||||
// Value::integer(0),
|
|
||||||
// Value::integer(3),
|
|
||||||
// Value::integer(3),
|
|
||||||
// Value::integer(4)
|
|
||||||
// ],
|
|
||||||
// vec![]
|
|
||||||
// ))
|
|
||||||
// );
|
|
||||||
|
|
||||||
// assert_eq!(run(source), Ok(Some(Value::integer(4))));
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn if_else_simple() {
|
|
||||||
let source = "if 1 == 1 { 2 } else { 3 }";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
*Instruction::equal(true, 0, 1)
|
|
||||||
.set_b_is_constant()
|
|
||||||
.set_c_is_constant(),
|
|
||||||
Span(5, 7)
|
|
||||||
),
|
|
||||||
(Instruction::jump(3), Span(5, 7)),
|
|
||||||
(Instruction::load_constant(0, 2, true), Span(12, 13)),
|
|
||||||
(Instruction::load_constant(0, 3, false), Span(23, 24)),
|
|
||||||
(Instruction::r#return(true), Span(26, 26)),
|
|
||||||
],
|
|
||||||
vec![
|
|
||||||
Value::integer(1),
|
|
||||||
Value::integer(1),
|
|
||||||
Value::integer(2),
|
|
||||||
Value::integer(3)
|
|
||||||
],
|
|
||||||
vec![]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(Some(Value::integer(2))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn if_expression_false() {
|
|
||||||
let source = "if 1 == 2 { 2 }";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
*Instruction::equal(true, 0, 1)
|
|
||||||
.set_b_is_constant()
|
|
||||||
.set_c_is_constant(),
|
|
||||||
Span(5, 7)
|
|
||||||
),
|
|
||||||
(Instruction::jump(3), Span(5, 7)),
|
|
||||||
(Instruction::load_constant(0, 2, false), Span(12, 13)),
|
|
||||||
],
|
|
||||||
vec![Value::integer(1), Value::integer(2), Value::integer(2)],
|
|
||||||
vec![]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(None));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn if_expression_true() {
|
|
||||||
let source = "if 1 == 1 { 2 }";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
*Instruction::equal(true, 0, 1)
|
|
||||||
.set_b_is_constant()
|
|
||||||
.set_c_is_constant(),
|
|
||||||
Span(5, 7)
|
|
||||||
),
|
|
||||||
(Instruction::jump(3), Span(5, 7)),
|
|
||||||
(Instruction::load_constant(0, 2, false), Span(12, 13)),
|
|
||||||
],
|
|
||||||
vec![Value::integer(1), Value::integer(1), Value::integer(2)],
|
|
||||||
vec![]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(None));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn less_than() {
|
fn less_than() {
|
||||||
let source = "1 < 2";
|
let source = "1 < 2";
|
||||||
|
Loading…
Reference in New Issue
Block a user