Add new tests
This commit is contained in:
parent
dc2acbfe46
commit
dcea611a0b
@ -42,3 +42,7 @@ harness = false
|
||||
[[test]]
|
||||
name = "add"
|
||||
path = "tests/math/add.rs"
|
||||
|
||||
[[test]]
|
||||
name = "subtract"
|
||||
path = "tests/math/subtract.rs"
|
||||
|
@ -924,8 +924,9 @@ impl<'src> Compiler<'src> {
|
||||
});
|
||||
}
|
||||
};
|
||||
let position = Span(left_position.0, right_position.1);
|
||||
|
||||
self.emit_instruction(instruction, r#type, operator_position);
|
||||
self.emit_instruction(instruction, r#type, position);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -441,6 +441,30 @@ pub fn add(instruction: InstructionFields, thread: &mut Thread) {
|
||||
|
||||
thread.set_byte_register(destination, register);
|
||||
}
|
||||
(TypeCode::FLOAT, TypeCode::FLOAT) => {
|
||||
let left_value = if left_is_constant {
|
||||
if cfg!(debug_assertions) {
|
||||
thread.get_constant(left).as_float().unwrap()
|
||||
} else {
|
||||
unsafe { thread.get_constant(left).as_float().unwrap_unchecked() }
|
||||
}
|
||||
} else {
|
||||
thread.get_float_register(left)
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
if cfg!(debug_assertions) {
|
||||
thread.get_constant(right).as_float().unwrap()
|
||||
} else {
|
||||
unsafe { thread.get_constant(right).as_float().unwrap_unchecked() }
|
||||
}
|
||||
} else {
|
||||
thread.get_float_register(right)
|
||||
};
|
||||
let sum = left_value + right_value;
|
||||
let register = Register::Value(sum);
|
||||
|
||||
thread.set_float_register(destination, register);
|
||||
}
|
||||
(TypeCode::STRING, TypeCode::STRING) => {
|
||||
let left_value = if left_is_constant {
|
||||
if cfg!(debug_assertions) {
|
||||
@ -505,29 +529,65 @@ pub fn add(instruction: InstructionFields, thread: &mut Thread) {
|
||||
|
||||
thread.set_string_register(destination, register);
|
||||
}
|
||||
(TypeCode::FLOAT, TypeCode::FLOAT) => {
|
||||
(TypeCode::STRING, TypeCode::CHARACTER) => {
|
||||
let left_value = if left_is_constant {
|
||||
if cfg!(debug_assertions) {
|
||||
thread.get_constant(left).as_float().unwrap()
|
||||
thread.get_constant(left).as_string().unwrap().clone()
|
||||
} else {
|
||||
unsafe { thread.get_constant(left).as_float().unwrap_unchecked() }
|
||||
unsafe {
|
||||
thread
|
||||
.get_constant(left)
|
||||
.as_string()
|
||||
.unwrap_unchecked()
|
||||
.clone()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
thread.get_float_register(left)
|
||||
thread.get_string_register(left).clone()
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
if cfg!(debug_assertions) {
|
||||
thread.get_constant(right).as_float().unwrap()
|
||||
thread.get_constant(right).as_character().unwrap()
|
||||
} else {
|
||||
unsafe { thread.get_constant(right).as_float().unwrap_unchecked() }
|
||||
unsafe { thread.get_constant(right).as_character().unwrap_unchecked() }
|
||||
}
|
||||
} else {
|
||||
thread.get_float_register(right)
|
||||
thread.get_character_register(right)
|
||||
};
|
||||
let sum = left_value + right_value;
|
||||
let mut sum = left_value.clone();
|
||||
|
||||
sum.push(*right_value);
|
||||
|
||||
let register = Register::Value(sum);
|
||||
|
||||
thread.set_float_register(destination, register);
|
||||
thread.set_string_register(destination, register);
|
||||
}
|
||||
(TypeCode::CHARACTER, TypeCode::STRING) => {
|
||||
let left_value = if left_is_constant {
|
||||
if cfg!(debug_assertions) {
|
||||
thread.get_constant(left).as_character().unwrap()
|
||||
} else {
|
||||
unsafe { thread.get_constant(left).as_character().unwrap_unchecked() }
|
||||
}
|
||||
} else {
|
||||
thread.get_character_register(left)
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
if cfg!(debug_assertions) {
|
||||
thread.get_constant(right).as_string().unwrap()
|
||||
} else {
|
||||
unsafe { thread.get_constant(right).as_string().unwrap_unchecked() }
|
||||
}
|
||||
} else {
|
||||
thread.get_string_register(right)
|
||||
};
|
||||
let mut sum = right_value.clone();
|
||||
|
||||
sum.insert(0, *left_value);
|
||||
|
||||
let register = Register::Value(sum);
|
||||
|
||||
thread.set_string_register(destination, register);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ fn add_bytes() {
|
||||
),
|
||||
Instruction::r#return(true, 2, TypeCode::BYTE),
|
||||
],
|
||||
positions: vec![Span(0, 4), Span(7, 11), Span(5, 6), Span(11, 11)],
|
||||
positions: vec![Span(0, 4), Span(7, 11), Span(0, 11), Span(11, 11)],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::byte(0x2A));
|
||||
@ -57,11 +57,11 @@ fn add_many_bytes() {
|
||||
positions: vec![
|
||||
Span(0, 4),
|
||||
Span(7, 11),
|
||||
Span(5, 6),
|
||||
Span(0, 11),
|
||||
Span(14, 18),
|
||||
Span(12, 13),
|
||||
Span(0, 18),
|
||||
Span(21, 25),
|
||||
Span(19, 20),
|
||||
Span(0, 25),
|
||||
Span(25, 25),
|
||||
],
|
||||
..Chunk::default()
|
||||
@ -85,7 +85,7 @@ fn add_characters() {
|
||||
),
|
||||
Instruction::r#return(true, 0, TypeCode::STRING),
|
||||
],
|
||||
positions: vec![Span(4, 5), Span(9, 9)],
|
||||
positions: vec![Span(0, 9), Span(9, 9)],
|
||||
constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')],
|
||||
..Chunk::default()
|
||||
};
|
||||
@ -95,6 +95,44 @@ fn add_characters() {
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_many_characters() {
|
||||
let source = "'a' + 'b' + 'c' + 'd'";
|
||||
let chunk = Chunk {
|
||||
r#type: FunctionType::new([], [], Type::String),
|
||||
instructions: vec![
|
||||
Instruction::add(
|
||||
0,
|
||||
Operand::Constant(0, TypeCode::CHARACTER),
|
||||
Operand::Constant(1, TypeCode::CHARACTER),
|
||||
),
|
||||
Instruction::add(
|
||||
1,
|
||||
Operand::Register(0, TypeCode::STRING),
|
||||
Operand::Constant(2, TypeCode::CHARACTER),
|
||||
),
|
||||
Instruction::add(
|
||||
2,
|
||||
Operand::Register(1, TypeCode::STRING),
|
||||
Operand::Constant(3, TypeCode::CHARACTER),
|
||||
),
|
||||
Instruction::r#return(true, 2, TypeCode::STRING),
|
||||
],
|
||||
positions: vec![Span(0, 9), Span(0, 15), Span(0, 21), Span(21, 21)],
|
||||
constants: vec![
|
||||
ConcreteValue::Character('a'),
|
||||
ConcreteValue::Character('b'),
|
||||
ConcreteValue::Character('c'),
|
||||
ConcreteValue::Character('d'),
|
||||
],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::string("abcd"));
|
||||
|
||||
assert_eq!(chunk, compile(source).unwrap());
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_floats() {
|
||||
let source = "2.40 + 40.02";
|
||||
@ -108,7 +146,7 @@ fn add_floats() {
|
||||
),
|
||||
Instruction::r#return(true, 0, TypeCode::FLOAT),
|
||||
],
|
||||
positions: vec![Span(5, 6), Span(12, 12)],
|
||||
positions: vec![Span(0, 12), Span(12, 12)],
|
||||
constants: vec![ConcreteValue::Float(2.40), ConcreteValue::Float(40.02)],
|
||||
..Chunk::default()
|
||||
};
|
||||
@ -118,6 +156,39 @@ fn add_floats() {
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_many_floats() {
|
||||
let source = "2.40 + 40.02 + 2.40 + 40.02";
|
||||
let chunk = Chunk {
|
||||
r#type: FunctionType::new([], [], Type::Float),
|
||||
instructions: vec![
|
||||
Instruction::add(
|
||||
0,
|
||||
Operand::Constant(0, TypeCode::FLOAT),
|
||||
Operand::Constant(1, TypeCode::FLOAT),
|
||||
),
|
||||
Instruction::add(
|
||||
1,
|
||||
Operand::Register(0, TypeCode::FLOAT),
|
||||
Operand::Constant(0, TypeCode::FLOAT),
|
||||
),
|
||||
Instruction::add(
|
||||
2,
|
||||
Operand::Register(1, TypeCode::FLOAT),
|
||||
Operand::Constant(1, TypeCode::FLOAT),
|
||||
),
|
||||
Instruction::r#return(true, 2, TypeCode::FLOAT),
|
||||
],
|
||||
positions: vec![Span(0, 12), Span(0, 19), Span(0, 27), Span(27, 27)],
|
||||
constants: vec![ConcreteValue::Float(2.40), ConcreteValue::Float(40.02)],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::float(84.84));
|
||||
|
||||
assert_eq!(chunk, compile(source).unwrap());
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_integers() {
|
||||
let source = "40 + 2";
|
||||
@ -131,7 +202,7 @@ fn add_integers() {
|
||||
),
|
||||
Instruction::r#return(true, 0, TypeCode::INTEGER),
|
||||
],
|
||||
positions: vec![Span(3, 4), Span(6, 6)],
|
||||
positions: vec![Span(0, 6), Span(6, 6)],
|
||||
constants: vec![ConcreteValue::Integer(40), ConcreteValue::Integer(2)],
|
||||
..Chunk::default()
|
||||
};
|
||||
@ -141,6 +212,39 @@ fn add_integers() {
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_many_integers() {
|
||||
let source = "40 + 2 + 40 + 2";
|
||||
let chunk = Chunk {
|
||||
r#type: FunctionType::new([], [], Type::Integer),
|
||||
instructions: vec![
|
||||
Instruction::add(
|
||||
0,
|
||||
Operand::Constant(0, TypeCode::INTEGER),
|
||||
Operand::Constant(1, TypeCode::INTEGER),
|
||||
),
|
||||
Instruction::add(
|
||||
1,
|
||||
Operand::Register(0, TypeCode::INTEGER),
|
||||
Operand::Constant(0, TypeCode::INTEGER),
|
||||
),
|
||||
Instruction::add(
|
||||
2,
|
||||
Operand::Register(1, TypeCode::INTEGER),
|
||||
Operand::Constant(1, TypeCode::INTEGER),
|
||||
),
|
||||
Instruction::r#return(true, 2, TypeCode::INTEGER),
|
||||
],
|
||||
positions: vec![Span(0, 6), Span(0, 11), Span(0, 15), Span(15, 15)],
|
||||
constants: vec![ConcreteValue::Integer(40), ConcreteValue::Integer(2)],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::integer(84));
|
||||
|
||||
assert_eq!(chunk, compile(source).unwrap());
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_strings() {
|
||||
let source = "\"Hello, \" + \"World!\"";
|
||||
@ -154,7 +258,7 @@ fn add_strings() {
|
||||
),
|
||||
Instruction::r#return(true, 0, TypeCode::STRING),
|
||||
],
|
||||
positions: vec![Span(10, 11), Span(20, 20)],
|
||||
positions: vec![Span(0, 20), Span(20, 20)],
|
||||
constants: vec![
|
||||
ConcreteValue::String(DustString::from("Hello, ")),
|
||||
ConcreteValue::String(DustString::from("World!")),
|
||||
@ -166,3 +270,41 @@ fn add_strings() {
|
||||
assert_eq!(chunk, compile(source).unwrap());
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_many_strings() {
|
||||
let source = "\"foo\" + \"bar\" + \"baz\" + \"buzz\"";
|
||||
let chunk = Chunk {
|
||||
r#type: FunctionType::new([], [], Type::String),
|
||||
instructions: vec![
|
||||
Instruction::add(
|
||||
0,
|
||||
Operand::Constant(0, TypeCode::STRING),
|
||||
Operand::Constant(1, TypeCode::STRING),
|
||||
),
|
||||
Instruction::add(
|
||||
1,
|
||||
Operand::Register(0, TypeCode::STRING),
|
||||
Operand::Constant(2, TypeCode::STRING),
|
||||
),
|
||||
Instruction::add(
|
||||
2,
|
||||
Operand::Register(1, TypeCode::STRING),
|
||||
Operand::Constant(3, TypeCode::STRING),
|
||||
),
|
||||
Instruction::r#return(true, 2, TypeCode::STRING),
|
||||
],
|
||||
positions: vec![Span(0, 13), Span(0, 21), Span(0, 30), Span(30, 30)],
|
||||
constants: vec![
|
||||
ConcreteValue::String(DustString::from("foo")),
|
||||
ConcreteValue::String(DustString::from("bar")),
|
||||
ConcreteValue::String(DustString::from("baz")),
|
||||
ConcreteValue::String(DustString::from("buzz")),
|
||||
],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::string("foobarbazbuzz"));
|
||||
|
||||
assert_eq!(chunk, compile(source).unwrap());
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
||||
|
0
dust-lang/tests/math/subtract.rs
Normal file
0
dust-lang/tests/math/subtract.rs
Normal file
Loading…
x
Reference in New Issue
Block a user