Add new "add" tests; Allow adding strings to characters and visa versa
This commit is contained in:
parent
31a41581eb
commit
544edaf5f4
@ -629,20 +629,16 @@ impl<'src> Compiler<'src> {
|
|||||||
};
|
};
|
||||||
let operator = self.current_token;
|
let operator = self.current_token;
|
||||||
let operator_position = self.current_position;
|
let operator_position = self.current_position;
|
||||||
|
|
||||||
Compiler::expect_addable_type(&left_type, &left_position)?;
|
|
||||||
|
|
||||||
let rule = ParseRule::from(&operator);
|
let rule = ParseRule::from(&operator);
|
||||||
let is_assignment = matches!(
|
let is_assignment = matches!(
|
||||||
operator,
|
operator,
|
||||||
Token::PlusEqual | Token::MinusEqual | Token::StarEqual | Token::SlashEqual
|
Token::PlusEqual | Token::MinusEqual | Token::StarEqual | Token::SlashEqual
|
||||||
);
|
);
|
||||||
|
|
||||||
let r#type = if is_assignment {
|
if push_back_left {
|
||||||
Type::None
|
self.instructions
|
||||||
} else {
|
.push((left_instruction, left_type.clone(), left_position));
|
||||||
left_type.clone()
|
}
|
||||||
};
|
|
||||||
|
|
||||||
if is_assignment && !left_is_mutable_local {
|
if is_assignment && !left_is_mutable_local {
|
||||||
return Err(CompileError::ExpectedMutableVariable {
|
return Err(CompileError::ExpectedMutableVariable {
|
||||||
@ -651,10 +647,15 @@ impl<'src> Compiler<'src> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if push_back_left {
|
Compiler::expect_addable_type(&left_type, &left_position)?;
|
||||||
self.instructions
|
|
||||||
.push((left_instruction, left_type.clone(), left_position));
|
let r#type = if is_assignment {
|
||||||
}
|
Type::None
|
||||||
|
} else if left_type == Type::Character {
|
||||||
|
Type::String
|
||||||
|
} else {
|
||||||
|
left_type.clone()
|
||||||
|
};
|
||||||
|
|
||||||
self.advance()?;
|
self.advance()?;
|
||||||
self.parse_sub_expression(&rule.precedence)?;
|
self.parse_sub_expression(&rule.precedence)?;
|
||||||
@ -1628,9 +1629,11 @@ impl<'src> Compiler<'src> {
|
|||||||
) -> Result<(), CompileError> {
|
) -> Result<(), CompileError> {
|
||||||
if matches!(
|
if matches!(
|
||||||
(left, right),
|
(left, right),
|
||||||
(Type::Character, Type::Character)
|
(Type::Character, Type::String)
|
||||||
|
| (Type::Character, Type::Character)
|
||||||
| (Type::Float, Type::Float)
|
| (Type::Float, Type::Float)
|
||||||
| (Type::Integer, Type::Integer)
|
| (Type::Integer, Type::Integer)
|
||||||
|
| (Type::String, Type::Character)
|
||||||
| (Type::String, Type::String),
|
| (Type::String, Type::String),
|
||||||
) {
|
) {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -70,9 +70,11 @@ impl ConcreteValue {
|
|||||||
(Character(left), Character(right)) => {
|
(Character(left), Character(right)) => {
|
||||||
ConcreteValue::string(format!("{}{}", left, right))
|
ConcreteValue::string(format!("{}{}", left, right))
|
||||||
}
|
}
|
||||||
|
(Character(left), String(right)) => ConcreteValue::string(format!("{}{}", left, right)),
|
||||||
(Float(left), Float(right)) => ConcreteValue::Float(*left + *right),
|
(Float(left), Float(right)) => ConcreteValue::Float(*left + *right),
|
||||||
(Integer(left), Integer(right)) => ConcreteValue::Integer(left.saturating_add(*right)),
|
(Integer(left), Integer(right)) => ConcreteValue::Integer(left.saturating_add(*right)),
|
||||||
(String(left), String(right)) => ConcreteValue::string(format!("{}{}", left, right)),
|
(String(left), String(right)) => ConcreteValue::string(format!("{}{}", left, right)),
|
||||||
|
(String(left), Character(right)) => ConcreteValue::string(format!("{}{}", left, right)),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ValueError::CannotAdd(
|
return Err(ValueError::CannotAdd(
|
||||||
self.clone().to_value(),
|
self.clone().to_value(),
|
||||||
|
@ -32,6 +32,41 @@ fn add_characters() {
|
|||||||
assert_eq!(run(source), Ok(Some(ConcreteValue::string("ab"))));
|
assert_eq!(run(source), Ok(Some(ConcreteValue::string("ab"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_character_and_string() {
|
||||||
|
let source = "'a' + \"b\"";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
compile(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::String),
|
||||||
|
},
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
Instruction::add(
|
||||||
|
Destination::Register(0),
|
||||||
|
Argument::Constant(0),
|
||||||
|
Argument::Constant(1)
|
||||||
|
),
|
||||||
|
Span(4, 5)
|
||||||
|
),
|
||||||
|
(Instruction::r#return(true), Span(9, 9))
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
ConcreteValue::Character('a'),
|
||||||
|
ConcreteValue::String("b".to_string())
|
||||||
|
],
|
||||||
|
vec![]
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(ConcreteValue::string("ab"))));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_floats() {
|
fn add_floats() {
|
||||||
let source = "1.0 + 2.0";
|
let source = "1.0 + 2.0";
|
||||||
@ -128,3 +163,41 @@ fn add_strings() {
|
|||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_string_and_character() {
|
||||||
|
let source = "\"a\" + 'b'";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
compile(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::String),
|
||||||
|
},
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
Instruction::add(
|
||||||
|
Destination::Register(0),
|
||||||
|
Argument::Constant(0),
|
||||||
|
Argument::Constant(1)
|
||||||
|
),
|
||||||
|
Span(4, 5)
|
||||||
|
),
|
||||||
|
(Instruction::r#return(true), Span(9, 9))
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
ConcreteValue::String("a".to_string()),
|
||||||
|
ConcreteValue::Character('b')
|
||||||
|
],
|
||||||
|
vec![]
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
run(source),
|
||||||
|
Ok(Some(ConcreteValue::String("ab".to_string())))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user