From b27596c2c3b7723e9fb299104df9b39967e2243a Mon Sep 17 00:00:00 2001 From: PierreYvesR Date: Tue, 26 Dec 2023 13:12:30 +0000 Subject: [PATCH] Support custom Math operators single-operand only: log, exp and trigonometric functions --- src/Fable.Transforms/Replacements.fs | 8 +++++++- tests/Dart/src/CustomOperatorTests.fs | 5 +++++ tests/Js/Main/CustomOperatorsTests.fs | 10 ++++++++++ tests/Python/TestCustomOperators.fs | 6 ++++++ tests/Rust/tests/src/CustomOperatorTests.fs | 7 +++++++ 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/Fable.Transforms/Replacements.fs b/src/Fable.Transforms/Replacements.fs index cd28bc2c91..5bb7e9cd5a 100644 --- a/src/Fable.Transforms/Replacements.fs +++ b/src/Fable.Transforms/Replacements.fs @@ -2143,7 +2143,13 @@ let operators |> Some | _ -> math r t args i.SignatureArgTypes i.CompiledName |> Some | ("Acos" | "Asin" | "Atan" | "Atan2" | "Cos" | "Cosh" | "Exp" | "Log" | "Log2" | "Log10" | "Sin" | "Sinh" | "Sqrt" | "Tan" | "Tanh"), - _ -> math r t args i.SignatureArgTypes i.CompiledName |> Some + _ -> + let argTypes = args |> List.map (fun a -> a.Type) + + match argTypes with + | Number(_, _) :: _ -> + math r t args i.SignatureArgTypes i.CompiledName |> Some + | _ -> applyOp com ctx r t i.CompiledName args |> Some | "Round", _ -> match args with | ExprType(Number(Decimal, _)) :: _ -> diff --git a/tests/Dart/src/CustomOperatorTests.fs b/tests/Dart/src/CustomOperatorTests.fs index df705c4f49..3210e0496a 100644 --- a/tests/Dart/src/CustomOperatorTests.fs +++ b/tests/Dart/src/CustomOperatorTests.fs @@ -15,6 +15,7 @@ type MyRecord = { value: int } static member (+) (x: MyRecord, y: int) = { value = x.value + y } static member (+) (x: int, y: MyRecord) = x + y.value + 2 + static member Exp (x: MyRecord) = { value = x.value + 1} type CustomPow = { Ok: bool } @@ -41,6 +42,10 @@ let typeOperators() = let x = { Ok = false } x ** 2 |> equal { Ok = true } + testCase "Custom Exp works" <| fun () -> + let x = { value = 0 } + x |> exp |> equal { value = 1 } + let (+) (x: int) (y: int) = x * y let (-) (x: int) (y: int) = x / y diff --git a/tests/Js/Main/CustomOperatorsTests.fs b/tests/Js/Main/CustomOperatorsTests.fs index 71539639f3..31caf518d1 100644 --- a/tests/Js/Main/CustomOperatorsTests.fs +++ b/tests/Js/Main/CustomOperatorsTests.fs @@ -16,6 +16,8 @@ type MyRecord = static member (+) (x: MyRecord, y: int) = { value = x.value + y } static member (+) (x: int, y: MyRecord) = x + y.value + 2 + static member Exp (x: MyRecord) = { value = x.value + 1} + type CustomPow = { Ok: bool } static member Pow(x: CustomPow, n: int) = { Ok = true } @@ -40,6 +42,14 @@ let typeOperators = [ testCase "Custom Pow works" <| fun () -> // See #2496 let x = { Ok = false } x ** 2 |> equal { Ok = true } + + testCase "Custom Exp works" <| fun () -> + let x = { value=10 } + exp x |> equal { value= 11 } + + testCase "Float Exp works" <| fun () -> + let x = 0.0 + exp x |> equal 1. ] let (+) (x: int) (y: int) = x * y diff --git a/tests/Python/TestCustomOperators.fs b/tests/Python/TestCustomOperators.fs index 66d0b605a7..9ad0df5846 100644 --- a/tests/Python/TestCustomOperators.fs +++ b/tests/Python/TestCustomOperators.fs @@ -15,6 +15,7 @@ type MyRecord = { value: int } static member (+) (x: MyRecord, y: int) = { value = x.value + y } static member (+) (x: int, y: MyRecord) = x + y.value + 2 + static member Exp (x: MyRecord) = { value = x.value + 1} [] let ``test Custom operators with types work`` () = @@ -35,6 +36,11 @@ let ``test Custom operator overloads work`` () = x + 2 |> equal { value = 7 } 3 + x |> equal 10 +[] +let ``test Custom operator Exp works`` () = + let x = { value = 0 } + x |> exp |> equal { value = 1 } + let (+) (x: int) (y: int) = x * y let (-) (x: int) (y: int) = x / y diff --git a/tests/Rust/tests/src/CustomOperatorTests.fs b/tests/Rust/tests/src/CustomOperatorTests.fs index 01cd89da23..fcf148ebeb 100644 --- a/tests/Rust/tests/src/CustomOperatorTests.fs +++ b/tests/Rust/tests/src/CustomOperatorTests.fs @@ -19,6 +19,8 @@ type MyStruct = static member (<<<) (x: MyStruct, n: int) = { value = pown x.value n } static member (~-) (x: MyStruct) = { value = -x.value } + static member Exp (x: MyStruct) = { value = exp x.value} + type MyRecord = { value: int } static member (+) (x: MyRecord, y: int) = { value = x.value + y } @@ -60,6 +62,11 @@ let ``Custom Pow works`` () = // See #2496 let x = { Ok = false } x ** 2 |> equal { Ok = true } +[] +let ``Custom Exp works`` () = + let x = { MyStruct.value = 0. } + x |> exp |> equal { MyStruct.value = 1.0 } + let (+) (x: int) (y: int) = x * y let (-) (x: int) (y: int) = x / y let (||||) x y = x + y