{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ExistentialQuantification #-}
module Data.Array.Knead.Symbolic.Render.Argument (
   Arg.T(Arg.Cons),
   Arg.unit,
   Arg.primitive,
   Arg.pair,
   Arg.triple,
   array,
   ) where

import qualified Data.Array.Knead.Symbolic.Physical as Phys
import qualified Data.Array.Knead.Symbolic.Private as Core
import qualified Data.Array.Knead.Shape as Shape
import qualified Data.Array.Knead.Expression as Expr
import Data.Array.Knead.Code (getElementPtr)

import qualified Data.Array.Comfort.Storable.Unchecked as Array

import qualified LLVM.DSL.Render.Argument as Arg
import LLVM.DSL.Expression (unExp)

import qualified LLVM.Extra.Multi.Value.Storable as Storable
import qualified LLVM.Extra.Multi.Value.Marshal as Marshal
import qualified LLVM.Extra.Multi.Value as MultiValue

import Foreign.ForeignPtr (withForeignPtr, touchForeignPtr)

import Prelude2010
import Prelude ()



array ::
   (Shape.C sh, Marshal.C sh, Storable.C a) =>
   Arg.T (Phys.Array sh a) (Core.Array sh a)
array :: forall sh a. (C sh, C sh, C a) => T (Array sh a) (Array sh a)
array =
   (Exp (sh, Ptr a) -> Array sh a)
-> (Array sh a -> Creator (sh, Ptr a))
-> T (Array sh a) (Array sh a)
forall a adsl al.
C al =>
(Exp al -> adsl) -> (a -> Creator al) -> T a adsl
Arg.Cons
      ((Exp sh -> Exp (Ptr a) -> Array sh a)
-> Exp (sh, Ptr a) -> Array sh a
forall a b c. (Exp a -> Exp b -> c) -> Exp (a, b) -> c
Expr.uncurry ((Exp sh -> Exp (Ptr a) -> Array sh a)
 -> Exp (sh, Ptr a) -> Array sh a)
-> (Exp sh -> Exp (Ptr a) -> Array sh a)
-> Exp (sh, Ptr a)
-> Array sh a
forall a b. (a -> b) -> a -> b
$ \Exp sh
esh Exp (Ptr a)
eptr ->
         Exp sh -> (forall r. Val (Index sh) -> Code r a) -> Array sh a
forall sh a.
Exp sh -> (forall r. Val (Index sh) -> Code r a) -> Array sh a
Core.Array Exp sh
esh
            (\Val (Index sh)
ix -> do
               T sh
sh <- Exp sh -> forall r. CodeGenFunction r (T sh)
forall a. Exp a -> forall r. CodeGenFunction r (T a)
unExp Exp sh
esh
               MultiValue.Cons Repr (Ptr a)
ptr <- Exp (Ptr a) -> forall r. CodeGenFunction r (T (Ptr a))
forall a. Exp a -> forall r. CodeGenFunction r (T a)
unExp Exp (Ptr a)
eptr
               Value (Ptr a) -> Code r a
forall a r. C a => Value (Ptr a) -> CodeGenFunction r (T a)
forall r. Value (Ptr a) -> CodeGenFunction r (T a)
Storable.load (Value (Ptr a) -> Code r a)
-> CodeGenFunction r (Value (Ptr a)) -> Code r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< T sh
-> Value (Ptr a)
-> Val (Index sh)
-> CodeGenFunction r (Value (Ptr a))
forall sh ix a r.
(C sh, Index sh ~ ix, C a) =>
T sh -> Value (Ptr a) -> T ix -> CodeGenFunction r (Value (Ptr a))
getElementPtr T sh
sh Repr (Ptr a)
Value (Ptr a)
ptr Val (Index sh)
ix))
      (\(Array.Array sh
sh ForeignPtr a
fptr) ->
         ForeignPtr a
-> (Ptr a -> Creator (sh, Ptr a)) -> Creator (sh, Ptr a)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
fptr ((Ptr a -> Creator (sh, Ptr a)) -> Creator (sh, Ptr a))
-> (Ptr a -> Creator (sh, Ptr a)) -> Creator (sh, Ptr a)
forall a b. (a -> b) -> a -> b
$ \Ptr a
ptr ->
         ((sh, Ptr a), IO ()) -> Creator (sh, Ptr a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ((sh
sh, Ptr a
ptr), ForeignPtr a -> IO ()
forall a. ForeignPtr a -> IO ()
touchForeignPtr ForeignPtr a
fptr))