Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions rust/src/instructions/math/arithmetic/add_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,23 @@ pub fn add_values(
}
}
}
if matches!(
num_type,
PrimitiveTypes::Hlf | PrimitiveTypes::Flt | PrimitiveTypes::Dbl
) {
for operand in [&a, &b] {
if matches!(
operand,
&Value::Int16(_) | &Value::Int32(_) | &Value::Int64(_) | &Value::Int128(_)
) {
return Err(VMError::TypeMismatch {
ip,
expected: expected_type(num_type, ExpectedCategory::Float),
found: get_type_name(operand.clone()),
});
}
}
}
Ok(match num_type {
PrimitiveTypes::Sht => Value::Int16(add_i16in(a.as_i16(), b.as_i16())),
PrimitiveTypes::Int => Value::Int32(add_i32in(a.as_i32(), b.as_i32())),
Expand Down Expand Up @@ -90,6 +107,27 @@ pub fn add_func(stack: &mut Stack, num_type: PrimitiveTypes, ip: usize) -> Resul
mod tests {
use super::*;
#[test]
fn float_directive_rejects_integer_operands_without_mutating_stack() {
for (a, b, found) in [
(Value::Int32(1), Value::Float32(2.0), "Integer"),
(Value::Float64(1.0), Value::Int64(2), "Long"),
] {
assert!(matches!(
add_values(a.clone(), b.clone(), PrimitiveTypes::Flt, 10),
Err(VMError::TypeMismatch { ip: 10, expected: "Float", found: actual })
if actual == found
));
let mut stack = Stack::from_vec(vec![a, b]);
let original = stack.clone();
assert!(matches!(
add_func(&mut stack, PrimitiveTypes::Flt, 11),
Err(VMError::TypeMismatch { ip: 11, expected: "Float", found: actual })
if actual == found
));
assert_eq!(stack, original);
}
}
#[test]
fn integer_directive_rejects_float_operands_without_mutating_stack() {
for (a, b, found) in [
(Value::Float32(1.0), Value::Int32(2), "Float"),
Expand Down
41 changes: 41 additions & 0 deletions rust/src/instructions/math/arithmetic/div_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,23 @@ pub fn div_values(
}
}
}
if matches!(
num_type,
PrimitiveTypes::Hlf | PrimitiveTypes::Flt | PrimitiveTypes::Dbl
) {
for operand in [&a, &b] {
if matches!(
operand,
&Value::Int16(_) | &Value::Int32(_) | &Value::Int64(_) | &Value::Int128(_)
) {
return Err(VMError::TypeMismatch {
ip,
expected: expected_type(num_type, ExpectedCategory::Float),
found: get_type_name(operand.clone()),
});
}
}
}
Ok(match num_type {
PrimitiveTypes::Sht => Value::Int16(div_i16in(a.as_i16(), b.as_i16())),
PrimitiveTypes::Int => Value::Int32(div_i32in(a.as_i32(), b.as_i32())),
Expand Down Expand Up @@ -93,6 +110,30 @@ pub fn div_func(stack: &mut Stack, num_type: PrimitiveTypes, ip: usize) -> Resul
mod tests {
use super::*;
#[test]
fn float_directive_rejects_integer_operands_without_mutating_stack() {
let a = Value::Float32(4.0);
let b = Value::Int64(2);
assert!(matches!(
div_values(a.clone(), b.clone(), PrimitiveTypes::Flt, 10),
Err(VMError::TypeMismatch {
ip: 10,
expected: "Float",
found: "Long"
})
));
let mut stack = Stack::from_vec(vec![a, b]);
let original = stack.clone();
assert!(matches!(
div_func(&mut stack, PrimitiveTypes::Flt, 11),
Err(VMError::TypeMismatch {
ip: 11,
expected: "Float",
found: "Long"
})
));
assert_eq!(stack, original);
}
#[test]
fn integer_directive_rejects_float_operands_without_mutating_stack() {
for (a, b, found) in [
(Value::Float32(1.0), Value::Int32(2), "Float"),
Expand Down
41 changes: 41 additions & 0 deletions rust/src/instructions/math/arithmetic/mod_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,23 @@ pub fn mod_values(
}
}
}
if matches!(
num_type,
PrimitiveTypes::Hlf | PrimitiveTypes::Flt | PrimitiveTypes::Dbl
) {
for operand in [&a, &b] {
if matches!(
operand,
&Value::Int16(_) | &Value::Int32(_) | &Value::Int64(_) | &Value::Int128(_)
) {
return Err(VMError::TypeMismatch {
ip,
expected: expected_type(num_type, ExpectedCategory::Float),
found: get_type_name(operand.clone()),
});
}
}
}
Ok(match num_type {
PrimitiveTypes::Sht => Value::Int16(mod_i16in(a.as_i16(), b.as_i16())),
PrimitiveTypes::Int => Value::Int32(mod_i32in(a.as_i32(), b.as_i32())),
Expand Down Expand Up @@ -93,6 +110,30 @@ pub fn mod_func(stack: &mut Stack, num_type: PrimitiveTypes, ip: usize) -> Resul
mod tests {
use super::*;
#[test]
fn float_directive_rejects_integer_operands_without_mutating_stack() {
let a = Value::Int32(4);
let b = Value::Float32(2.0);
assert!(matches!(
mod_values(a.clone(), b.clone(), PrimitiveTypes::Flt, 10),
Err(VMError::TypeMismatch {
ip: 10,
expected: "Float",
found: "Integer"
})
));
let mut stack = Stack::from_vec(vec![a, b]);
let original = stack.clone();
assert!(matches!(
mod_func(&mut stack, PrimitiveTypes::Flt, 11),
Err(VMError::TypeMismatch {
ip: 11,
expected: "Float",
found: "Integer"
})
));
assert_eq!(stack, original);
}
#[test]
fn integer_directive_rejects_float_operands_without_mutating_stack() {
for (a, b, found) in [
(Value::Float32(1.0), Value::Int32(2), "Float"),
Expand Down
41 changes: 41 additions & 0 deletions rust/src/instructions/math/arithmetic/mul_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,23 @@ pub fn mul_values(
}
}
}
if matches!(
num_type,
PrimitiveTypes::Hlf | PrimitiveTypes::Flt | PrimitiveTypes::Dbl
) {
for operand in [&a, &b] {
if matches!(
operand,
&Value::Int16(_) | &Value::Int32(_) | &Value::Int64(_) | &Value::Int128(_)
) {
return Err(VMError::TypeMismatch {
ip,
expected: expected_type(num_type, ExpectedCategory::Float),
found: get_type_name(operand.clone()),
});
}
}
}
Ok(match num_type {
PrimitiveTypes::Sht => Value::Int16(mul_i16in(a.as_i16(), b.as_i16())),
PrimitiveTypes::Int => Value::Int32(mul_i32in(a.as_i32(), b.as_i32())),
Expand Down Expand Up @@ -93,6 +110,30 @@ pub fn mul_func(stack: &mut Stack, num_type: PrimitiveTypes, ip: usize) -> Resul
mod tests {
use super::*;
#[test]
fn float_directive_rejects_integer_operands_without_mutating_stack() {
let a = Value::Float64(4.0);
let b = Value::Int64(2);
assert!(matches!(
mul_values(a.clone(), b.clone(), PrimitiveTypes::Dbl, 10),
Err(VMError::TypeMismatch {
ip: 10,
expected: "Double",
found: "Long"
})
));
let mut stack = Stack::from_vec(vec![a, b]);
let original = stack.clone();
assert!(matches!(
mul_func(&mut stack, PrimitiveTypes::Dbl, 11),
Err(VMError::TypeMismatch {
ip: 11,
expected: "Double",
found: "Long"
})
));
assert_eq!(stack, original);
}
#[test]
fn integer_directive_rejects_float_operands_without_mutating_stack() {
for (a, b, found) in [
(Value::Float32(1.0), Value::Int32(2), "Float"),
Expand Down
36 changes: 36 additions & 0 deletions rust/src/instructions/math/arithmetic/neg_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,19 @@ pub fn neg_values(a: Value, num_type: PrimitiveTypes, ip: usize) -> Result<Value
found: get_type_name(a.clone()),
});
}
if matches!(
num_type,
PrimitiveTypes::Hlf | PrimitiveTypes::Flt | PrimitiveTypes::Dbl
) && matches!(
&a,
&Value::Int16(_) | &Value::Int32(_) | &Value::Int64(_) | &Value::Int128(_)
) {
return Err(VMError::TypeMismatch {
ip,
expected: expected_type(num_type, ExpectedCategory::Float),
found: get_type_name(a.clone()),
});
}
Ok(match num_type {
PrimitiveTypes::Sht => Value::Int16(neg_i16in(a.as_i16())),
PrimitiveTypes::Int => Value::Int32(neg_i32in(a.as_i32())),
Expand Down Expand Up @@ -71,6 +84,29 @@ pub fn neg_func(stack: &mut Stack, num_type: PrimitiveTypes, ip: usize) -> Resul
mod tests {
use super::*;
#[test]
fn float_directive_rejects_integer_operand_without_mutating_stack() {
let operand = Value::Int64(1);
assert!(matches!(
neg_values(operand.clone(), PrimitiveTypes::Dbl, 10),
Err(VMError::TypeMismatch {
ip: 10,
expected: "Double",
found: "Long"
})
));
let mut stack = Stack::from_vec(vec![operand]);
let original = stack.clone();
assert!(matches!(
neg_func(&mut stack, PrimitiveTypes::Dbl, 11),
Err(VMError::TypeMismatch {
ip: 11,
expected: "Double",
found: "Long"
})
));
assert_eq!(stack, original);
}
#[test]
fn integer_directive_rejects_float_operand_without_mutating_stack() {
let operand = Value::Float32(1.0);
assert!(matches!(
Expand Down
41 changes: 41 additions & 0 deletions rust/src/instructions/math/arithmetic/sub_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,23 @@ pub fn sub_values(
}
}
}
if matches!(
num_type,
PrimitiveTypes::Hlf | PrimitiveTypes::Flt | PrimitiveTypes::Dbl
) {
for operand in [&a, &b] {
if matches!(
operand,
&Value::Int16(_) | &Value::Int32(_) | &Value::Int64(_) | &Value::Int128(_)
) {
return Err(VMError::TypeMismatch {
ip,
expected: expected_type(num_type, ExpectedCategory::Float),
found: get_type_name(operand.clone()),
});
}
}
}
Ok(match num_type {
PrimitiveTypes::Sht => Value::Int16(sub_i16in(a.as_i16(), b.as_i16())),
PrimitiveTypes::Int => Value::Int32(sub_i32in(a.as_i32(), b.as_i32())),
Expand Down Expand Up @@ -93,6 +110,30 @@ pub fn sub_func(stack: &mut Stack, num_type: PrimitiveTypes, ip: usize) -> Resul
mod tests {
use super::*;
#[test]
fn float_directive_rejects_integer_operands_without_mutating_stack() {
let a = Value::Int32(4);
let b = Value::Float32(2.0);
assert!(matches!(
sub_values(a.clone(), b.clone(), PrimitiveTypes::Flt, 10),
Err(VMError::TypeMismatch {
ip: 10,
expected: "Float",
found: "Integer"
})
));
let mut stack = Stack::from_vec(vec![a, b]);
let original = stack.clone();
assert!(matches!(
sub_func(&mut stack, PrimitiveTypes::Flt, 11),
Err(VMError::TypeMismatch {
ip: 11,
expected: "Float",
found: "Integer"
})
));
assert_eq!(stack, original);
}
#[test]
fn integer_directive_rejects_float_operands_without_mutating_stack() {
for (a, b, found) in [
(Value::Float32(1.0), Value::Int32(2), "Float"),
Expand Down
33 changes: 30 additions & 3 deletions rust/src/instructions/math/root/cbrt_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ use crate::types::value::Value;
use crate::utils::{expected_type::expected_type, get_type_name::get_type_name};
#[inline(always)]
pub fn cbrt_values(a: Value, num_type: PrimitiveTypes, ip: usize) -> Result<Value, VMError> {
if !a.is_number() {
if !matches!(
&a,
Value::Float16(_) | Value::Float32(_) | Value::Float64(_)
) {
return Err(VMError::TypeMismatch {
ip,
expected: expected_type(num_type, ExpectedCategory::Float),
found: get_type_name(a),
found: get_type_name(a.clone()),
});
}
Ok(match num_type {
Expand All @@ -34,7 +37,7 @@ pub fn cbrt_values(a: Value, num_type: PrimitiveTypes, ip: usize) -> Result<Valu
return Err(VMError::TypeMismatch {
ip,
expected: expected_type(num_type, ExpectedCategory::Float),
found: a.type_of(),
found: "unknown",
});
}
})
Expand All @@ -51,6 +54,30 @@ pub fn cbrt_func(stack: &mut Stack, num_type: PrimitiveTypes, ip: usize) -> Resu
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rejects_integer_operands_without_mutating_stack() {
let value = Value::Int64(1);
assert!(matches!(
cbrt_values(value.clone(), PrimitiveTypes::Dbl, 21),
Err(VMError::TypeMismatch {
ip: 21,
expected: "Double",
found: "Long"
})
));
let mut stack = Stack::from_vec(vec![value]);
let original = stack.clone();
assert!(matches!(
cbrt_func(&mut stack, PrimitiveTypes::Dbl, 22),
Err(VMError::TypeMismatch {
ip: 22,
expected: "Double",
found: "Long"
})
));
assert_eq!(stack, original);
}
#[test]
fn reports_errors_without_mutating_stack() {
crate::instructions::math::assert_unary_float_errors(super::cbrt_func, "CBRT");
Expand Down
Loading
Loading