1
0
dust/dust-lang/tests/values.rs
2025-02-07 19:37:39 -05:00

445 lines
15 KiB
Rust

use dust_lang::{
Chunk, ConcreteValue, DustString, FunctionType, Instruction, Span, Type, Value, compile,
instruction::TypeCode, run,
};
#[test]
fn load_boolean_true() {
let source = "true";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::Boolean,
..FunctionType::default()
},
instructions: vec![
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
],
positions: vec![Span(0, 4), Span(4, 4)],
..Chunk::default()
};
let return_value = Some(Value::boolean(true));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_boolean_false() {
let source = "false";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::Boolean,
..FunctionType::default()
},
instructions: vec![
Instruction::load_encoded(0, false as u8, TypeCode::BOOLEAN, false),
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
],
positions: vec![Span(0, 5), Span(5, 5)],
..Chunk::default()
};
let return_value = Some(Value::boolean(false));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_byte() {
let source = "0x2a";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::Byte,
..FunctionType::default()
},
instructions: vec![
Instruction::load_encoded(0, 0x2a, TypeCode::BYTE, false),
Instruction::r#return(true, 0, TypeCode::BYTE),
],
positions: vec![Span(0, 6), Span(6, 6)],
..Chunk::default()
};
let return_value = Some(Value::byte(0x2a));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_character() {
let source = "'a'";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::Character,
..FunctionType::default()
},
instructions: vec![
Instruction::load_constant(0, 0, TypeCode::CHARACTER, false),
Instruction::r#return(true, 0, TypeCode::CHARACTER),
],
positions: vec![Span(0, 3), Span(3, 3)],
constants: vec![ConcreteValue::Character('a')],
..Chunk::default()
};
let return_value = Some(Value::character('a'));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_float() {
let source = "42.42";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::Float,
..FunctionType::default()
},
instructions: vec![
Instruction::load_constant(0, 0, TypeCode::FLOAT, false),
Instruction::r#return(true, 0, TypeCode::FLOAT),
],
positions: vec![Span(0, 4), Span(4, 4)],
constants: vec![ConcreteValue::Float(42.42)],
..Chunk::default()
};
let return_value = Some(Value::float(42.42));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_integer() {
let source = "42";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::Integer,
..FunctionType::default()
},
instructions: vec![
Instruction::load_constant(0, 0, TypeCode::INTEGER, false),
Instruction::r#return(true, 0, TypeCode::INTEGER),
],
positions: vec![Span(0, 2), Span(2, 2)],
constants: vec![ConcreteValue::Integer(42)],
..Chunk::default()
};
let return_value = Some(Value::integer(42));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_string() {
let source = "\"Hello, World!\"";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::String,
..FunctionType::default()
},
instructions: vec![
Instruction::load_constant(0, 0, TypeCode::STRING, false),
Instruction::r#return(true, 0, TypeCode::STRING),
],
positions: vec![Span(0, 15), Span(15, 15)],
constants: vec![ConcreteValue::String(DustString::from("Hello, World!"))],
..Chunk::default()
};
let return_value = Some(Value::string("Hello, World!"));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_boolean_list() {
let source = "[true, false]";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::List(TypeCode::BOOLEAN),
..FunctionType::default()
},
instructions: vec![
Instruction::load_encoded(0, true as u8, TypeCode::BOOLEAN, false),
Instruction::load_encoded(1, false as u8, TypeCode::BOOLEAN, false),
Instruction::load_list(0, TypeCode::BOOLEAN, 0, 1, false),
Instruction::r#return(true, 0, TypeCode::LIST),
],
positions: vec![Span(0, 13), Span(13, 13)],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List(vec![
ConcreteValue::Boolean(true),
ConcreteValue::Boolean(false),
])));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_byte_list() {
let source = "[0x2a, 0x42]";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::List(TypeCode::BYTE),
..FunctionType::default()
},
instructions: vec![
Instruction::load_encoded(0, 0x2a, TypeCode::BYTE, false),
Instruction::load_encoded(1, 0x42, TypeCode::BYTE, false),
Instruction::load_list(0, TypeCode::BYTE, 0, 1, false),
Instruction::r#return(true, 0, TypeCode::LIST),
],
positions: vec![Span(0, 15), Span(15, 15)],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List(vec![
ConcreteValue::Byte(0x2a),
ConcreteValue::Byte(0x42),
])));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_character_list() {
let source = "['a', 'b']";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::List(TypeCode::CHARACTER),
..FunctionType::default()
},
instructions: vec![
Instruction::load_constant(0, 0, TypeCode::CHARACTER, false),
Instruction::load_constant(1, 1, TypeCode::CHARACTER, false),
Instruction::load_list(0, TypeCode::CHARACTER, 0, 1, false),
Instruction::r#return(true, 0, TypeCode::LIST),
],
positions: vec![Span(0, 9), Span(9, 9)],
constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List(vec![
ConcreteValue::Character('a'),
ConcreteValue::Character('b'),
])));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_float_list() {
let source = "[42.42, 24.24]";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::List(TypeCode::FLOAT),
..FunctionType::default()
},
instructions: vec![
Instruction::load_constant(0, 0, TypeCode::FLOAT, false),
Instruction::load_constant(1, 1, TypeCode::FLOAT, false),
Instruction::load_list(0, TypeCode::FLOAT, 0, 1, false),
Instruction::r#return(true, 0, TypeCode::LIST),
],
positions: vec![Span(0, 15), Span(15, 15)],
constants: vec![ConcreteValue::Float(42.42), ConcreteValue::Float(24.24)],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List(vec![
ConcreteValue::Float(42.42),
ConcreteValue::Float(24.24),
])));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_integer_list() {
let source = "[1, 2, 3]";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::List(TypeCode::INTEGER),
..FunctionType::default()
},
instructions: vec![
Instruction::load_constant(0, 0, TypeCode::INTEGER, false),
Instruction::load_constant(1, 1, TypeCode::INTEGER, false),
Instruction::load_constant(2, 2, TypeCode::INTEGER, false),
Instruction::load_list(0, TypeCode::INTEGER, 0, 2, false),
Instruction::r#return(true, 0, TypeCode::LIST),
],
positions: vec![Span(0, 9), Span(9, 9)],
constants: vec![
ConcreteValue::Integer(1),
ConcreteValue::Integer(2),
ConcreteValue::Integer(3),
],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List(vec![
ConcreteValue::Integer(1),
ConcreteValue::Integer(2),
ConcreteValue::Integer(3),
])));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_string_list() {
let source = "[\"Hello\", \"World\"]";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::List(TypeCode::STRING),
..FunctionType::default()
},
instructions: vec![
Instruction::load_constant(0, 0, TypeCode::STRING, false),
Instruction::load_constant(1, 1, TypeCode::STRING, false),
Instruction::load_list(0, TypeCode::STRING, 0, 1, false),
Instruction::r#return(true, 0, TypeCode::LIST),
],
positions: vec![Span(0, 19), Span(19, 19)],
constants: vec![
ConcreteValue::String(DustString::from("Hello")),
ConcreteValue::String(DustString::from("World")),
],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List(vec![
ConcreteValue::String(DustString::from("Hello")),
ConcreteValue::String(DustString::from("World")),
])));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_nested_list() {
let source = "[[1, 2], [3, 4]]";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::List(TypeCode::LIST),
..FunctionType::default()
},
instructions: vec![
Instruction::load_constant(0, 0, TypeCode::INTEGER, false),
Instruction::load_constant(1, 1, TypeCode::INTEGER, false),
Instruction::load_list(0, TypeCode::INTEGER, 0, 1, false),
Instruction::load_constant(2, 2, TypeCode::INTEGER, false),
Instruction::load_constant(3, 3, TypeCode::INTEGER, false),
Instruction::load_list(1, TypeCode::INTEGER, 2, 3, false),
Instruction::load_list(2, TypeCode::LIST, 0, 1, false),
Instruction::r#return(true, 2, TypeCode::LIST),
],
positions: vec![
Span(2, 3),
Span(5, 6),
Span(1, 7),
Span(10, 11),
Span(13, 14),
Span(9, 15),
Span(0, 16),
Span(16, 16),
],
constants: vec![
ConcreteValue::Integer(1),
ConcreteValue::Integer(2),
ConcreteValue::Integer(3),
ConcreteValue::Integer(4),
],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List(vec![
ConcreteValue::List(vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)]),
ConcreteValue::List(vec![ConcreteValue::Integer(3), ConcreteValue::Integer(4)]),
])));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}
#[test]
fn load_deeply_nested_list() {
let source = "[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]";
let chunk = Chunk {
r#type: FunctionType {
return_type: Type::List(TypeCode::LIST),
..FunctionType::default()
},
instructions: vec![
Instruction::load_constant(0, 0, TypeCode::INTEGER, false),
Instruction::load_constant(1, 1, TypeCode::INTEGER, false),
Instruction::load_list(0, TypeCode::INTEGER, 0, 1, false),
Instruction::load_constant(2, 2, TypeCode::INTEGER, false),
Instruction::load_constant(3, 3, TypeCode::INTEGER, false),
Instruction::load_list(1, TypeCode::INTEGER, 2, 3, false),
Instruction::load_list(2, TypeCode::LIST, 0, 1, false),
Instruction::close(0, 1, TypeCode::LIST),
Instruction::load_constant(4, 4, TypeCode::INTEGER, false),
Instruction::load_constant(5, 5, TypeCode::INTEGER, false),
Instruction::load_list(3, TypeCode::INTEGER, 4, 5, false),
Instruction::load_constant(6, 6, TypeCode::INTEGER, false),
Instruction::load_constant(7, 7, TypeCode::INTEGER, false),
Instruction::load_list(4, TypeCode::INTEGER, 6, 7, false),
Instruction::load_list(5, TypeCode::LIST, 3, 4, false),
Instruction::close(3, 4, TypeCode::LIST),
Instruction::load_list(6, TypeCode::LIST, 2, 5, false),
Instruction::r#return(true, 6, TypeCode::LIST),
],
positions: vec![
Span(3, 4),
Span(6, 7),
Span(2, 8),
Span(11, 12),
Span(14, 15),
Span(10, 16),
Span(1, 17),
Span(17, 18),
Span(21, 22),
Span(24, 25),
Span(20, 26),
Span(29, 30),
Span(32, 33),
Span(28, 34),
Span(19, 35),
Span(35, 36),
Span(0, 36),
Span(36, 36),
],
constants: vec![
ConcreteValue::Integer(1),
ConcreteValue::Integer(2),
ConcreteValue::Integer(3),
ConcreteValue::Integer(4),
ConcreteValue::Integer(5),
ConcreteValue::Integer(6),
ConcreteValue::Integer(7),
ConcreteValue::Integer(8),
],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List(vec![
ConcreteValue::List(vec![
ConcreteValue::List(vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)]),
ConcreteValue::List(vec![ConcreteValue::Integer(3), ConcreteValue::Integer(4)]),
]),
ConcreteValue::List(vec![
ConcreteValue::List(vec![ConcreteValue::Integer(5), ConcreteValue::Integer(6)]),
ConcreteValue::List(vec![ConcreteValue::Integer(7), ConcreteValue::Integer(8)]),
]),
])));
assert_eq!(chunk, compile(source).unwrap());
assert_eq!(return_value, run(source).unwrap());
}