Repository: MiSawa/xq
Pull request #84 (2022-02-27 05:53:27)

Implement trigonometric and hyperbolic functions
This PR adds trigonometric functions, inverse trigonometric functions, hyperbolic functions, and inverse hyperbolic functions. In tests, I used `floor` to round the results because we cannot get some floating-point number exactly (for example, we can't test `2 | sin` equals to `0.9092974268256817` due to deserializing error). Also note that current testing macro does not allow to test nan value (and maybe infinite as well).


Patch:
diff --git a/src/intrinsic/math.rs b/src/intrinsic/math.rs
index fdb8b28..31b45d2 100644
--- a/src/intrinsic/math.rs
+++ b/src/intrinsic/math.rs
@@ -36,10 +36,14 @@ pub(crate) fn is_finite(v: Number) -> Result<bool> {
     Ok(v.is_finite())
 }
 
-pub(crate) fn floor(v: Number) -> Result<Number> {
-    Ok(v.floor())
+macro_rules! pub_math_fn {
+    ($($name: ident),*) => {
+        $(
+            pub(crate) fn $name(v: Number) -> Result<Number> {
+                Ok(v.$name())
+            }
+        )*
+    };
 }
 
-pub(crate) fn sqrt(v: Number) -> Result<Number> {
-    Ok(v.sqrt())
-}
+pub_math_fn!(floor, sqrt, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh);
diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs
index f037003..bbfe46f 100644
--- a/src/intrinsic/mod.rs
+++ b/src/intrinsic/mod.rs
@@ -53,11 +53,23 @@ static INTRINSICS0: phf::Map<&'static str, NamedFn0> = phf_map! {
 
     "nan" => NamedFn0 { name: "nan", func: math::nan },
     "infinite" => NamedFn0 { name: "infinite", func: math::infinite },
-    "floor" => as_math_fn!(floor),
-    "sqrt" => as_math_fn!(sqrt),
     "isnan" => as_math_fn!(is_nan),
-    "isfinite" => as_math_fn!(is_finite),
     "isnormal" => as_math_fn!(is_normal),
+    "isfinite" => as_math_fn!(is_finite),
+    "floor" => as_math_fn!(floor),
+    "sqrt" => as_math_fn!(sqrt),
+    "sin" => as_math_fn!(sin),
+    "cos" => as_math_fn!(cos),
+    "tan" => as_math_fn!(tan),
+    "asin" => as_math_fn!(asin),
+    "acos" => as_math_fn!(acos),
+    "atan" => as_math_fn!(atan),
+    "sinh" => as_math_fn!(sinh),
+    "cosh" => as_math_fn!(cosh),
+    "tanh" => as_math_fn!(tanh),
+    "asinh" => as_math_fn!(asinh),
+    "acosh" => as_math_fn!(acosh),
+    "atanh" => as_math_fn!(atanh),
 };
 static INTRINSICS1: phf::Map<&'static str, NamedFn1> = phf_map! {
     "error" => NamedFn1 { name: "error", func: error1 },


Test patch:
diff --git a/tests/hand_written/math.rs b/tests/hand_written/math.rs
new file mode 100644
index 0000000..095537c
--- /dev/null
+++ b/tests/hand_written/math.rs
@@ -0,0 +1,61 @@
+use crate::test;
+
+test!(
+    trigonometric_functions,
+    r#"
+    map(sin), map(cos), map(tan) | map(. * 1000000000 | floor / 1000000000)
+    "#,
+    r#"
+    [0,1,2]
+    "#,
+    r#"
+    [0,0.841470984, 0.909297426]
+    [1,0.540302305,-0.416146837]
+    [0,1.557407724,-2.185039864]
+    "#
+);
+
+test!(
+    inverse_trigonometric_functions,
+    r#"
+    map(asin), map(acos), map(atan) | map(. * 1000000000 | floor / 1000000000)
+    "#,
+    r#"
+    [0,0.5,1]
+    "#,
+    r#"
+    [0,0.523598775,1.570796326]
+    [1.570796326,1.047197551,0]
+    [0,0.463647609,0.785398163]
+    "#
+);
+
+test!(
+    hyperbolic_functions,
+    r#"
+    map(sinh), map(cosh), map(tanh) | map(. * 1000000000 | floor / 1000000000)
+    "#,
+    r#"
+    [0,1,2]
+    "#,
+    r#"
+    [0,1.175201193,3.626860407]
+    [1,1.543080634,3.762195691]
+    [0,0.761594155,0.964027580]
+    "#
+);
+
+test!(
+    inverse_hyperbolic_functions,
+    r#"
+    map(asinh), map(.+1 | acosh), map(./3 | atanh) | map(. * 1000000000 | floor / 1000000000)
+    "#,
+    r#"
+    [0,1,2]
+    "#,
+    r#"
+    [0,0.881373587,1.443635475]
+    [0,1.316957896,1.762747174]
+    [0,0.346573590,0.804718956]
+    "#
+);
diff --git a/tests/hand_written/mod.rs b/tests/hand_written/mod.rs
index 810971c..fbcceb6 100644
--- a/tests/hand_written/mod.rs
+++ b/tests/hand_written/mod.rs
@@ -1,6 +1,7 @@
 use crate::test;
 
 mod assignments;
+mod math;
 
 test!(
     recursive,