Add and pass new tests
This commit is contained in:
parent
1d0824165d
commit
3d48558b94
@ -38,7 +38,3 @@ harness = false
|
||||
[[bench]]
|
||||
name = "threads"
|
||||
harness = false
|
||||
|
||||
[[test]]
|
||||
name = "load_values"
|
||||
path = "tests/values/load_values.rs"
|
||||
|
@ -842,20 +842,6 @@ impl<'src> Compiler<'src> {
|
||||
|
||||
check_math_type(&left_type, operator, &left_position)?;
|
||||
|
||||
let destination = if is_assignment {
|
||||
left.index()
|
||||
} else {
|
||||
match left_type {
|
||||
Type::Boolean => self.next_boolean_register(),
|
||||
Type::Byte => self.next_byte_register(),
|
||||
Type::Character => self.next_character_register(),
|
||||
Type::Float => self.next_float_register(),
|
||||
Type::Integer => self.next_integer_register(),
|
||||
Type::String => self.next_string_register(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
};
|
||||
|
||||
if is_assignment && !left_is_mutable_local {
|
||||
return Err(CompileError::ExpectedMutableVariable {
|
||||
found: self.previous_token.to_owned(),
|
||||
@ -890,6 +876,19 @@ impl<'src> Compiler<'src> {
|
||||
} else {
|
||||
left_type.clone()
|
||||
};
|
||||
let destination = if is_assignment {
|
||||
left.index()
|
||||
} else {
|
||||
match left_type {
|
||||
Type::Boolean => self.next_boolean_register(),
|
||||
Type::Byte => self.next_byte_register(),
|
||||
Type::Character => self.next_character_register(),
|
||||
Type::Float => self.next_float_register(),
|
||||
Type::Integer => self.next_integer_register(),
|
||||
Type::String => self.next_string_register(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
};
|
||||
let instruction = match operator {
|
||||
Token::Plus | Token::PlusEqual => Instruction::add(destination, left, right),
|
||||
Token::Minus | Token::MinusEqual => Instruction::subtract(destination, left, right),
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
AbstractList, ConcreteValue, Instruction, Value,
|
||||
AbstractList, ConcreteValue, DustString, Instruction, Value,
|
||||
instruction::{InstructionFields, TypeCode},
|
||||
};
|
||||
|
||||
@ -372,6 +372,58 @@ pub fn add(instruction: InstructionFields, thread: &mut Thread) {
|
||||
|
||||
thread.set_string_register(destination, register);
|
||||
}
|
||||
(TypeCode::CHARACTER, TypeCode::CHARACTER) => {
|
||||
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_character().unwrap()
|
||||
} else {
|
||||
unsafe { thread.get_constant(right).as_character().unwrap_unchecked() }
|
||||
}
|
||||
} else {
|
||||
thread.get_character_register(right)
|
||||
};
|
||||
let mut sum = DustString::new();
|
||||
|
||||
sum.push(*left_value);
|
||||
sum.push(*right_value);
|
||||
|
||||
let register = Register::Value(sum);
|
||||
|
||||
thread.set_string_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);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
138
dust-lang/tests/add.rs
Normal file
138
dust-lang/tests/add.rs
Normal file
@ -0,0 +1,138 @@
|
||||
use dust_lang::{
|
||||
Chunk, ConcreteValue, DustString, FunctionType, Instruction, Operand, Span, Type, Value,
|
||||
compile, instruction::TypeCode, run,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn add_bytes() {
|
||||
let source = "0x28 + 0x02";
|
||||
let chunk = Chunk {
|
||||
r#type: FunctionType {
|
||||
return_type: Type::Byte,
|
||||
..FunctionType::default()
|
||||
},
|
||||
instructions: vec![
|
||||
Instruction::load_encoded(0, 40, TypeCode::BYTE, false),
|
||||
Instruction::load_encoded(1, 2, TypeCode::BYTE, false),
|
||||
Instruction::add(
|
||||
2,
|
||||
Operand::Register(0, TypeCode::BYTE),
|
||||
Operand::Register(1, TypeCode::BYTE),
|
||||
),
|
||||
Instruction::r#return(true, 2, TypeCode::BYTE),
|
||||
],
|
||||
positions: vec![Span(0, 4), Span(7, 11), Span(5, 6), Span(11, 11)],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::byte(0x2A));
|
||||
|
||||
assert_eq!(chunk, compile(source).unwrap());
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_characters() {
|
||||
let source = "'a' + 'b'";
|
||||
let chunk = Chunk {
|
||||
r#type: FunctionType {
|
||||
return_type: Type::String,
|
||||
..FunctionType::default()
|
||||
},
|
||||
instructions: vec![
|
||||
Instruction::add(
|
||||
0,
|
||||
Operand::Constant(0, TypeCode::CHARACTER),
|
||||
Operand::Constant(1, TypeCode::CHARACTER),
|
||||
),
|
||||
Instruction::r#return(true, 0, TypeCode::STRING),
|
||||
],
|
||||
positions: vec![Span(4, 5), Span(9, 9)],
|
||||
constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::string("ab"));
|
||||
|
||||
assert_eq!(chunk, compile(source).unwrap());
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_floats() {
|
||||
let source = "2.40 + 40.02";
|
||||
let chunk = Chunk {
|
||||
r#type: FunctionType {
|
||||
return_type: Type::Float,
|
||||
..FunctionType::default()
|
||||
},
|
||||
instructions: vec![
|
||||
Instruction::add(
|
||||
0,
|
||||
Operand::Constant(0, TypeCode::FLOAT),
|
||||
Operand::Constant(1, TypeCode::FLOAT),
|
||||
),
|
||||
Instruction::r#return(true, 0, TypeCode::FLOAT),
|
||||
],
|
||||
positions: vec![Span(0, 4), Span(7, 11), Span(5, 6), Span(11, 11)],
|
||||
constants: vec![ConcreteValue::Float(2.40), ConcreteValue::Float(40.02)],
|
||||
..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 add_integers() {
|
||||
let source = "40 + 2";
|
||||
let chunk = Chunk {
|
||||
r#type: FunctionType {
|
||||
return_type: Type::Integer,
|
||||
..FunctionType::default()
|
||||
},
|
||||
instructions: vec![
|
||||
Instruction::add(
|
||||
0,
|
||||
Operand::Constant(0, TypeCode::INTEGER),
|
||||
Operand::Constant(1, TypeCode::INTEGER),
|
||||
),
|
||||
Instruction::r#return(true, 0, TypeCode::INTEGER),
|
||||
],
|
||||
positions: vec![Span(3, 4), Span(7, 7)],
|
||||
constants: vec![ConcreteValue::Integer(40), ConcreteValue::Integer(2)],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::integer(42));
|
||||
|
||||
assert_eq!(chunk, compile(source).unwrap());
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_strings() {
|
||||
let source = "\"Hello, \" + \"World!\"";
|
||||
let chunk = Chunk {
|
||||
r#type: FunctionType {
|
||||
return_type: Type::String,
|
||||
..FunctionType::default()
|
||||
},
|
||||
instructions: vec![
|
||||
Instruction::add(
|
||||
0,
|
||||
Operand::Constant(0, TypeCode::STRING),
|
||||
Operand::Constant(1, TypeCode::STRING),
|
||||
),
|
||||
Instruction::r#return(true, 0, TypeCode::STRING),
|
||||
],
|
||||
positions: vec![Span(0, 8), Span(11, 18), Span(9, 10), Span(19, 25)],
|
||||
constants: vec![
|
||||
ConcreteValue::String(DustString::from("Hello, ")),
|
||||
ConcreteValue::String(DustString::from("World!")),
|
||||
],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::string("Hello, World!"));
|
||||
|
||||
assert_eq!(chunk, compile(source).unwrap());
|
||||
assert_eq!(return_value, run(source).unwrap());
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user