module LLVM.Internal.BasicBlock where

import LLVM.Prelude

import Control.Monad.Trans
import Foreign.Ptr

import qualified LLVM.Internal.FFI.PtrHierarchy as FFI
import qualified LLVM.Internal.FFI.BasicBlock as FFI
import qualified LLVM.Internal.FFI.Iterate as FFI

import LLVM.Internal.DecodeAST
import LLVM.Internal.Coding
import LLVM.Internal.Instruction ()

import qualified LLVM.AST.Instruction as A

getBasicBlockTerminator :: Ptr FFI.BasicBlock -> DecodeAST (DecodeAST (A.Named A.Terminator))
getBasicBlockTerminator :: Ptr BasicBlock -> DecodeAST (DecodeAST (Named Terminator))
getBasicBlockTerminator = Ptr Instruction -> DecodeAST (DecodeAST (Named Terminator))
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (Ptr Instruction -> DecodeAST (DecodeAST (Named Terminator)))
-> (Ptr BasicBlock -> DecodeAST (Ptr Instruction))
-> Ptr BasicBlock
-> DecodeAST (DecodeAST (Named Terminator))
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (IO (Ptr Instruction) -> DecodeAST (Ptr Instruction)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr Instruction) -> DecodeAST (Ptr Instruction))
-> (Ptr BasicBlock -> IO (Ptr Instruction))
-> Ptr BasicBlock
-> DecodeAST (Ptr Instruction)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr BasicBlock -> IO (Ptr Instruction)
FFI.getBasicBlockTerminator)

getNamedInstructions :: Ptr FFI.BasicBlock -> DecodeAST (DecodeAST [A.Named A.Instruction])
getNamedInstructions :: Ptr BasicBlock -> DecodeAST (DecodeAST [Named Instruction])
getNamedInstructions b :: Ptr BasicBlock
b = do
  [Ptr Instruction]
ffiInstructions <- IO [Ptr Instruction] -> DecodeAST [Ptr Instruction]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Ptr Instruction] -> DecodeAST [Ptr Instruction])
-> IO [Ptr Instruction] -> DecodeAST [Ptr Instruction]
forall a b. (a -> b) -> a -> b
$ IO (Ptr Instruction)
-> (Ptr Instruction -> IO (Ptr Instruction))
-> IO [Ptr Instruction]
forall a. IO (Ptr a) -> (Ptr a -> IO (Ptr a)) -> IO [Ptr a]
FFI.getXs (Ptr BasicBlock -> IO (Ptr Instruction)
FFI.getFirstInstruction Ptr BasicBlock
b) Ptr Instruction -> IO (Ptr Instruction)
FFI.getNextInstruction
  let n :: Int
n = [Ptr Instruction] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ptr Instruction]
ffiInstructions
  ([DecodeAST (Named Instruction)] -> DecodeAST [Named Instruction])
-> DecodeAST [DecodeAST (Named Instruction)]
-> DecodeAST (DecodeAST [Named Instruction])
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM [DecodeAST (Named Instruction)] -> DecodeAST [Named Instruction]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence (DecodeAST [DecodeAST (Named Instruction)]
 -> DecodeAST (DecodeAST [Named Instruction]))
-> ((Ptr Instruction -> DecodeAST (DecodeAST (Named Instruction)))
    -> DecodeAST [DecodeAST (Named Instruction)])
-> (Ptr Instruction -> DecodeAST (DecodeAST (Named Instruction)))
-> DecodeAST (DecodeAST [Named Instruction])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Ptr Instruction]
-> (Ptr Instruction -> DecodeAST (DecodeAST (Named Instruction)))
-> DecodeAST [DecodeAST (Named Instruction)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (Int -> [Ptr Instruction] -> [Ptr Instruction]
forall a. Int -> [a] -> [a]
take (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-1) [Ptr Instruction]
ffiInstructions) ((Ptr Instruction -> DecodeAST (DecodeAST (Named Instruction)))
 -> DecodeAST (DecodeAST [Named Instruction]))
-> (Ptr Instruction -> DecodeAST (DecodeAST (Named Instruction)))
-> DecodeAST (DecodeAST [Named Instruction])
forall a b. (a -> b) -> a -> b
$ Ptr Instruction -> DecodeAST (DecodeAST (Named Instruction))
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM