{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE UndecidableInstances #-}

{- | High level representation of a JVM instruction, with type-safe arguments and no stack manipulation needed.
This is not a 1-1 mapping to the actual instructions, use "H2JVM.Internal.Raw.Instruction" for that.
Instead, this includes some conveniences like the 'Label' instruction to avoid manually dealing with jump offsets.
-}
module H2JVM.Instruction (
    Instruction,
    Instruction' (..),
    LDCEntry (..),
    IfCond (..),
    jumpTarget,
    ldcEntryToFieldType,
)
where

import Data.Data (Data)
import Data.Text (Text)
import GHC.Generics (Generic)

import H2JVM.Builder.Label (Label)
import H2JVM.ConstantPool
import H2JVM.Descriptor
import H2JVM.Internal.Pretty
import H2JVM.Internal.Raw.Instruction ()
import H2JVM.Internal.Raw.Types
import H2JVM.Type

{- | An instruction whose labels are the 'Label' type.
This is probably the type you want.
-}
type Instruction = Instruction' Label

-- | An instruction with a polymorphic label type.
data Instruction' label
    = -- | @aload_<n>@
      ALoad U2
    | -- | @astore_<n>@
      AStore U2
    | AReturn
    | AConstNull
    | Dup
    | IAnd
    | -- | Encodes @if_<cond>@
      If (IfCond label)
    | Instanceof ClassInfoType
    | InvokeStatic ClassInfoType Text MethodDescriptor
    | InvokeInterface ClassInfoType Text MethodDescriptor
    | InvokeVirtual ClassInfoType Text MethodDescriptor
    | InvokeDynamic BootstrapMethod Text MethodDescriptor
    | InvokeSpecial ClassInfoType Text MethodDescriptor
    | IOr
    | ILoad U2
    | IStore U2
    | Label label
    | LDC LDCEntry
    | PutStatic ClassInfoType Text FieldType
    | GetField ClassInfoType Text FieldType
    | GetStatic ClassInfoType Text FieldType
    | PutField ClassInfoType Text FieldType
    | Goto label
    | CheckCast ClassInfoType
    | Return
    | IReturn
    | IConst0
    | IConst1
    | New ClassInfoType
    | ArrayLength
    | AALoad
    | -- | Encodes @if_icmp<cond>@
      IfICmp (IfCond label)
    | IAdd
    | ISub
    | IMul
    | IDiv
    deriving (Typeable (Instruction' label)
Typeable (Instruction' label) =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g)
 -> Instruction' label
 -> c (Instruction' label))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Instruction' label))
-> (Instruction' label -> Constr)
-> (Instruction' label -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Instruction' label)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Instruction' label)))
-> ((forall b. Data b => b -> b)
    -> Instruction' label -> Instruction' label)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Instruction' label -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Instruction' label -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> Instruction' label -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> Instruction' label -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> Instruction' label -> m (Instruction' label))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> Instruction' label -> m (Instruction' label))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> Instruction' label -> m (Instruction' label))
-> Data (Instruction' label)
Instruction' label -> Constr
Instruction' label -> DataType
(forall b. Data b => b -> b)
-> Instruction' label -> Instruction' label
forall label. Data label => Typeable (Instruction' label)
forall label. Data label => Instruction' label -> Constr
forall label. Data label => Instruction' label -> DataType
forall label.
Data label =>
(forall b. Data b => b -> b)
-> Instruction' label -> Instruction' label
forall label u.
Data label =>
Int -> (forall d. Data d => d -> u) -> Instruction' label -> u
forall label u.
Data label =>
(forall d. Data d => d -> u) -> Instruction' label -> [u]
forall label r r'.
Data label =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Instruction' label -> r
forall label r r'.
Data label =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Instruction' label -> r
forall label (m :: * -> *).
(Data label, Monad m) =>
(forall d. Data d => d -> m d)
-> Instruction' label -> m (Instruction' label)
forall label (m :: * -> *).
(Data label, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> Instruction' label -> m (Instruction' label)
forall label (c :: * -> *).
Data label =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Instruction' label)
forall label (c :: * -> *).
Data label =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> Instruction' label
-> c (Instruction' label)
forall label (t :: * -> *) (c :: * -> *).
(Data label, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Instruction' label))
forall label (t :: * -> * -> *) (c :: * -> *).
(Data label, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Instruction' label))
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> Instruction' label -> u
forall u. (forall d. Data d => d -> u) -> Instruction' label -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Instruction' label -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Instruction' label -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> Instruction' label -> m (Instruction' label)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> Instruction' label -> m (Instruction' label)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Instruction' label)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> Instruction' label
-> c (Instruction' label)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Instruction' label))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Instruction' label))
$cgfoldl :: forall label (c :: * -> *).
Data label =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> Instruction' label
-> c (Instruction' label)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> Instruction' label
-> c (Instruction' label)
$cgunfold :: forall label (c :: * -> *).
Data label =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Instruction' label)
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Instruction' label)
$ctoConstr :: forall label. Data label => Instruction' label -> Constr
toConstr :: Instruction' label -> Constr
$cdataTypeOf :: forall label. Data label => Instruction' label -> DataType
dataTypeOf :: Instruction' label -> DataType
$cdataCast1 :: forall label (t :: * -> *) (c :: * -> *).
(Data label, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Instruction' label))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Instruction' label))
$cdataCast2 :: forall label (t :: * -> * -> *) (c :: * -> *).
(Data label, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Instruction' label))
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Instruction' label))
$cgmapT :: forall label.
Data label =>
(forall b. Data b => b -> b)
-> Instruction' label -> Instruction' label
gmapT :: (forall b. Data b => b -> b)
-> Instruction' label -> Instruction' label
$cgmapQl :: forall label r r'.
Data label =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Instruction' label -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Instruction' label -> r
$cgmapQr :: forall label r r'.
Data label =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Instruction' label -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Instruction' label -> r
$cgmapQ :: forall label u.
Data label =>
(forall d. Data d => d -> u) -> Instruction' label -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Instruction' label -> [u]
$cgmapQi :: forall label u.
Data label =>
Int -> (forall d. Data d => d -> u) -> Instruction' label -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> Instruction' label -> u
$cgmapM :: forall label (m :: * -> *).
(Data label, Monad m) =>
(forall d. Data d => d -> m d)
-> Instruction' label -> m (Instruction' label)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> Instruction' label -> m (Instruction' label)
$cgmapMp :: forall label (m :: * -> *).
(Data label, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> Instruction' label -> m (Instruction' label)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> Instruction' label -> m (Instruction' label)
$cgmapMo :: forall label (m :: * -> *).
(Data label, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> Instruction' label -> m (Instruction' label)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> Instruction' label -> m (Instruction' label)
Data, Instruction' label -> Instruction' label -> Bool
(Instruction' label -> Instruction' label -> Bool)
-> (Instruction' label -> Instruction' label -> Bool)
-> Eq (Instruction' label)
forall label.
Eq label =>
Instruction' label -> Instruction' label -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall label.
Eq label =>
Instruction' label -> Instruction' label -> Bool
== :: Instruction' label -> Instruction' label -> Bool
$c/= :: forall label.
Eq label =>
Instruction' label -> Instruction' label -> Bool
/= :: Instruction' label -> Instruction' label -> Bool
Eq, (forall a b. (a -> b) -> Instruction' a -> Instruction' b)
-> (forall a b. a -> Instruction' b -> Instruction' a)
-> Functor Instruction'
forall a b. a -> Instruction' b -> Instruction' a
forall a b. (a -> b) -> Instruction' a -> Instruction' b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Instruction' a -> Instruction' b
fmap :: forall a b. (a -> b) -> Instruction' a -> Instruction' b
$c<$ :: forall a b. a -> Instruction' b -> Instruction' a
<$ :: forall a b. a -> Instruction' b -> Instruction' a
Functor, (forall x. Instruction' label -> Rep (Instruction' label) x)
-> (forall x. Rep (Instruction' label) x -> Instruction' label)
-> Generic (Instruction' label)
forall x. Rep (Instruction' label) x -> Instruction' label
forall x. Instruction' label -> Rep (Instruction' label) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall label x. Rep (Instruction' label) x -> Instruction' label
forall label x. Instruction' label -> Rep (Instruction' label) x
$cfrom :: forall label x. Instruction' label -> Rep (Instruction' label) x
from :: forall x. Instruction' label -> Rep (Instruction' label) x
$cto :: forall label x. Rep (Instruction' label) x -> Instruction' label
to :: forall x. Rep (Instruction' label) x -> Instruction' label
Generic, Eq (Instruction' label)
Eq (Instruction' label) =>
(Instruction' label -> Instruction' label -> Ordering)
-> (Instruction' label -> Instruction' label -> Bool)
-> (Instruction' label -> Instruction' label -> Bool)
-> (Instruction' label -> Instruction' label -> Bool)
-> (Instruction' label -> Instruction' label -> Bool)
-> (Instruction' label -> Instruction' label -> Instruction' label)
-> (Instruction' label -> Instruction' label -> Instruction' label)
-> Ord (Instruction' label)
Instruction' label -> Instruction' label -> Bool
Instruction' label -> Instruction' label -> Ordering
Instruction' label -> Instruction' label -> Instruction' label
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall label. Ord label => Eq (Instruction' label)
forall label.
Ord label =>
Instruction' label -> Instruction' label -> Bool
forall label.
Ord label =>
Instruction' label -> Instruction' label -> Ordering
forall label.
Ord label =>
Instruction' label -> Instruction' label -> Instruction' label
$ccompare :: forall label.
Ord label =>
Instruction' label -> Instruction' label -> Ordering
compare :: Instruction' label -> Instruction' label -> Ordering
$c< :: forall label.
Ord label =>
Instruction' label -> Instruction' label -> Bool
< :: Instruction' label -> Instruction' label -> Bool
$c<= :: forall label.
Ord label =>
Instruction' label -> Instruction' label -> Bool
<= :: Instruction' label -> Instruction' label -> Bool
$c> :: forall label.
Ord label =>
Instruction' label -> Instruction' label -> Bool
> :: Instruction' label -> Instruction' label -> Bool
$c>= :: forall label.
Ord label =>
Instruction' label -> Instruction' label -> Bool
>= :: Instruction' label -> Instruction' label -> Bool
$cmax :: forall label.
Ord label =>
Instruction' label -> Instruction' label -> Instruction' label
max :: Instruction' label -> Instruction' label -> Instruction' label
$cmin :: forall label.
Ord label =>
Instruction' label -> Instruction' label -> Instruction' label
min :: Instruction' label -> Instruction' label -> Instruction' label
Ord, Int -> Instruction' label -> ShowS
[Instruction' label] -> ShowS
Instruction' label -> String
(Int -> Instruction' label -> ShowS)
-> (Instruction' label -> String)
-> ([Instruction' label] -> ShowS)
-> Show (Instruction' label)
forall label. Show label => Int -> Instruction' label -> ShowS
forall label. Show label => [Instruction' label] -> ShowS
forall label. Show label => Instruction' label -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall label. Show label => Int -> Instruction' label -> ShowS
showsPrec :: Int -> Instruction' label -> ShowS
$cshow :: forall label. Show label => Instruction' label -> String
show :: Instruction' label -> String
$cshowList :: forall label. Show label => [Instruction' label] -> ShowS
showList :: [Instruction' label] -> ShowS
Show)

-- | A condition of an if instruction.
data IfCond label = IfEq label | IfNe label | IfLt label | IfGe label | IfGt label | IfLe label
    deriving (Typeable (IfCond label)
Typeable (IfCond label) =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> IfCond label -> c (IfCond label))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (IfCond label))
-> (IfCond label -> Constr)
-> (IfCond label -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (IfCond label)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (IfCond label)))
-> ((forall b. Data b => b -> b) -> IfCond label -> IfCond label)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> IfCond label -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> IfCond label -> r)
-> (forall u. (forall d. Data d => d -> u) -> IfCond label -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> IfCond label -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label))
-> Data (IfCond label)
IfCond label -> Constr
IfCond label -> DataType
(forall b. Data b => b -> b) -> IfCond label -> IfCond label
forall label. Data label => Typeable (IfCond label)
forall label. Data label => IfCond label -> Constr
forall label. Data label => IfCond label -> DataType
forall label.
Data label =>
(forall b. Data b => b -> b) -> IfCond label -> IfCond label
forall label u.
Data label =>
Int -> (forall d. Data d => d -> u) -> IfCond label -> u
forall label u.
Data label =>
(forall d. Data d => d -> u) -> IfCond label -> [u]
forall label r r'.
Data label =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> IfCond label -> r
forall label r r'.
Data label =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> IfCond label -> r
forall label (m :: * -> *).
(Data label, Monad m) =>
(forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label)
forall label (m :: * -> *).
(Data label, MonadPlus m) =>
(forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label)
forall label (c :: * -> *).
Data label =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (IfCond label)
forall label (c :: * -> *).
Data label =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> IfCond label -> c (IfCond label)
forall label (t :: * -> *) (c :: * -> *).
(Data label, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (IfCond label))
forall label (t :: * -> * -> *) (c :: * -> *).
(Data label, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (IfCond label))
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> IfCond label -> u
forall u. (forall d. Data d => d -> u) -> IfCond label -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> IfCond label -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> IfCond label -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (IfCond label)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> IfCond label -> c (IfCond label)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (IfCond label))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (IfCond label))
$cgfoldl :: forall label (c :: * -> *).
Data label =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> IfCond label -> c (IfCond label)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> IfCond label -> c (IfCond label)
$cgunfold :: forall label (c :: * -> *).
Data label =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (IfCond label)
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (IfCond label)
$ctoConstr :: forall label. Data label => IfCond label -> Constr
toConstr :: IfCond label -> Constr
$cdataTypeOf :: forall label. Data label => IfCond label -> DataType
dataTypeOf :: IfCond label -> DataType
$cdataCast1 :: forall label (t :: * -> *) (c :: * -> *).
(Data label, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (IfCond label))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (IfCond label))
$cdataCast2 :: forall label (t :: * -> * -> *) (c :: * -> *).
(Data label, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (IfCond label))
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (IfCond label))
$cgmapT :: forall label.
Data label =>
(forall b. Data b => b -> b) -> IfCond label -> IfCond label
gmapT :: (forall b. Data b => b -> b) -> IfCond label -> IfCond label
$cgmapQl :: forall label r r'.
Data label =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> IfCond label -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> IfCond label -> r
$cgmapQr :: forall label r r'.
Data label =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> IfCond label -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> IfCond label -> r
$cgmapQ :: forall label u.
Data label =>
(forall d. Data d => d -> u) -> IfCond label -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> IfCond label -> [u]
$cgmapQi :: forall label u.
Data label =>
Int -> (forall d. Data d => d -> u) -> IfCond label -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> IfCond label -> u
$cgmapM :: forall label (m :: * -> *).
(Data label, Monad m) =>
(forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label)
$cgmapMp :: forall label (m :: * -> *).
(Data label, MonadPlus m) =>
(forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label)
$cgmapMo :: forall label (m :: * -> *).
(Data label, MonadPlus m) =>
(forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> IfCond label -> m (IfCond label)
Data, IfCond label -> IfCond label -> Bool
(IfCond label -> IfCond label -> Bool)
-> (IfCond label -> IfCond label -> Bool) -> Eq (IfCond label)
forall label. Eq label => IfCond label -> IfCond label -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall label. Eq label => IfCond label -> IfCond label -> Bool
== :: IfCond label -> IfCond label -> Bool
$c/= :: forall label. Eq label => IfCond label -> IfCond label -> Bool
/= :: IfCond label -> IfCond label -> Bool
Eq, (forall m. Monoid m => IfCond m -> m)
-> (forall m a. Monoid m => (a -> m) -> IfCond a -> m)
-> (forall m a. Monoid m => (a -> m) -> IfCond a -> m)
-> (forall a b. (a -> b -> b) -> b -> IfCond a -> b)
-> (forall a b. (a -> b -> b) -> b -> IfCond a -> b)
-> (forall b a. (b -> a -> b) -> b -> IfCond a -> b)
-> (forall b a. (b -> a -> b) -> b -> IfCond a -> b)
-> (forall a. (a -> a -> a) -> IfCond a -> a)
-> (forall a. (a -> a -> a) -> IfCond a -> a)
-> (forall a. IfCond a -> [a])
-> (forall a. IfCond a -> Bool)
-> (forall a. IfCond a -> Int)
-> (forall a. Eq a => a -> IfCond a -> Bool)
-> (forall a. Ord a => IfCond a -> a)
-> (forall a. Ord a => IfCond a -> a)
-> (forall a. Num a => IfCond a -> a)
-> (forall a. Num a => IfCond a -> a)
-> Foldable IfCond
forall a. Eq a => a -> IfCond a -> Bool
forall a. Num a => IfCond a -> a
forall a. Ord a => IfCond a -> a
forall m. Monoid m => IfCond m -> m
forall a. IfCond a -> Bool
forall a. IfCond a -> Int
forall a. IfCond a -> [a]
forall a. (a -> a -> a) -> IfCond a -> a
forall m a. Monoid m => (a -> m) -> IfCond a -> m
forall b a. (b -> a -> b) -> b -> IfCond a -> b
forall a b. (a -> b -> b) -> b -> IfCond a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => IfCond m -> m
fold :: forall m. Monoid m => IfCond m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> IfCond a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> IfCond a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> IfCond a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> IfCond a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> IfCond a -> b
foldr :: forall a b. (a -> b -> b) -> b -> IfCond a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> IfCond a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> IfCond a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> IfCond a -> b
foldl :: forall b a. (b -> a -> b) -> b -> IfCond a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> IfCond a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> IfCond a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> IfCond a -> a
foldr1 :: forall a. (a -> a -> a) -> IfCond a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> IfCond a -> a
foldl1 :: forall a. (a -> a -> a) -> IfCond a -> a
$ctoList :: forall a. IfCond a -> [a]
toList :: forall a. IfCond a -> [a]
$cnull :: forall a. IfCond a -> Bool
null :: forall a. IfCond a -> Bool
$clength :: forall a. IfCond a -> Int
length :: forall a. IfCond a -> Int
$celem :: forall a. Eq a => a -> IfCond a -> Bool
elem :: forall a. Eq a => a -> IfCond a -> Bool
$cmaximum :: forall a. Ord a => IfCond a -> a
maximum :: forall a. Ord a => IfCond a -> a
$cminimum :: forall a. Ord a => IfCond a -> a
minimum :: forall a. Ord a => IfCond a -> a
$csum :: forall a. Num a => IfCond a -> a
sum :: forall a. Num a => IfCond a -> a
$cproduct :: forall a. Num a => IfCond a -> a
product :: forall a. Num a => IfCond a -> a
Foldable, (forall a b. (a -> b) -> IfCond a -> IfCond b)
-> (forall a b. a -> IfCond b -> IfCond a) -> Functor IfCond
forall a b. a -> IfCond b -> IfCond a
forall a b. (a -> b) -> IfCond a -> IfCond b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> IfCond a -> IfCond b
fmap :: forall a b. (a -> b) -> IfCond a -> IfCond b
$c<$ :: forall a b. a -> IfCond b -> IfCond a
<$ :: forall a b. a -> IfCond b -> IfCond a
Functor, (forall x. IfCond label -> Rep (IfCond label) x)
-> (forall x. Rep (IfCond label) x -> IfCond label)
-> Generic (IfCond label)
forall x. Rep (IfCond label) x -> IfCond label
forall x. IfCond label -> Rep (IfCond label) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall label x. Rep (IfCond label) x -> IfCond label
forall label x. IfCond label -> Rep (IfCond label) x
$cfrom :: forall label x. IfCond label -> Rep (IfCond label) x
from :: forall x. IfCond label -> Rep (IfCond label) x
$cto :: forall label x. Rep (IfCond label) x -> IfCond label
to :: forall x. Rep (IfCond label) x -> IfCond label
Generic, Eq (IfCond label)
Eq (IfCond label) =>
(IfCond label -> IfCond label -> Ordering)
-> (IfCond label -> IfCond label -> Bool)
-> (IfCond label -> IfCond label -> Bool)
-> (IfCond label -> IfCond label -> Bool)
-> (IfCond label -> IfCond label -> Bool)
-> (IfCond label -> IfCond label -> IfCond label)
-> (IfCond label -> IfCond label -> IfCond label)
-> Ord (IfCond label)
IfCond label -> IfCond label -> Bool
IfCond label -> IfCond label -> Ordering
IfCond label -> IfCond label -> IfCond label
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall label. Ord label => Eq (IfCond label)
forall label. Ord label => IfCond label -> IfCond label -> Bool
forall label. Ord label => IfCond label -> IfCond label -> Ordering
forall label.
Ord label =>
IfCond label -> IfCond label -> IfCond label
$ccompare :: forall label. Ord label => IfCond label -> IfCond label -> Ordering
compare :: IfCond label -> IfCond label -> Ordering
$c< :: forall label. Ord label => IfCond label -> IfCond label -> Bool
< :: IfCond label -> IfCond label -> Bool
$c<= :: forall label. Ord label => IfCond label -> IfCond label -> Bool
<= :: IfCond label -> IfCond label -> Bool
$c> :: forall label. Ord label => IfCond label -> IfCond label -> Bool
> :: IfCond label -> IfCond label -> Bool
$c>= :: forall label. Ord label => IfCond label -> IfCond label -> Bool
>= :: IfCond label -> IfCond label -> Bool
$cmax :: forall label.
Ord label =>
IfCond label -> IfCond label -> IfCond label
max :: IfCond label -> IfCond label -> IfCond label
$cmin :: forall label.
Ord label =>
IfCond label -> IfCond label -> IfCond label
min :: IfCond label -> IfCond label -> IfCond label
Ord, Int -> IfCond label -> ShowS
[IfCond label] -> ShowS
IfCond label -> String
(Int -> IfCond label -> ShowS)
-> (IfCond label -> String)
-> ([IfCond label] -> ShowS)
-> Show (IfCond label)
forall label. Show label => Int -> IfCond label -> ShowS
forall label. Show label => [IfCond label] -> ShowS
forall label. Show label => IfCond label -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall label. Show label => Int -> IfCond label -> ShowS
showsPrec :: Int -> IfCond label -> ShowS
$cshow :: forall label. Show label => IfCond label -> String
show :: IfCond label -> String
$cshowList :: forall label. Show label => [IfCond label] -> ShowS
showList :: [IfCond label] -> ShowS
Show, Functor IfCond
Foldable IfCond
(Functor IfCond, Foldable IfCond) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> IfCond a -> f (IfCond b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    IfCond (f a) -> f (IfCond a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> IfCond a -> m (IfCond b))
-> (forall (m :: * -> *) a.
    Monad m =>
    IfCond (m a) -> m (IfCond a))
-> Traversable IfCond
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => IfCond (m a) -> m (IfCond a)
forall (f :: * -> *) a.
Applicative f =>
IfCond (f a) -> f (IfCond a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> IfCond a -> m (IfCond b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> IfCond a -> f (IfCond b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> IfCond a -> f (IfCond b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> IfCond a -> f (IfCond b)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
IfCond (f a) -> f (IfCond a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
IfCond (f a) -> f (IfCond a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> IfCond a -> m (IfCond b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> IfCond a -> m (IfCond b)
$csequence :: forall (m :: * -> *) a. Monad m => IfCond (m a) -> m (IfCond a)
sequence :: forall (m :: * -> *) a. Monad m => IfCond (m a) -> m (IfCond a)
Traversable)

instance Pretty label => Pretty (IfCond label) where
    pretty :: forall ann. IfCond label -> Doc ann
pretty (IfEq label
l) = Doc ann
"ifeq" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> label -> Doc ann
forall ann. label -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty label
l
    pretty (IfNe label
l) = Doc ann
"ifne" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> label -> Doc ann
forall ann. label -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty label
l
    pretty (IfLt label
l) = Doc ann
"iflt" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> label -> Doc ann
forall ann. label -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty label
l
    pretty (IfGe label
l) = Doc ann
"ifge" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> label -> Doc ann
forall ann. label -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty label
l
    pretty (IfGt label
l) = Doc ann
"ifgt" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> label -> Doc ann
forall ann. label -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty label
l
    pretty (IfLe label
l) = Doc ann
"ifle" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> label -> Doc ann
forall ann. label -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty label
l

instance Pretty label => Pretty (Instruction' label) where
    pretty :: forall ann. Instruction' label -> Doc ann
pretty Instruction' label
AALoad = Doc ann
"aaload"
    pretty Instruction' label
ArrayLength = Doc ann
"arraylength"
    pretty (ALoad U2
x) = Doc ann
"aload" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> U2 -> Doc ann
forall ann. U2 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty U2
x
    pretty (AStore U2
x) = Doc ann
"astore" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> U2 -> Doc ann
forall ann. U2 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty U2
x
    pretty Instruction' label
AReturn = Doc ann
"areturn"
    pretty Instruction' label
AConstNull = Doc ann
"aconst_null"
    pretty Instruction' label
Dup = Doc ann
"dup"
    pretty Instruction' label
IAnd = Doc ann
"iand"
    pretty (If IfCond label
cond) = Doc ann
"if" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> IfCond label -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. IfCond label -> Doc ann
pretty IfCond label
cond
    pretty (Instanceof ClassInfoType
c) = Doc ann
"instanceof" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
c
    pretty (InvokeStatic ClassInfoType
c Text
n MethodDescriptor
d) = Doc ann
"invokestatic" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
c Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"." Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
n Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> MethodDescriptor -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. MethodDescriptor -> Doc ann
pretty MethodDescriptor
d
    pretty (InvokeInterface ClassInfoType
c Text
n MethodDescriptor
d) = Doc ann
"invokeinterface" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
c Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"." Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
n Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> MethodDescriptor -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. MethodDescriptor -> Doc ann
pretty MethodDescriptor
d
    pretty (InvokeVirtual ClassInfoType
c Text
n MethodDescriptor
d) = Doc ann
"invokevirtual" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
c Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"." Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
n Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> MethodDescriptor -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. MethodDescriptor -> Doc ann
pretty MethodDescriptor
d
    pretty (InvokeDynamic BootstrapMethod
b Text
n MethodDescriptor
d) = Doc ann
"invokedynamic" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> BootstrapMethod -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. BootstrapMethod -> Doc ann
pretty BootstrapMethod
b Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"." Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
n Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> MethodDescriptor -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. MethodDescriptor -> Doc ann
pretty MethodDescriptor
d
    pretty (InvokeSpecial ClassInfoType
c Text
n MethodDescriptor
d) = Doc ann
"invokespecial" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
c Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"." Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
n Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> MethodDescriptor -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. MethodDescriptor -> Doc ann
pretty MethodDescriptor
d
    pretty Instruction' label
IOr = Doc ann
"ior"
    pretty (ILoad U2
x) = Doc ann
"iload" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> U2 -> Doc ann
forall ann. U2 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty U2
x
    pretty (IStore U2
x) = Doc ann
"istore" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> U2 -> Doc ann
forall ann. U2 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty U2
x
    pretty (Label label
l) = Doc ann
":" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> label -> Doc ann
forall ann. label -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty label
l
    pretty (LDC LDCEntry
x) = Doc ann
"ldc" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> LDCEntry -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. LDCEntry -> Doc ann
pretty LDCEntry
x
    pretty (PutStatic ClassInfoType
c Text
n FieldType
t) = Doc ann
"putstatic" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
c Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"." Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
n Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FieldType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FieldType -> Doc ann
pretty FieldType
t
    pretty (GetField ClassInfoType
c Text
n FieldType
t) = Doc ann
"getfield" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
c Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"." Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
n Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FieldType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FieldType -> Doc ann
pretty FieldType
t
    pretty (GetStatic ClassInfoType
c Text
n FieldType
t) = Doc ann
"getstatic" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
c Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"." Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
n Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FieldType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FieldType -> Doc ann
pretty FieldType
t
    pretty (PutField ClassInfoType
c Text
n FieldType
t) = Doc ann
"putfield" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
c Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"." Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
n Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FieldType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FieldType -> Doc ann
pretty FieldType
t
    pretty (Goto label
l) = Doc ann
"goto" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> label -> Doc ann
forall ann. label -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty label
l
    pretty (CheckCast ClassInfoType
c) = Doc ann
"checkcast" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
c
    pretty Instruction' label
Return = Doc ann
"return"
    pretty Instruction' label
IReturn = Doc ann
"ireturn"
    pretty Instruction' label
IConst0 = Doc ann
"iconst_0"
    pretty Instruction' label
IConst1 = Doc ann
"iconst_1"
    pretty (New ClassInfoType
c) = Doc ann
"new" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
c
    pretty (IfICmp IfCond label
cmp) = Doc ann
"if_icmp" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> IfCond label -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. IfCond label -> Doc ann
pretty IfCond label
cmp
    pretty Instruction' label
IAdd = Doc ann
"iadd"
    pretty Instruction' label
ISub = Doc ann
"isub"
    pretty Instruction' label
IMul = Doc ann
"imul"
    pretty Instruction' label
IDiv = Doc ann
"idiv"

-- | The jump target of an instruction, if it is a jump instruction.
jumpTarget :: Instruction' label -> Maybe label
jumpTarget :: forall label. Instruction' label -> Maybe label
jumpTarget (If IfCond label
cond) = label -> Maybe label
forall a. a -> Maybe a
Just (label -> Maybe label) -> label -> Maybe label
forall a b. (a -> b) -> a -> b
$ IfCond label -> label
forall label. IfCond label -> label
condJumpTarget IfCond label
cond
jumpTarget (Goto label
l) = label -> Maybe label
forall a. a -> Maybe a
Just label
l
jumpTarget (IfICmp IfCond label
cond) = label -> Maybe label
forall a. a -> Maybe a
Just (label -> Maybe label) -> label -> Maybe label
forall a b. (a -> b) -> a -> b
$ IfCond label -> label
forall label. IfCond label -> label
condJumpTarget IfCond label
cond
jumpTarget Instruction' label
_ = Maybe label
forall a. Maybe a
Nothing

condJumpTarget :: IfCond label -> label
condJumpTarget :: forall label. IfCond label -> label
condJumpTarget = \case
    IfEq label
l -> label
l
    IfNe label
l -> label
l
    IfLt label
l -> label
l
    IfGe label
l -> label
l
    IfGt label
l -> label
l
    IfLe label
l -> label
l

-- | A value that can be loaded by the 'LDC' instruction.
data LDCEntry
    = -- | Load an integer constant.
      LDCInt JVMInt
    | -- | Load a float constant.
      LDCFloat Float
    | -- | Load a string constant.
      LDCString Text
    | -- | Load a Class object.
      LDCClass ClassInfoType
    deriving (Typeable LDCEntry
Typeable LDCEntry =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> LDCEntry -> c LDCEntry)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c LDCEntry)
-> (LDCEntry -> Constr)
-> (LDCEntry -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c LDCEntry))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LDCEntry))
-> ((forall b. Data b => b -> b) -> LDCEntry -> LDCEntry)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> LDCEntry -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> LDCEntry -> r)
-> (forall u. (forall d. Data d => d -> u) -> LDCEntry -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> LDCEntry -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> LDCEntry -> m LDCEntry)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> LDCEntry -> m LDCEntry)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> LDCEntry -> m LDCEntry)
-> Data LDCEntry
LDCEntry -> Constr
LDCEntry -> DataType
(forall b. Data b => b -> b) -> LDCEntry -> LDCEntry
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> LDCEntry -> u
forall u. (forall d. Data d => d -> u) -> LDCEntry -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LDCEntry -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LDCEntry -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> LDCEntry -> m LDCEntry
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LDCEntry -> m LDCEntry
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LDCEntry
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LDCEntry -> c LDCEntry
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LDCEntry)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LDCEntry)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LDCEntry -> c LDCEntry
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LDCEntry -> c LDCEntry
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LDCEntry
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LDCEntry
$ctoConstr :: LDCEntry -> Constr
toConstr :: LDCEntry -> Constr
$cdataTypeOf :: LDCEntry -> DataType
dataTypeOf :: LDCEntry -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LDCEntry)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LDCEntry)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LDCEntry)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LDCEntry)
$cgmapT :: (forall b. Data b => b -> b) -> LDCEntry -> LDCEntry
gmapT :: (forall b. Data b => b -> b) -> LDCEntry -> LDCEntry
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LDCEntry -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LDCEntry -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LDCEntry -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LDCEntry -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> LDCEntry -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> LDCEntry -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> LDCEntry -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> LDCEntry -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> LDCEntry -> m LDCEntry
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> LDCEntry -> m LDCEntry
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LDCEntry -> m LDCEntry
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LDCEntry -> m LDCEntry
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LDCEntry -> m LDCEntry
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LDCEntry -> m LDCEntry
Data, LDCEntry -> LDCEntry -> Bool
(LDCEntry -> LDCEntry -> Bool)
-> (LDCEntry -> LDCEntry -> Bool) -> Eq LDCEntry
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LDCEntry -> LDCEntry -> Bool
== :: LDCEntry -> LDCEntry -> Bool
$c/= :: LDCEntry -> LDCEntry -> Bool
/= :: LDCEntry -> LDCEntry -> Bool
Eq, (forall x. LDCEntry -> Rep LDCEntry x)
-> (forall x. Rep LDCEntry x -> LDCEntry) -> Generic LDCEntry
forall x. Rep LDCEntry x -> LDCEntry
forall x. LDCEntry -> Rep LDCEntry x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. LDCEntry -> Rep LDCEntry x
from :: forall x. LDCEntry -> Rep LDCEntry x
$cto :: forall x. Rep LDCEntry x -> LDCEntry
to :: forall x. Rep LDCEntry x -> LDCEntry
Generic, Eq LDCEntry
Eq LDCEntry =>
(LDCEntry -> LDCEntry -> Ordering)
-> (LDCEntry -> LDCEntry -> Bool)
-> (LDCEntry -> LDCEntry -> Bool)
-> (LDCEntry -> LDCEntry -> Bool)
-> (LDCEntry -> LDCEntry -> Bool)
-> (LDCEntry -> LDCEntry -> LDCEntry)
-> (LDCEntry -> LDCEntry -> LDCEntry)
-> Ord LDCEntry
LDCEntry -> LDCEntry -> Bool
LDCEntry -> LDCEntry -> Ordering
LDCEntry -> LDCEntry -> LDCEntry
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: LDCEntry -> LDCEntry -> Ordering
compare :: LDCEntry -> LDCEntry -> Ordering
$c< :: LDCEntry -> LDCEntry -> Bool
< :: LDCEntry -> LDCEntry -> Bool
$c<= :: LDCEntry -> LDCEntry -> Bool
<= :: LDCEntry -> LDCEntry -> Bool
$c> :: LDCEntry -> LDCEntry -> Bool
> :: LDCEntry -> LDCEntry -> Bool
$c>= :: LDCEntry -> LDCEntry -> Bool
>= :: LDCEntry -> LDCEntry -> Bool
$cmax :: LDCEntry -> LDCEntry -> LDCEntry
max :: LDCEntry -> LDCEntry -> LDCEntry
$cmin :: LDCEntry -> LDCEntry -> LDCEntry
min :: LDCEntry -> LDCEntry -> LDCEntry
Ord, Int -> LDCEntry -> ShowS
[LDCEntry] -> ShowS
LDCEntry -> String
(Int -> LDCEntry -> ShowS)
-> (LDCEntry -> String) -> ([LDCEntry] -> ShowS) -> Show LDCEntry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LDCEntry -> ShowS
showsPrec :: Int -> LDCEntry -> ShowS
$cshow :: LDCEntry -> String
show :: LDCEntry -> String
$cshowList :: [LDCEntry] -> ShowS
showList :: [LDCEntry] -> ShowS
Show)

instance Pretty LDCEntry where
    pretty :: forall ann. LDCEntry -> Doc ann
pretty (LDCInt JVMInt
x) = JVMInt -> Doc ann
forall ann. JVMInt -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty JVMInt
x
    pretty (LDCFloat Float
x) = Float -> Doc ann
forall ann. Float -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Float
x
    pretty (LDCString Text
x) = Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
x
    pretty (LDCClass ClassInfoType
x) = ClassInfoType -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ClassInfoType -> Doc ann
pretty ClassInfoType
x

-- | Convert an 'LDCEntry to a 'FieldType.
ldcEntryToFieldType :: LDCEntry -> FieldType
ldcEntryToFieldType :: LDCEntry -> FieldType
ldcEntryToFieldType (LDCInt JVMInt
_) = PrimitiveType -> FieldType
PrimitiveFieldType PrimitiveType
JInt
ldcEntryToFieldType (LDCFloat Float
_) = PrimitiveType -> FieldType
PrimitiveFieldType PrimitiveType
JFloat
ldcEntryToFieldType (LDCString Text
_) = QualifiedClassName -> FieldType
ObjectFieldType QualifiedClassName
"java/lang/String"
ldcEntryToFieldType (LDCClass (ClassInfoType QualifiedClassName
x)) = QualifiedClassName -> FieldType
ObjectFieldType QualifiedClassName
x
ldcEntryToFieldType (LDCClass (ArrayClassInfoType ClassInfoType
x)) = FieldType -> FieldType
ArrayFieldType (FieldType -> FieldType) -> FieldType -> FieldType
forall a b. (a -> b) -> a -> b
$ LDCEntry -> FieldType
ldcEntryToFieldType (LDCEntry -> FieldType) -> LDCEntry -> FieldType
forall a b. (a -> b) -> a -> b
$ ClassInfoType -> LDCEntry
LDCClass ClassInfoType
x
ldcEntryToFieldType (LDCClass (PrimitiveClassInfoType PrimitiveType
x)) = PrimitiveType -> FieldType
PrimitiveFieldType PrimitiveType
x