diff --git a/rust/src/instructions/math/vector/arithmetic/addv_func.rs b/rust/src/instructions/math/vector/arithmetic/addv_func.rs index 0d3298ac..a83c7142 100644 --- a/rust/src/instructions/math/vector/arithmetic/addv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/addv_func.rs @@ -50,6 +50,19 @@ pub fn addv_values( found: get_type_name(value.clone()), }); } + if matches!( + num_type, + PrimitiveTypes::Sht | PrimitiveTypes::Int | PrimitiveTypes::Lng | PrimitiveTypes::Oct + ) && matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { + return Err(VMError::TypeMismatch { + ip, + expected: expected_type(num_type, ExpectedCategory::Integer), + found: get_type_name(value.clone()), + }); + } } Ok(match num_type { PrimitiveTypes::Sht => Value::Array(addv_i16in(&arr_a, &arr_b)), @@ -63,7 +76,7 @@ pub fn addv_values( return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::All), - found: num_type.directive(), + found: "unknown", }); } }) @@ -91,6 +104,23 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn rejects_float_elements_for_integer_directives() { + let left = array(vec![Value::Float32(1.0)]); + let right = array(vec![Value::Int32(2)]); + assert!(matches!( + addv_values(left.clone(), right.clone(), PrimitiveTypes::Int, 24), + Err(VMError::TypeMismatch { + ip: 24, + expected: "Integer", + found: "Float" + }) + )); + let mut stack = Stack::from_vec(vec![left, right]); + let original = stack.clone(); + assert!(addv_func(&mut stack, PrimitiveTypes::Int, 25).is_err()); + assert_eq!(stack, original); + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false), array(vec![Value::Int32(1)])]); let original = stack.clone(); diff --git a/rust/src/instructions/math/vector/arithmetic/cosv_func.rs b/rust/src/instructions/math/vector/arithmetic/cosv_func.rs index c8bb3355..c5a2b8d9 100644 --- a/rust/src/instructions/math/vector/arithmetic/cosv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/cosv_func.rs @@ -25,7 +25,10 @@ pub fn cosv_values(a_val: Value, num_type: PrimitiveTypes, ip: usize) -> Result< found: get_type_name(a_val.clone()), })?; for value in arr_a.iter() { - if !value.is_number() { + if !matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::Float), @@ -41,7 +44,7 @@ pub fn cosv_values(a_val: Value, num_type: PrimitiveTypes, ip: usize) -> Result< return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::Float), - found: expected_type(num_type, ExpectedCategory::All), + found: "unknown", }); } }) @@ -64,6 +67,29 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn requires_float_elements_and_accepts_cross_width_values() { + assert!( + cosv_values( + array(vec![Value::Float16(half::f16::ZERO)]), + PrimitiveTypes::Dbl, + 24 + ) + .is_ok() + ); + for invalid in [Value::Int64(1), Value::Bool(false)] { + let value = array(vec![invalid.clone()]); + assert!(matches!( + cosv_values(value.clone(), PrimitiveTypes::Flt, 25), + Err(VMError::TypeMismatch { ip: 25, expected: "Float", found: actual }) + if actual == get_type_name(invalid.clone()) + )); + let mut stack = Stack::from_vec(vec![value]); + let original = stack.clone(); + assert!(cosv_func(&mut stack, PrimitiveTypes::Flt, 26).is_err()); + assert_eq!(stack, original); + } + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false)]); let original = stack.clone(); diff --git a/rust/src/instructions/math/vector/arithmetic/divv_func.rs b/rust/src/instructions/math/vector/arithmetic/divv_func.rs index 247a2b03..6dcc925b 100644 --- a/rust/src/instructions/math/vector/arithmetic/divv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/divv_func.rs @@ -48,6 +48,19 @@ pub fn divv_values( found: get_type_name(value.clone()), }); } + if matches!( + num_type, + PrimitiveTypes::Sht | PrimitiveTypes::Int | PrimitiveTypes::Lng | PrimitiveTypes::Oct + ) && matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { + return Err(VMError::TypeMismatch { + ip, + expected: expected_type(num_type, ExpectedCategory::Integer), + found: get_type_name(value.clone()), + }); + } } Ok(match num_type { PrimitiveTypes::Sht => Value::Array(divv_i16in(&arr_a, &arr_b)), @@ -61,7 +74,7 @@ pub fn divv_values( return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::All), - found: num_type.directive(), + found: "unknown", }); } }) @@ -89,6 +102,23 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn rejects_float_elements_for_integer_directives() { + let left = array(vec![Value::Int64(2)]); + let right = array(vec![Value::Float32(1.0)]); + assert!(matches!( + divv_values(left.clone(), right.clone(), PrimitiveTypes::Lng, 24), + Err(VMError::TypeMismatch { + ip: 24, + expected: "Long", + found: "Float" + }) + )); + let mut stack = Stack::from_vec(vec![left, right]); + let original = stack.clone(); + assert!(divv_func(&mut stack, PrimitiveTypes::Lng, 25).is_err()); + assert_eq!(stack, original); + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false), array(vec![Value::Int32(1)])]); let original = stack.clone(); diff --git a/rust/src/instructions/math/vector/arithmetic/modv_func.rs b/rust/src/instructions/math/vector/arithmetic/modv_func.rs index ca2d1e24..fea00077 100644 --- a/rust/src/instructions/math/vector/arithmetic/modv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/modv_func.rs @@ -48,6 +48,19 @@ pub fn modv_values( found: get_type_name(value.clone()), }); } + if matches!( + num_type, + PrimitiveTypes::Sht | PrimitiveTypes::Int | PrimitiveTypes::Lng | PrimitiveTypes::Oct + ) && matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { + return Err(VMError::TypeMismatch { + ip, + expected: expected_type(num_type, ExpectedCategory::Integer), + found: get_type_name(value.clone()), + }); + } } Ok(match num_type { PrimitiveTypes::Sht => Value::Array(modv_i16in(&arr_a, &arr_b)), @@ -61,7 +74,7 @@ pub fn modv_values( return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::All), - found: num_type.directive(), + found: "unknown", }); } }) @@ -89,6 +102,23 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn rejects_float_elements_for_integer_directives() { + let left = array(vec![Value::Float64(2.0)]); + let right = array(vec![Value::Int128(1)]); + assert!(matches!( + modv_values(left.clone(), right.clone(), PrimitiveTypes::Oct, 24), + Err(VMError::TypeMismatch { + ip: 24, + expected: "Octa", + found: "Double" + }) + )); + let mut stack = Stack::from_vec(vec![left, right]); + let original = stack.clone(); + assert!(modv_func(&mut stack, PrimitiveTypes::Oct, 25).is_err()); + assert_eq!(stack, original); + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false), array(vec![Value::Int32(1)])]); let original = stack.clone(); diff --git a/rust/src/instructions/math/vector/arithmetic/mulv_func.rs b/rust/src/instructions/math/vector/arithmetic/mulv_func.rs index 345d3bfc..21e5536c 100644 --- a/rust/src/instructions/math/vector/arithmetic/mulv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/mulv_func.rs @@ -48,6 +48,19 @@ pub fn mulv_values( found: get_type_name(value.clone()), }); } + if matches!( + num_type, + PrimitiveTypes::Sht | PrimitiveTypes::Int | PrimitiveTypes::Lng | PrimitiveTypes::Oct + ) && matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { + return Err(VMError::TypeMismatch { + ip, + expected: expected_type(num_type, ExpectedCategory::Integer), + found: get_type_name(value.clone()), + }); + } } Ok(match num_type { PrimitiveTypes::Sht => Value::Array(mulv_i16in(&arr_a, &arr_b)), @@ -61,7 +74,7 @@ pub fn mulv_values( return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::All), - found: expected_type(num_type, ExpectedCategory::All), + found: "unknown", }); } }) @@ -89,6 +102,23 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn rejects_float_elements_for_integer_directives() { + let left = array(vec![Value::Float16(half::f16::ONE)]); + let right = array(vec![Value::Int16(2)]); + assert!(matches!( + mulv_values(left.clone(), right.clone(), PrimitiveTypes::Sht, 24), + Err(VMError::TypeMismatch { + ip: 24, + expected: "Short", + found: "Half" + }) + )); + let mut stack = Stack::from_vec(vec![left, right]); + let original = stack.clone(); + assert!(mulv_func(&mut stack, PrimitiveTypes::Sht, 25).is_err()); + assert_eq!(stack, original); + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false), array(vec![Value::Int32(1)])]); let original = stack.clone(); diff --git a/rust/src/instructions/math/vector/arithmetic/negv_func.rs b/rust/src/instructions/math/vector/arithmetic/negv_func.rs index 6801babb..6c924176 100644 --- a/rust/src/instructions/math/vector/arithmetic/negv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/negv_func.rs @@ -31,6 +31,19 @@ pub fn negv_values(a_val: Value, num_type: PrimitiveTypes, ip: usize) -> Result< found: get_type_name(value.clone()), }); } + if matches!( + num_type, + PrimitiveTypes::Sht | PrimitiveTypes::Int | PrimitiveTypes::Lng | PrimitiveTypes::Oct + ) && matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { + return Err(VMError::TypeMismatch { + ip, + expected: expected_type(num_type, ExpectedCategory::Integer), + found: get_type_name(value.clone()), + }); + } } Ok(match num_type { PrimitiveTypes::Sht => Value::Array(negv_i16in(&arr_a)), @@ -44,7 +57,7 @@ pub fn negv_values(a_val: Value, num_type: PrimitiveTypes, ip: usize) -> Result< return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::All), - found: num_type.directive(), + found: "unknown", }); } }) @@ -67,6 +80,22 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn rejects_float_elements_for_integer_directives() { + let value = array(vec![Value::Float32(1.0)]); + assert!(matches!( + negv_values(value.clone(), PrimitiveTypes::Int, 24), + Err(VMError::TypeMismatch { + ip: 24, + expected: "Integer", + found: "Float" + }) + )); + let mut stack = Stack::from_vec(vec![value]); + let original = stack.clone(); + assert!(negv_func(&mut stack, PrimitiveTypes::Int, 25).is_err()); + assert_eq!(stack, original); + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false)]); let original = stack.clone(); diff --git a/rust/src/instructions/math/vector/arithmetic/powfv_func.rs b/rust/src/instructions/math/vector/arithmetic/powfv_func.rs index 1d945862..80195487 100644 --- a/rust/src/instructions/math/vector/arithmetic/powfv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/powfv_func.rs @@ -42,7 +42,10 @@ pub fn powfv_values( }); } for value in arr_a.iter().chain(arr_b.iter()) { - if !value.is_number() { + if !matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::Float), @@ -58,7 +61,7 @@ pub fn powfv_values( return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::Float), - found: expected_type(num_type, ExpectedCategory::All), + found: "unknown", }); } }) @@ -89,6 +92,31 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn requires_float_elements_and_accepts_cross_width_values() { + assert!( + powfv_values( + array(vec![Value::Float16(half::f16::from_f32(2.0))]), + array(vec![Value::Float64(3.0)]), + PrimitiveTypes::Flt, + 24 + ) + .is_ok() + ); + for invalid in [Value::Int32(2), Value::Bool(false)] { + let left = array(vec![invalid.clone()]); + let right = array(vec![Value::Float32(3.0)]); + assert!(matches!( + powfv_values(left.clone(), right.clone(), PrimitiveTypes::Flt, 25), + Err(VMError::TypeMismatch { ip: 25, expected: "Float", found: actual }) + if actual == get_type_name(invalid.clone()) + )); + let mut stack = Stack::from_vec(vec![left, right]); + let original = stack.clone(); + assert!(powfv_func(&mut stack, PrimitiveTypes::Flt, 26).is_err()); + assert_eq!(stack, original); + } + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false), array(vec![Value::Int32(1)])]); let original = stack.clone(); diff --git a/rust/src/instructions/math/vector/arithmetic/powiv_func.rs b/rust/src/instructions/math/vector/arithmetic/powiv_func.rs index 16ef7acf..db3bf585 100644 --- a/rust/src/instructions/math/vector/arithmetic/powiv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/powiv_func.rs @@ -12,11 +12,10 @@ use crate::instructions::math::vector::arithmetic::powiv::{ powiv_f16in::powiv_f16in, powiv_f32in::powiv_f32in, powiv_f64in::powiv_f64in, }; use crate::modules::vmerror::VMError; -use crate::types::expected_category::ExpectedCategory; use crate::types::primitive_types::PrimitiveTypes; use crate::types::stack::Stack; use crate::types::value::Value; -use crate::utils::{expected_type::expected_type, get_type_name::get_type_name}; +use crate::utils::get_type_name::get_type_name; fn expected_powiv_type(num_type: PrimitiveTypes) -> &'static str { match num_type { PrimitiveTypes::Hlf => "Float16/Int16", @@ -49,8 +48,23 @@ pub fn powiv_values( found: "Array", }); } - for value in arr_a.iter().chain(arr_b.iter()) { - if !value.is_number() { + for value in arr_a.iter() { + if !matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { + return Err(VMError::TypeMismatch { + ip, + expected: expected_powiv_type(num_type), + found: get_type_name(value.clone()), + }); + } + } + for value in arr_b.iter() { + if !matches!( + value, + Value::Int16(_) | Value::Int32(_) | Value::Int64(_) | Value::Int128(_) + ) { return Err(VMError::TypeMismatch { ip, expected: expected_powiv_type(num_type), @@ -66,7 +80,7 @@ pub fn powiv_values( return Err(VMError::TypeMismatch { ip, expected: expected_powiv_type(num_type), - found: expected_type(num_type, ExpectedCategory::All), + found: "unknown", }); } }) @@ -97,6 +111,35 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn validates_operand_families_and_accepts_cross_width_values() { + assert!( + powiv_values( + array(vec![Value::Float16(half::f16::from_f32(2.0))]), + array(vec![Value::Int64(3)]), + PrimitiveTypes::Flt, + 24 + ) + .is_ok() + ); + for (base, exponent, found) in [ + (Value::Int32(2), Value::Int32(3), "Integer"), + (Value::Float32(2.0), Value::Float64(3.0), "Double"), + (Value::Float32(2.0), Value::Bool(false), "Boolean"), + ] { + let left = array(vec![base]); + let right = array(vec![exponent]); + assert!(matches!( + powiv_values(left.clone(), right.clone(), PrimitiveTypes::Flt, 25), + Err(VMError::TypeMismatch { ip: 25, expected: "Float32/Int32", found: actual }) + if actual == found + )); + let mut stack = Stack::from_vec(vec![left, right]); + let original = stack.clone(); + assert!(powiv_func(&mut stack, PrimitiveTypes::Flt, 26).is_err()); + assert_eq!(stack, original); + } + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false), array(vec![Value::Int32(1)])]); let original = stack.clone(); @@ -110,7 +153,7 @@ mod tests { fn validates_elements_and_directives() { assert!( powiv_values( - array(vec![Value::Int32(1)]), + array(vec![Value::Float32(1.0)]), array(vec![Value::Int32(1)]), PrimitiveTypes::Flt, 11 diff --git a/rust/src/instructions/math/vector/arithmetic/powv_func.rs b/rust/src/instructions/math/vector/arithmetic/powv_func.rs index 478cdc96..142120fc 100644 --- a/rust/src/instructions/math/vector/arithmetic/powv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/powv_func.rs @@ -49,6 +49,16 @@ pub fn powv_values( found: get_type_name(value.clone()), }); } + if matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { + return Err(VMError::TypeMismatch { + ip, + expected: expected_type(num_type, ExpectedCategory::Integer), + found: get_type_name(value.clone()), + }); + } } Ok(match num_type { PrimitiveTypes::Sht => Value::Array(powv_i16in(&arr_a, &arr_b)), @@ -59,7 +69,7 @@ pub fn powv_values( return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::Integer), - found: expected_type(num_type, ExpectedCategory::All), + found: "unknown", }); } }) @@ -87,6 +97,23 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn rejects_float_elements() { + let left = array(vec![Value::Int32(2)]); + let right = array(vec![Value::Float32(3.0)]); + assert!(matches!( + powv_values(left.clone(), right.clone(), PrimitiveTypes::Int, 24), + Err(VMError::TypeMismatch { + ip: 24, + expected: "Integer", + found: "Float" + }) + )); + let mut stack = Stack::from_vec(vec![left, right]); + let original = stack.clone(); + assert!(powv_func(&mut stack, PrimitiveTypes::Int, 25).is_err()); + assert_eq!(stack, original); + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false), array(vec![Value::Int32(1)])]); let original = stack.clone(); diff --git a/rust/src/instructions/math/vector/arithmetic/sinv_func.rs b/rust/src/instructions/math/vector/arithmetic/sinv_func.rs index 53156ef3..cbcc6cd6 100644 --- a/rust/src/instructions/math/vector/arithmetic/sinv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/sinv_func.rs @@ -25,7 +25,10 @@ pub fn sinv_values(a_val: Value, num_type: PrimitiveTypes, ip: usize) -> Result< found: get_type_name(a_val.clone()), })?; for value in arr_a.iter() { - if !value.is_number() { + if !matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::Float), @@ -41,7 +44,7 @@ pub fn sinv_values(a_val: Value, num_type: PrimitiveTypes, ip: usize) -> Result< return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::Float), - found: expected_type(num_type, ExpectedCategory::All), + found: "unknown", }); } }) @@ -64,6 +67,22 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn requires_float_elements_and_accepts_cross_width_values() { + assert!(sinv_values(array(vec![Value::Float64(0.0)]), PrimitiveTypes::Hlf, 24).is_ok()); + for invalid in [Value::Int32(1), Value::Bool(false)] { + let value = array(vec![invalid.clone()]); + assert!(matches!( + sinv_values(value.clone(), PrimitiveTypes::Flt, 25), + Err(VMError::TypeMismatch { ip: 25, expected: "Float", found: actual }) + if actual == get_type_name(invalid.clone()) + )); + let mut stack = Stack::from_vec(vec![value]); + let original = stack.clone(); + assert!(sinv_func(&mut stack, PrimitiveTypes::Flt, 26).is_err()); + assert_eq!(stack, original); + } + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false)]); let original = stack.clone(); diff --git a/rust/src/instructions/math/vector/arithmetic/subv_func.rs b/rust/src/instructions/math/vector/arithmetic/subv_func.rs index 54b7e3a0..ac43e8f2 100644 --- a/rust/src/instructions/math/vector/arithmetic/subv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/subv_func.rs @@ -50,6 +50,19 @@ pub fn subv_values( found: get_type_name(value.clone()), }); } + if matches!( + num_type, + PrimitiveTypes::Sht | PrimitiveTypes::Int | PrimitiveTypes::Lng | PrimitiveTypes::Oct + ) && matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { + return Err(VMError::TypeMismatch { + ip, + expected: expected_type(num_type, ExpectedCategory::Integer), + found: get_type_name(value.clone()), + }); + } } Ok(match num_type { PrimitiveTypes::Sht => Value::Array(subv_i16in(&arr_a, &arr_b)), @@ -63,7 +76,7 @@ pub fn subv_values( return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::All), - found: num_type.directive(), + found: "unknown", }); } }) @@ -91,6 +104,23 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn rejects_float_elements_for_integer_directives() { + let left = array(vec![Value::Int32(2)]); + let right = array(vec![Value::Float64(1.0)]); + assert!(matches!( + subv_values(left.clone(), right.clone(), PrimitiveTypes::Int, 24), + Err(VMError::TypeMismatch { + ip: 24, + expected: "Integer", + found: "Double" + }) + )); + let mut stack = Stack::from_vec(vec![left, right]); + let original = stack.clone(); + assert!(subv_func(&mut stack, PrimitiveTypes::Int, 25).is_err()); + assert_eq!(stack, original); + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false), array(vec![Value::Int32(1)])]); let original = stack.clone(); diff --git a/rust/src/instructions/math/vector/arithmetic/tanv_func.rs b/rust/src/instructions/math/vector/arithmetic/tanv_func.rs index d42b2678..ac6f9cb0 100644 --- a/rust/src/instructions/math/vector/arithmetic/tanv_func.rs +++ b/rust/src/instructions/math/vector/arithmetic/tanv_func.rs @@ -25,7 +25,10 @@ pub fn tanv_values(a_val: Value, num_type: PrimitiveTypes, ip: usize) -> Result< found: get_type_name(a_val.clone()), })?; for value in arr_a.iter() { - if !value.is_number() { + if !matches!( + value, + Value::Float16(_) | Value::Float32(_) | Value::Float64(_) + ) { return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::Float), @@ -41,7 +44,7 @@ pub fn tanv_values(a_val: Value, num_type: PrimitiveTypes, ip: usize) -> Result< return Err(VMError::TypeMismatch { ip, expected: expected_type(num_type, ExpectedCategory::Float), - found: expected_type(num_type, ExpectedCategory::All), + found: "unknown", }); } }) @@ -64,6 +67,22 @@ mod tests { Value::Array(Arc::new(values)) } #[test] + fn requires_float_elements_and_accepts_cross_width_values() { + assert!(tanv_values(array(vec![Value::Float64(0.0)]), PrimitiveTypes::Flt, 24).is_ok()); + for invalid in [Value::Int16(1), Value::Bool(false)] { + let value = array(vec![invalid.clone()]); + assert!(matches!( + tanv_values(value.clone(), PrimitiveTypes::Flt, 25), + Err(VMError::TypeMismatch { ip: 25, expected: "Float", found: actual }) + if actual == get_type_name(invalid.clone()) + )); + let mut stack = Stack::from_vec(vec![value]); + let original = stack.clone(); + assert!(tanv_func(&mut stack, PrimitiveTypes::Flt, 26).is_err()); + assert_eq!(stack, original); + } + } + #[test] fn reports_type_mismatch_without_mutating_stack() { let mut stack = Stack::from_vec(vec![Value::Bool(false)]); let original = stack.clone();