Add tests for chained logic operators
This commit is contained in:
parent
d2ee33c7df
commit
fe59024bf4
@ -98,3 +98,11 @@ path = "tests/logic/and_and.rs"
|
|||||||
[[test]]
|
[[test]]
|
||||||
name = "or_or"
|
name = "or_or"
|
||||||
path = "tests/logic/or_or.rs"
|
path = "tests/logic/or_or.rs"
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "and_or"
|
||||||
|
path = "tests/logic/and_or.rs"
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "or_and"
|
||||||
|
path = "tests/logic/or_and.rs"
|
||||||
|
@ -72,7 +72,7 @@ impl From<&Token<'_>> for ParseRule<'_> {
|
|||||||
Token::DoubleAmpersand => ParseRule {
|
Token::DoubleAmpersand => ParseRule {
|
||||||
prefix: None,
|
prefix: None,
|
||||||
infix: Some(Compiler::parse_logical_binary),
|
infix: Some(Compiler::parse_logical_binary),
|
||||||
precedence: Precedence::LogicalAnd,
|
precedence: Precedence::Logic,
|
||||||
},
|
},
|
||||||
Token::DoubleEqual => ParseRule {
|
Token::DoubleEqual => ParseRule {
|
||||||
prefix: None,
|
prefix: None,
|
||||||
@ -82,7 +82,7 @@ impl From<&Token<'_>> for ParseRule<'_> {
|
|||||||
Token::DoublePipe => ParseRule {
|
Token::DoublePipe => ParseRule {
|
||||||
prefix: None,
|
prefix: None,
|
||||||
infix: Some(Compiler::parse_logical_binary),
|
infix: Some(Compiler::parse_logical_binary),
|
||||||
precedence: Precedence::LogicalOr,
|
precedence: Precedence::Logic,
|
||||||
},
|
},
|
||||||
Token::DoubleDot => ParseRule {
|
Token::DoubleDot => ParseRule {
|
||||||
prefix: Some(Compiler::expect_expression),
|
prefix: Some(Compiler::expect_expression),
|
||||||
@ -284,14 +284,13 @@ impl From<&Token<'_>> for ParseRule<'_> {
|
|||||||
/// Operator precedence levels.
|
/// Operator precedence levels.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum Precedence {
|
pub enum Precedence {
|
||||||
Primary = 9,
|
Primary = 8,
|
||||||
Call = 8,
|
Call = 7,
|
||||||
Unary = 7,
|
Unary = 6,
|
||||||
Factor = 6,
|
Factor = 5,
|
||||||
Term = 5,
|
Term = 4,
|
||||||
Comparison = 4,
|
Comparison = 3,
|
||||||
LogicalAnd = 3,
|
Logic = 2,
|
||||||
LogicalOr = 2,
|
|
||||||
Assignment = 1,
|
Assignment = 1,
|
||||||
None = 0,
|
None = 0,
|
||||||
}
|
}
|
||||||
@ -300,9 +299,8 @@ impl Precedence {
|
|||||||
pub fn increment(&self) -> Self {
|
pub fn increment(&self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Precedence::None => Precedence::Assignment,
|
Precedence::None => Precedence::Assignment,
|
||||||
Precedence::Assignment => Precedence::LogicalOr,
|
Precedence::Assignment => Precedence::Logic,
|
||||||
Precedence::LogicalOr => Precedence::LogicalAnd,
|
Precedence::Logic => Precedence::Comparison,
|
||||||
Precedence::LogicalAnd => Precedence::Comparison,
|
|
||||||
Precedence::Comparison => Precedence::Term,
|
Precedence::Comparison => Precedence::Term,
|
||||||
Precedence::Term => Precedence::Factor,
|
Precedence::Term => Precedence::Factor,
|
||||||
Precedence::Factor => Precedence::Unary,
|
Precedence::Factor => Precedence::Unary,
|
||||||
|
267
dust-lang/tests/logic/and_or.rs
Normal file
267
dust-lang/tests/logic/and_or.rs
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
use dust_lang::{
|
||||||
|
Chunk, FunctionType, Instruction, Span, Type, Value, compile, instruction::TypeCode, run,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn true_and_true_or_true() {
|
||||||
|
let source = "true && true || true";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 4),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(8, 12),
|
||||||
|
Span(13, 15),
|
||||||
|
Span(13, 15),
|
||||||
|
Span(16, 20),
|
||||||
|
Span(20, 20),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(true));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn true_and_false_or_true() {
|
||||||
|
let source = "true && false || true";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 4),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(8, 13),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(17, 21),
|
||||||
|
Span(21, 21),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(true));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn true_and_true_or_false() {
|
||||||
|
let source = "true && true || false";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 4),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(8, 12),
|
||||||
|
Span(13, 15),
|
||||||
|
Span(13, 15),
|
||||||
|
Span(16, 21),
|
||||||
|
Span(21, 21),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(true));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn true_and_false_or_false() {
|
||||||
|
let source = "true && false || false";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 4),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(8, 13),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(17, 22),
|
||||||
|
Span(22, 22),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(false));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn false_and_true_or_true() {
|
||||||
|
let source = "false && true || true";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 5),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(9, 13),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(17, 21),
|
||||||
|
Span(21, 21),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(false));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn false_and_false_or_true() {
|
||||||
|
let source = "false && false || true";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 5),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(9, 14),
|
||||||
|
Span(15, 17),
|
||||||
|
Span(15, 17),
|
||||||
|
Span(18, 22),
|
||||||
|
Span(22, 22),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(false));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn false_and_true_or_false() {
|
||||||
|
let source = "false && true || false";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 5),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(9, 13),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(17, 22),
|
||||||
|
Span(22, 22),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(false));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn false_and_false_or_false() {
|
||||||
|
let source = "false && false || false";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 5),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(9, 14),
|
||||||
|
Span(15, 17),
|
||||||
|
Span(15, 17),
|
||||||
|
Span(18, 23),
|
||||||
|
Span(23, 23),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(false));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
266
dust-lang/tests/logic/or_and.rs
Normal file
266
dust-lang/tests/logic/or_and.rs
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
use dust_lang::{
|
||||||
|
Chunk, FunctionType, Instruction, Span, Type, Value, compile, instruction::TypeCode, run,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn true_or_true_and_true() {
|
||||||
|
let source = "true || true && true";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 4),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(8, 12),
|
||||||
|
Span(13, 15),
|
||||||
|
Span(13, 15),
|
||||||
|
Span(16, 20),
|
||||||
|
Span(20, 20),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(true));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn true_or_false_or_true() {
|
||||||
|
let source = "true || false || true";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 4),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(8, 13),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(17, 21),
|
||||||
|
Span(21, 21),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(true));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn true_or_true_and_false() {
|
||||||
|
let source = "true || true && false";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 4),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(8, 12),
|
||||||
|
Span(13, 15),
|
||||||
|
Span(13, 15),
|
||||||
|
Span(16, 21),
|
||||||
|
Span(21, 21),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(true));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn true_or_false_and_false() {
|
||||||
|
let source = "true || false && false";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 4),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(5, 7),
|
||||||
|
Span(8, 13),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(17, 22),
|
||||||
|
Span(22, 22),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(true));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn false_or_true_and_true() {
|
||||||
|
let source = "false || true && true";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 5),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(9, 13),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(17, 21),
|
||||||
|
Span(21, 21),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(true));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn false_or_false_and_true() {
|
||||||
|
let source = "false || false && true";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 5),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(9, 14),
|
||||||
|
Span(15, 17),
|
||||||
|
Span(15, 17),
|
||||||
|
Span(18, 22),
|
||||||
|
Span(22, 22),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(false));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn false_or_true_and_false() {
|
||||||
|
let source = "false || true && false";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 5),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(9, 13),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(14, 16),
|
||||||
|
Span(17, 22),
|
||||||
|
Span(22, 22),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(false));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn false_or_false_and_false() {
|
||||||
|
let source = "false || false && false";
|
||||||
|
let chunk = Chunk {
|
||||||
|
r#type: FunctionType::new([], [], Type::Boolean),
|
||||||
|
instructions: vec![
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, false),
|
||||||
|
Instruction::jump(4, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::test(0, true),
|
||||||
|
Instruction::jump(1, true),
|
||||||
|
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
|
||||||
|
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||||
|
],
|
||||||
|
positions: vec![
|
||||||
|
Span(0, 5),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(6, 8),
|
||||||
|
Span(9, 14),
|
||||||
|
Span(15, 17),
|
||||||
|
Span(15, 17),
|
||||||
|
Span(18, 23),
|
||||||
|
Span(23, 23),
|
||||||
|
],
|
||||||
|
..Chunk::default()
|
||||||
|
};
|
||||||
|
let return_value = Some(Value::boolean(false));
|
||||||
|
|
||||||
|
assert_eq!(chunk, compile(source).unwrap());
|
||||||
|
assert_eq!(return_value, run(source).unwrap());
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user