{-# LANGUAGE BlockArguments      #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE ViewPatterns        #-}

module Dovetail.Core.Math where

import Data.Foldable (fold)
import Dovetail
import Dovetail.Evaluate (builtIn)

env :: forall ctx. Env ctx
env :: Env ctx
env = do
  let _ModuleName :: ModuleName
_ModuleName = Text -> ModuleName
ModuleName Text
"Math"

  [Env ctx] -> Env ctx
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold
    [ -- abs :: Number -> Number
      ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"abs"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double
forall a. Num a => a -> a
abs Double
a)
      -- acos :: Number -> Radians
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"acos"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double
forall a. Floating a => a -> a
acos Double
a)
      -- asin :: Number -> Radians
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"asin"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double
forall a. Floating a => a -> a
asin Double
a)
      -- atan :: Number -> Radians
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"atan"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double
forall a. Floating a => a -> a
atan Double
a)
      -- atan2 :: Number -> Number -> Radians
    , ModuleName
-> Text -> (Double -> Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"atan2"
        \Double
a Double
b -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double -> Double
forall a. RealFloat a => a -> a -> a
atan2 Double
a Double
b)
      -- ceil :: Number -> Number
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"ceil"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Integer (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
ceiling Double
a))
      -- cos :: Radians -> Number
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"cos"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double
forall a. Floating a => a -> a
cos Double
a)
      -- exp :: Number -> Number
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"exp"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double
forall a. Floating a => a -> a
exp Double
a)
      -- floor :: Number -> Number
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"floor"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Integer (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
a))
      -- imul :: Int -> Int -> Int
    , ModuleName
-> Text -> (Integer -> Integer -> Eval ctx Integer) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Integer -> Integer -> Eval ctx Integer)
        ModuleName
_ModuleName Text
"imul"
        \Integer
a Integer
b ->
          Integer -> Eval ctx Integer
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
b)
      -- log :: Number -> Number
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"log"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double
forall a. Floating a => a -> a
log Double
a)
      -- max :: Number -> Number -> Number
    , ModuleName
-> Text -> (Double -> Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"max"
        \Double
a Double
b -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
a Double
b)
      -- min :: Number -> Number -> Number
    , ModuleName
-> Text -> (Double -> Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"min"
        \Double
a Double
b -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double -> Double
forall a. Ord a => a -> a -> a
min Double
a Double
b)
      -- pow :: Number -> Number -> Number
    , ModuleName
-> Text -> (Double -> Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"pow"
        \Double
a Double
b -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double
a Double -> Double -> Double
forall a. Floating a => a -> a -> a
** Double
b)
      -- round :: Number -> Number
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"round"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Integer (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round Double
a))
      -- sin :: Radians -> Number
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"sin"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double
forall a. Floating a => a -> a
sin Double
a)
      -- sqrt :: Number -> Number
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"sqrt"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double
forall a. Floating a => a -> a
sqrt Double
a)
      -- tan :: Radians -> Number
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"tan"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> Double
forall a. Floating a => a -> a
tan Double
a)
      -- trunc :: Number -> Number
    , ModuleName -> Text -> (Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"trunc"
        \Double
a -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Integer (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate Double
a))
      -- remainder :: Number -> Number -> Number
    , ModuleName
-> Text -> (Double -> Double -> Eval ctx Double) -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @(Double -> Double -> Eval ctx Double)
        ModuleName
_ModuleName Text
"remainder"
        \Double
a Double
b -> 
          Double -> Eval ctx Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double
a Double -> Double -> Double
forall a. Num a => a -> a -> a
- Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Integer (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Double
a Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
b)) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
b)
      -- e :: Number
    , ModuleName -> Text -> Double -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @Double
        ModuleName
_ModuleName Text
"e"
          (Double -> Double
forall a. Floating a => a -> a
exp Double
1)
      -- ln2 :: Number
    , ModuleName -> Text -> Double -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @Double
        ModuleName
_ModuleName Text
"ln2"
          (Double -> Double
forall a. Floating a => a -> a
log Double
2)
      -- ln10 :: Number
    , ModuleName -> Text -> Double -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @Double
        ModuleName
_ModuleName Text
"ln10"
          (Double -> Double
forall a. Floating a => a -> a
log Double
10)
      -- log2e :: Number
    , ModuleName -> Text -> Double -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @Double
        ModuleName
_ModuleName Text
"log2e"
          (Double
1 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double -> Double
forall a. Floating a => a -> a
log Double
2)
      -- log10e :: Number
    , ModuleName -> Text -> Double -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @Double
        ModuleName
_ModuleName Text
"log10e"
          (Double
1 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/  Double -> Double
forall a. Floating a => a -> a
log Double
10)
      -- pi :: Number
    , ModuleName -> Text -> Double -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @Double
        ModuleName
_ModuleName Text
"pi"
          Double
forall a. Floating a => a
pi
      -- tau :: Number
    , ModuleName -> Text -> Double -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @Double
        ModuleName
_ModuleName Text
"tau"
          (Double
2 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
forall a. Floating a => a
pi)
      -- sqrt1_2 :: Number
    , ModuleName -> Text -> Double -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @Double
        ModuleName
_ModuleName Text
"sqrt1_2"
          (Double -> Double
forall a. Floating a => a -> a
sqrt Double
0.5)
      -- sqrt2 :: Number
    , ModuleName -> Text -> Double -> Env ctx
forall ctx a. ToValue ctx a => ModuleName -> Text -> a -> Env ctx
builtIn @ctx @Double
        ModuleName
_ModuleName Text
"sqrt2"
          (Double -> Double
forall a. Floating a => a -> a
sqrt Double
2)
    ]