mech_math/trig/
atan.rs

1use crate::*;
2use mech_core::*;
3use num_traits::*;
4#[cfg(feature = "matrix")]
5use mech_core::matrix::Matrix;
6
7// Atan ------------------------------------------------------------------------
8
9use libm::{atan,atanf};
10macro_rules! atan_op {
11  ($arg:expr, $out:expr) => {
12    unsafe{(*$out) = atan((*$arg));}
13  };}
14
15macro_rules! atan_vec_op {
16  ($arg:expr, $out:expr) => {
17    unsafe {
18      for i in 0..(*$arg).len() {
19        ((&mut (*$out))[i]) = atan(((&(*$arg))[i]));
20      }}};}
21
22macro_rules! atanf_op {
23  ($arg:expr, $out:expr) => {
24    unsafe{(*$out) = atanf((*$arg));}
25  };}  
26
27macro_rules! atanf_vec_op {
28  ($arg:expr, $out:expr) => {
29    unsafe {
30      for i in 0..(*$arg).len() {
31        ((&mut (*$out))[i]) = atanf(((&(*$arg))[i]));
32      }}};}
33
34#[cfg(feature = "f32")]
35impl_math_unop!(MathAtan, f32, atanf, FeatureFlag::Custom(hash_str("math/atan")));
36#[cfg(feature = "f64")]
37impl_math_unop!(MathAtan, f64, atan, FeatureFlag::Custom(hash_str("math/atan")));
38
39fn impl_atan_fxn(lhs_value: Value) -> MResult<Box<dyn MechFunction>> {
40  impl_urnop_match_arms2!(
41    MathAtan,
42    (lhs_value),
43    F32 => MatrixF32, F32, f32::zero(), "f32";
44    F64 => MatrixF64, F64, f64::zero(), "f64";
45  )
46}
47
48pub struct MathAtan {}
49
50impl NativeFunctionCompiler for MathAtan {
51  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
52    if arguments.len() == 1 {
53      let input = arguments[0].clone();
54      match impl_atan_fxn(input.clone()) {
55        Ok(fxn) => Ok(fxn),
56        Err(_) => {
57          match (input) {
58            (Value::MutableReference(input)) => {impl_atan_fxn(input.borrow().clone())}
59            x => Err(MechError2::new(
60                UnhandledFunctionArgumentKind1 { arg: x.kind(), fxn_name: "math/atan".to_string() },
61                None
62              ).with_compiler_loc()
63            ),
64          }
65        }
66      }
67    } else if arguments.len() == 2 {
68      let arg1 = arguments[0].clone();
69      let arg2 = arguments[1].clone();
70      match impl_atan2_fxn(arg1.clone(), arg2.clone()) {
71        Ok(fxn) => Ok(fxn),
72        Err(_) => {
73          match (arg1,arg2) {
74            (Value::MutableReference(arg1),Value::MutableReference(arg2)) => {impl_atan2_fxn(arg1.borrow().clone(),arg2.borrow().clone())}
75            (Value::MutableReference(arg1),arg2) => {impl_atan2_fxn(arg1.borrow().clone(),arg2.clone())}
76            (arg1,Value::MutableReference(arg2)) => {impl_atan2_fxn(arg1.clone(),arg2.borrow().clone())}
77            (arg1,arg2) => Err(MechError2::new(
78                UnhandledFunctionArgumentKind2 { arg: (arg1.kind(),arg2.kind()), fxn_name: "math/atan".to_string() },
79                None
80              ).with_compiler_loc()
81            ),
82          }
83        }
84      }
85    } else {
86      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() },None).with_compiler_loc());
87    }
88  }
89}
90
91register_descriptor! {
92  FunctionCompilerDescriptor {
93    name: "math/atan",
94    ptr: &MathAtan{},
95  }
96}