{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{- |
Loops over Storable arrays.
-}
module LLVM.Extra.Storable.Array where

import qualified LLVM.Extra.Storable.Private as Storable
import qualified LLVM.Extra.MaybeContinuation as MaybeCont
import qualified LLVM.Extra.Maybe as Maybe
import qualified LLVM.Extra.Tuple as Tuple
import qualified LLVM.Extra.Control as C
import LLVM.Core
   (CodeGenFunction, Value, CmpRet, IsInteger, IsConst, IsPrimitive)

import Foreign.Storable (Storable)
import Foreign.Ptr (Ptr)

import Control.Monad (liftM2)

import Data.Tuple.HT (mapSnd)


arrayLoop ::
   (Tuple.Phi s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i,
    Storable a, Value (Ptr a) ~ ptrA) =>
   Value i -> ptrA -> s ->
   (ptrA -> s -> CodeGenFunction r s) ->
   CodeGenFunction r s
arrayLoop :: forall s i a ptrA r.
(Phi s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i,
 Storable a, Value (Ptr a) ~ ptrA) =>
Value i
-> ptrA
-> s
-> (ptrA -> s -> CodeGenFunction r s)
-> CodeGenFunction r s
arrayLoop Value i
len ptrA
ptr s
start ptrA -> s -> CodeGenFunction r s
body =
   ((ptrA, s) -> s)
-> CodeGenFunction r (ptrA, s) -> CodeGenFunction r s
forall a b. (a -> b) -> CodeGenFunction r a -> CodeGenFunction r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ptrA, s) -> s
forall a b. (a, b) -> b
snd (CodeGenFunction r (ptrA, s) -> CodeGenFunction r s)
-> CodeGenFunction r (ptrA, s) -> CodeGenFunction r s
forall a b. (a -> b) -> a -> b
$
   Value i
-> (ptrA, s)
-> ((ptrA, s) -> CodeGenFunction r (ptrA, s))
-> CodeGenFunction r (ptrA, s)
forall s i r.
(Phi s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>
Value i -> s -> (s -> CodeGenFunction r s) -> CodeGenFunction r s
C.fixedLengthLoop Value i
len (ptrA
ptr, s
start) (((ptrA, s) -> CodeGenFunction r (ptrA, s))
 -> CodeGenFunction r (ptrA, s))
-> ((ptrA, s) -> CodeGenFunction r (ptrA, s))
-> CodeGenFunction r (ptrA, s)
forall a b. (a -> b) -> a -> b
$ \(ptrA
p,s
s) ->
      (ptrA -> s -> (ptrA, s))
-> CodeGenFunction r ptrA
-> CodeGenFunction r s
-> CodeGenFunction r (ptrA, s)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) (ptrA -> CodeGenFunction r ptrA
forall a ptr r.
(Storable a, Value (Ptr a) ~ ptr) =>
ptr -> CodeGenFunction r ptr
Storable.incrementPtr ptrA
p) (ptrA -> s -> CodeGenFunction r s
body ptrA
p s
s)

arrayLoop2 ::
   (Tuple.Phi s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i,
    Storable a, Value (Ptr a) ~ ptrA,
    Storable b, Value (Ptr b) ~ ptrB) =>
   Value i -> ptrA -> ptrB -> s ->
   (ptrA -> ptrB -> s -> CodeGenFunction r s) ->
   CodeGenFunction r s
arrayLoop2 :: forall s i a ptrA b ptrB r.
(Phi s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i,
 Storable a, Value (Ptr a) ~ ptrA, Storable b,
 Value (Ptr b) ~ ptrB) =>
Value i
-> ptrA
-> ptrB
-> s
-> (ptrA -> ptrB -> s -> CodeGenFunction r s)
-> CodeGenFunction r s
arrayLoop2 Value i
len ptrA
ptrA ptrB
ptrB s
start ptrA -> ptrB -> s -> CodeGenFunction r s
body =
   ((ptrB, s) -> s)
-> CodeGenFunction r (ptrB, s) -> CodeGenFunction r s
forall a b. (a -> b) -> CodeGenFunction r a -> CodeGenFunction r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ptrB, s) -> s
forall a b. (a, b) -> b
snd (CodeGenFunction r (ptrB, s) -> CodeGenFunction r s)
-> CodeGenFunction r (ptrB, s) -> CodeGenFunction r s
forall a b. (a -> b) -> a -> b
$
   Value i
-> ptrA
-> (ptrB, s)
-> (ptrA -> (ptrB, s) -> CodeGenFunction r (ptrB, s))
-> CodeGenFunction r (ptrB, s)
forall s i a ptrA r.
(Phi s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i,
 Storable a, Value (Ptr a) ~ ptrA) =>
Value i
-> ptrA
-> s
-> (ptrA -> s -> CodeGenFunction r s)
-> CodeGenFunction r s
arrayLoop Value i
len ptrA
ptrA (ptrB
ptrB,s
start) ((ptrA -> (ptrB, s) -> CodeGenFunction r (ptrB, s))
 -> CodeGenFunction r (ptrB, s))
-> (ptrA -> (ptrB, s) -> CodeGenFunction r (ptrB, s))
-> CodeGenFunction r (ptrB, s)
forall a b. (a -> b) -> a -> b
$ \ptrA
pa (ptrB
pb,s
s) ->
      (ptrB -> s -> (ptrB, s))
-> CodeGenFunction r ptrB
-> CodeGenFunction r s
-> CodeGenFunction r (ptrB, s)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) (ptrB -> CodeGenFunction r ptrB
forall a ptr r.
(Storable a, Value (Ptr a) ~ ptr) =>
ptr -> CodeGenFunction r ptr
Storable.incrementPtr ptrB
pb) (ptrA -> ptrB -> s -> CodeGenFunction r s
body ptrA
pa ptrB
pb s
s)


arrayLoopMaybeCont ::
   (Tuple.Phi s, Tuple.Undefined s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i,
    Storable a, Value (Ptr a) ~ ptrA,
    Maybe.T (ptrA, s) ~ z) =>
   Value i ->
   ptrA -> s ->
   (ptrA -> s -> MaybeCont.T r z s) ->
   CodeGenFunction r (Value i, Maybe.T s)
arrayLoopMaybeCont :: forall s i a ptrA z r.
(Phi s, Undefined s, Num i, IsConst i, IsInteger i, CmpRet i,
 IsPrimitive i, Storable a, Value (Ptr a) ~ ptrA,
 T (ptrA, s) ~ z) =>
Value i
-> ptrA
-> s
-> (ptrA -> s -> T r z s)
-> CodeGenFunction r (Value i, T s)
arrayLoopMaybeCont Value i
len ptrA
ptr s
start ptrA -> s -> T r z s
body =
   ((Value i, T (ptrA, s)) -> (Value i, T s))
-> CodeGenFunction r (Value i, T (ptrA, s))
-> CodeGenFunction r (Value i, T s)
forall a b. (a -> b) -> CodeGenFunction r a -> CodeGenFunction r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((T (ptrA, s) -> T s) -> (Value i, T (ptrA, s)) -> (Value i, T s)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (((ptrA, s) -> s) -> T (ptrA, s) -> T s
forall a b. (a -> b) -> T a -> T b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ptrA, s) -> s
forall a b. (a, b) -> b
snd)) (CodeGenFunction r (Value i, T (ptrA, s))
 -> CodeGenFunction r (Value i, T s))
-> CodeGenFunction r (Value i, T (ptrA, s))
-> CodeGenFunction r (Value i, T s)
forall a b. (a -> b) -> a -> b
$
   Value i
-> (ptrA, s)
-> ((ptrA, s) -> T r (T (ptrA, s)) (ptrA, s))
-> CodeGenFunction r (Value i, T (ptrA, s))
forall s i r.
(Phi s, Undefined s, Num i, IsConst i, IsInteger i, CmpRet i,
 IsPrimitive i) =>
Value i
-> s -> (s -> T r (T s) s) -> CodeGenFunction r (Value i, T s)
MaybeCont.fixedLengthLoop Value i
len (ptrA
ptr,s
start) (((ptrA, s) -> T r (T (ptrA, s)) (ptrA, s))
 -> CodeGenFunction r (Value i, T (ptrA, s)))
-> ((ptrA, s) -> T r (T (ptrA, s)) (ptrA, s))
-> CodeGenFunction r (Value i, T (ptrA, s))
forall a b. (a -> b) -> a -> b
$ \(ptrA
ptr0,s
s0) ->
      (ptrA -> s -> (ptrA, s))
-> T r (T (ptrA, s)) ptrA
-> T r (T (ptrA, s)) s
-> T r (T (ptrA, s)) (ptrA, s)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,)
         (CodeGenFunction r ptrA -> T r (T (ptrA, s)) ptrA
forall r a z. CodeGenFunction r a -> T r z a
MaybeCont.lift (CodeGenFunction r ptrA -> T r (T (ptrA, s)) ptrA)
-> CodeGenFunction r ptrA -> T r (T (ptrA, s)) ptrA
forall a b. (a -> b) -> a -> b
$ ptrA -> CodeGenFunction r ptrA
forall a ptr r.
(Storable a, Value (Ptr a) ~ ptr) =>
ptr -> CodeGenFunction r ptr
Storable.incrementPtr ptrA
ptr0)
         (ptrA -> s -> T r z s
body ptrA
ptr0 s
s0)

arrayLoopMaybeCont2 ::
   (Tuple.Phi s, Tuple.Undefined s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i,
    Storable a, Value (Ptr a) ~ ptrA,
    Storable b, Value (Ptr b) ~ ptrB,
    Maybe.T (ptrA, (ptrB, s)) ~ z) =>
   Value i ->
   ptrA -> ptrB -> s ->
   (ptrA -> ptrB -> s -> MaybeCont.T r z s) ->
   CodeGenFunction r (Value i, Maybe.T s)
arrayLoopMaybeCont2 :: forall s i a ptrA b ptrB z r.
(Phi s, Undefined s, Num i, IsConst i, IsInteger i, CmpRet i,
 IsPrimitive i, Storable a, Value (Ptr a) ~ ptrA, Storable b,
 Value (Ptr b) ~ ptrB, T (ptrA, (ptrB, s)) ~ z) =>
Value i
-> ptrA
-> ptrB
-> s
-> (ptrA -> ptrB -> s -> T r z s)
-> CodeGenFunction r (Value i, T s)
arrayLoopMaybeCont2 Value i
len ptrA
ptrA ptrB
ptrB s
start ptrA -> ptrB -> s -> T r z s
body =
   ((Value i, T (ptrB, s)) -> (Value i, T s))
-> CodeGenFunction r (Value i, T (ptrB, s))
-> CodeGenFunction r (Value i, T s)
forall a b. (a -> b) -> CodeGenFunction r a -> CodeGenFunction r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((T (ptrB, s) -> T s) -> (Value i, T (ptrB, s)) -> (Value i, T s)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (((ptrB, s) -> s) -> T (ptrB, s) -> T s
forall a b. (a -> b) -> T a -> T b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ptrB, s) -> s
forall a b. (a, b) -> b
snd)) (CodeGenFunction r (Value i, T (ptrB, s))
 -> CodeGenFunction r (Value i, T s))
-> CodeGenFunction r (Value i, T (ptrB, s))
-> CodeGenFunction r (Value i, T s)
forall a b. (a -> b) -> a -> b
$
   Value i
-> ptrA
-> (ptrB, s)
-> (ptrA -> (ptrB, s) -> T r z (ptrB, s))
-> CodeGenFunction r (Value i, T (ptrB, s))
forall s i a ptrA z r.
(Phi s, Undefined s, Num i, IsConst i, IsInteger i, CmpRet i,
 IsPrimitive i, Storable a, Value (Ptr a) ~ ptrA,
 T (ptrA, s) ~ z) =>
Value i
-> ptrA
-> s
-> (ptrA -> s -> T r z s)
-> CodeGenFunction r (Value i, T s)
arrayLoopMaybeCont Value i
len ptrA
ptrA (ptrB
ptrB,s
start) ((ptrA -> (ptrB, s) -> T r z (ptrB, s))
 -> CodeGenFunction r (Value i, T (ptrB, s)))
-> (ptrA -> (ptrB, s) -> T r z (ptrB, s))
-> CodeGenFunction r (Value i, T (ptrB, s))
forall a b. (a -> b) -> a -> b
$ \ptrA
ptrAi (ptrB
ptrB0,s
s0) ->
      (ptrB -> s -> (ptrB, s))
-> T r z ptrB -> T r z s -> T r z (ptrB, s)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,)
         (CodeGenFunction r ptrB -> T r z ptrB
forall r a z. CodeGenFunction r a -> T r z a
MaybeCont.lift (CodeGenFunction r ptrB -> T r z ptrB)
-> CodeGenFunction r ptrB -> T r z ptrB
forall a b. (a -> b) -> a -> b
$ ptrB -> CodeGenFunction r ptrB
forall a ptr r.
(Storable a, Value (Ptr a) ~ ptr) =>
ptr -> CodeGenFunction r ptr
Storable.incrementPtr ptrB
ptrB0)
         (ptrA -> ptrB -> s -> T r z s
body ptrA
ptrAi ptrB
ptrB0 s
s0)