-- SPDX-FileCopyrightText: 2021 Oxhead Alpha
-- SPDX-License-Identifier: LicenseRef-MIT-OA

-- | Michelson instructions in untyped model.

module Morley.Michelson.Untyped.Instr
  ( InstrAbstract (..)
  , ExpandedOp (..)
  , ExpandedInstr
  , flattenExpandedOp
  ) where

import Prelude hiding (EQ, GT, LT, group)

import Data.Aeson.TH (deriveJSON)
import Data.Aeson.Types
  (FromJSON(..), ToJSON(..), genericParseJSON, genericToEncoding, genericToJSON)
import Data.Data (Data(..))
import Fmt (Buildable(build), Doc, isEmpty, (+|), (<+>), (|+))
import Generics.SYB (everywhere, mkT)
import Prettyprinter (align, braces, enclose, group, space)
import Prettyprinter qualified as PP

import Morley.Michelson.ErrorPos (ErrorSrcPos)
import Morley.Michelson.Printer.Util (RenderDoc(..), doesntNeedParens, needsParens, renderOpsList)
import Morley.Michelson.Untyped.Annotation
  (Annotation, AnyAnn, FieldAnn, KnownAnnTag, TypeAnn, VarAnn, fullAnnSet, renderAnyAnns,
  singleAnnSet)
import Morley.Michelson.Untyped.Contract (Contract'(..))
import Morley.Michelson.Untyped.Ext
import Morley.Michelson.Untyped.HoistInstr
import Morley.Michelson.Untyped.Type (Ty)
import Morley.Michelson.Untyped.Value (Value'(..))
import Morley.Michelson.Untyped.View
import Morley.Util.Aeson

-------------------------------------
-- Types after macroexpander
-------------------------------------

type ExpandedInstr = InstrAbstract [] ExpandedOp

data ExpandedOp
  = PrimEx ExpandedInstr
  | SeqEx [ExpandedOp]
  | WithSrcEx ErrorSrcPos ExpandedOp
  deriving stock (Int -> ExpandedOp -> ShowS
[ExpandedOp] -> ShowS
ExpandedOp -> String
(Int -> ExpandedOp -> ShowS)
-> (ExpandedOp -> String)
-> ([ExpandedOp] -> ShowS)
-> Show ExpandedOp
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ExpandedOp -> ShowS
showsPrec :: Int -> ExpandedOp -> ShowS
$cshow :: ExpandedOp -> String
show :: ExpandedOp -> String
$cshowList :: [ExpandedOp] -> ShowS
showList :: [ExpandedOp] -> ShowS
Show, ExpandedOp -> ExpandedOp -> Bool
(ExpandedOp -> ExpandedOp -> Bool)
-> (ExpandedOp -> ExpandedOp -> Bool) -> Eq ExpandedOp
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ExpandedOp -> ExpandedOp -> Bool
== :: ExpandedOp -> ExpandedOp -> Bool
$c/= :: ExpandedOp -> ExpandedOp -> Bool
/= :: ExpandedOp -> ExpandedOp -> Bool
Eq, Typeable ExpandedOp
Typeable ExpandedOp
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ExpandedOp -> c ExpandedOp)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ExpandedOp)
-> (ExpandedOp -> Constr)
-> (ExpandedOp -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ExpandedOp))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ExpandedOp))
-> ((forall b. Data b => b -> b) -> ExpandedOp -> ExpandedOp)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ExpandedOp -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ExpandedOp -> r)
-> (forall u. (forall d. Data d => d -> u) -> ExpandedOp -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ExpandedOp -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ExpandedOp -> m ExpandedOp)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ExpandedOp -> m ExpandedOp)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ExpandedOp -> m ExpandedOp)
-> Data ExpandedOp
ExpandedOp -> Constr
ExpandedOp -> DataType
(forall b. Data b => b -> b) -> ExpandedOp -> ExpandedOp
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) -> ExpandedOp -> u
forall u. (forall d. Data d => d -> u) -> ExpandedOp -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ExpandedOp -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ExpandedOp -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ExpandedOp -> m ExpandedOp
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExpandedOp -> m ExpandedOp
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ExpandedOp
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ExpandedOp -> c ExpandedOp
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ExpandedOp)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ExpandedOp)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ExpandedOp -> c ExpandedOp
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ExpandedOp -> c ExpandedOp
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ExpandedOp
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ExpandedOp
$ctoConstr :: ExpandedOp -> Constr
toConstr :: ExpandedOp -> Constr
$cdataTypeOf :: ExpandedOp -> DataType
dataTypeOf :: ExpandedOp -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ExpandedOp)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ExpandedOp)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ExpandedOp)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ExpandedOp)
$cgmapT :: (forall b. Data b => b -> b) -> ExpandedOp -> ExpandedOp
gmapT :: (forall b. Data b => b -> b) -> ExpandedOp -> ExpandedOp
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ExpandedOp -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ExpandedOp -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ExpandedOp -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ExpandedOp -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ExpandedOp -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> ExpandedOp -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ExpandedOp -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ExpandedOp -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ExpandedOp -> m ExpandedOp
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ExpandedOp -> m ExpandedOp
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExpandedOp -> m ExpandedOp
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExpandedOp -> m ExpandedOp
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExpandedOp -> m ExpandedOp
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExpandedOp -> m ExpandedOp
Data, (forall x. ExpandedOp -> Rep ExpandedOp x)
-> (forall x. Rep ExpandedOp x -> ExpandedOp) -> Generic ExpandedOp
forall x. Rep ExpandedOp x -> ExpandedOp
forall x. ExpandedOp -> Rep ExpandedOp x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ExpandedOp -> Rep ExpandedOp x
from :: forall x. ExpandedOp -> Rep ExpandedOp x
$cto :: forall x. Rep ExpandedOp x -> ExpandedOp
to :: forall x. Rep ExpandedOp x -> ExpandedOp
Generic)

instance NFData ExpandedOp

instance RenderDoc ExpandedOp where
  renderDoc :: RenderContext -> ExpandedOp -> Doc
renderDoc RenderContext
pn (WithSrcEx ErrorSrcPos
_ ExpandedOp
op) = RenderContext -> ExpandedOp -> Doc
forall a. RenderDoc a => RenderContext -> a -> Doc
renderDoc RenderContext
pn ExpandedOp
op
  renderDoc RenderContext
pn (PrimEx ExpandedInstr
i) = RenderContext -> ExpandedInstr -> Doc
forall a. RenderDoc a => RenderContext -> a -> Doc
renderDoc RenderContext
pn ExpandedInstr
i
  renderDoc RenderContext
_  (SeqEx [ExpandedOp]
i) = Bool -> [ExpandedOp] -> Doc
forall op (f :: * -> *).
(RenderDoc op, Foldable f) =>
Bool -> f op -> Doc
renderOpsList Bool
False [ExpandedOp]
i
  isRenderable :: ExpandedOp -> Bool
isRenderable =
    \case PrimEx ExpandedInstr
i -> ExpandedInstr -> Bool
forall a. RenderDoc a => a -> Bool
isRenderable ExpandedInstr
i
          WithSrcEx ErrorSrcPos
_ ExpandedOp
op -> ExpandedOp -> Bool
forall a. RenderDoc a => a -> Bool
isRenderable ExpandedOp
op
          ExpandedOp
_ -> Bool
True

instance Buildable ExpandedOp where
  build :: ExpandedOp -> Doc
build (WithSrcEx ErrorSrcPos
_ ExpandedOp
op) = ExpandedOp -> Doc
forall a. Buildable a => a -> Doc
build ExpandedOp
op
  build (PrimEx ExpandedInstr
expandedInstr) = Doc
"<PrimEx: " Doc -> Doc -> Doc
forall b. FromDoc b => Doc -> Doc -> b
+| ExpandedInstr
expandedInstr ExpandedInstr -> Doc -> Doc
forall a b. (Buildable a, FromDoc b) => a -> Doc -> b
|+ Doc
">"
  build (SeqEx [ExpandedOp]
expandedOps)    = Doc
"<SeqEx: " Doc -> Doc -> Doc
forall b. FromDoc b => Doc -> Doc -> b
+| [ExpandedOp]
expandedOps [ExpandedOp] -> Doc -> Doc
forall a b. (Buildable a, FromDoc b) => a -> Doc -> b
|+ Doc
">"

-- | Flatten all 'SeqEx' in 'ExpandedOp'. This function is mostly for
-- testing. It returns instructions with the same logic, but they are
-- not strictly equivalent, because they are serialized differently
-- (grouping instructions into sequences affects the way they are
-- PACK'ed).
flattenExpandedOp :: ExpandedOp -> [ExpandedInstr]
flattenExpandedOp :: ExpandedOp -> [ExpandedInstr]
flattenExpandedOp =
  \case
    PrimEx ExpandedInstr
i -> [ExpandedInstr -> ExpandedInstr
flattenInstr ExpandedInstr
i]
    SeqEx [ExpandedOp]
ops -> (Element [ExpandedOp] -> [ExpandedInstr])
-> [ExpandedOp] -> [ExpandedInstr]
forall c b. Container c => (Element c -> [b]) -> c -> [b]
concatMap Element [ExpandedOp] -> [ExpandedInstr]
ExpandedOp -> [ExpandedInstr]
flattenExpandedOp [ExpandedOp]
ops
    WithSrcEx ErrorSrcPos
_ ExpandedOp
op -> ExpandedOp -> [ExpandedInstr]
flattenExpandedOp ExpandedOp
op
  where
    flattenInstr :: ExpandedInstr -> ExpandedInstr
    flattenInstr :: ExpandedInstr -> ExpandedInstr
flattenInstr = (forall b. Data b => b -> b) -> forall b. Data b => b -> b
everywhere (([ExpandedOp] -> [ExpandedOp]) -> a -> a
forall a b. (Typeable a, Typeable b) => (b -> b) -> a -> a
mkT [ExpandedOp] -> [ExpandedOp]
flattenOps)

    flattenOps :: [ExpandedOp] -> [ExpandedOp]
    flattenOps :: [ExpandedOp] -> [ExpandedOp]
flattenOps [] = []
    flattenOps (SeqEx [ExpandedOp]
s : [ExpandedOp]
xs) = [ExpandedOp]
s [ExpandedOp] -> [ExpandedOp] -> [ExpandedOp]
forall a. [a] -> [a] -> [a]
++ [ExpandedOp] -> [ExpandedOp]
flattenOps [ExpandedOp]
xs
    flattenOps (x :: ExpandedOp
x@(PrimEx ExpandedInstr
_) : [ExpandedOp]
xs) = ExpandedOp
x ExpandedOp -> [ExpandedOp] -> [ExpandedOp]
forall a. a -> [a] -> [a]
: [ExpandedOp] -> [ExpandedOp]
flattenOps [ExpandedOp]
xs
    flattenOps (WithSrcEx ErrorSrcPos
_ ExpandedOp
op : [ExpandedOp]
xs) = ExpandedOp
op ExpandedOp -> [ExpandedOp] -> [ExpandedOp]
forall a. a -> [a] -> [a]
: [ExpandedOp] -> [ExpandedOp]
flattenOps [ExpandedOp]
xs

-------------------------------------
-- Abstract instruction
-------------------------------------

instance HoistInstr InstrAbstract where
  hoistInstr :: forall (f :: * -> *) a (g :: * -> *).
(f a -> g a) -> InstrAbstract f a -> InstrAbstract g a
hoistInstr f a -> g a
f = \case
    EXT ExtInstrAbstract f a
x -> ExtInstrAbstract g a -> InstrAbstract g a
forall (f :: * -> *) op.
ExtInstrAbstract f op -> InstrAbstract f op
EXT (ExtInstrAbstract g a -> InstrAbstract g a)
-> ExtInstrAbstract g a -> InstrAbstract g a
forall a b. (a -> b) -> a -> b
$ (f a -> g a) -> ExtInstrAbstract f a -> ExtInstrAbstract g a
forall {k} (n :: (k -> *) -> k -> *) (f :: k -> *) (a :: k)
       (g :: k -> *).
HoistInstr n =>
(f a -> g a) -> n f a -> n g a
forall (f :: * -> *) a (g :: * -> *).
(f a -> g a) -> ExtInstrAbstract f a -> ExtInstrAbstract g a
hoistInstr f a -> g a
f ExtInstrAbstract f a
x
    IF_NONE f a
l f a
r -> g a -> g a -> InstrAbstract g a
forall (f :: * -> *) op. f op -> f op -> InstrAbstract f op
IF_NONE (f a -> g a
f f a
l) (f a -> g a
f f a
r)
    IF_LEFT f a
l f a
r -> g a -> g a -> InstrAbstract g a
forall (f :: * -> *) op. f op -> f op -> InstrAbstract f op
IF_LEFT (f a -> g a
f f a
l) (f a -> g a
f f a
r)
    IF_CONS f a
l f a
r -> g a -> g a -> InstrAbstract g a
forall (f :: * -> *) op. f op -> f op -> InstrAbstract f op
IF_CONS (f a -> g a
f f a
l) (f a -> g a
f f a
r)
    MAP VarAnn
ann f a
r -> VarAnn -> g a -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> f op -> InstrAbstract f op
MAP VarAnn
ann (f a -> g a
f f a
r)
    ITER f a
l -> g a -> InstrAbstract g a
forall (f :: * -> *) op. f op -> InstrAbstract f op
ITER (f a -> g a
f f a
l)
    IF f a
l f a
r -> g a -> g a -> InstrAbstract g a
forall (f :: * -> *) op. f op -> f op -> InstrAbstract f op
IF (f a -> g a
f f a
l) (f a -> g a
f f a
r)
    LOOP f a
l -> g a -> InstrAbstract g a
forall (f :: * -> *) op. f op -> InstrAbstract f op
LOOP (f a -> g a
f f a
l)
    LOOP_LEFT f a
l -> g a -> InstrAbstract g a
forall (f :: * -> *) op. f op -> InstrAbstract f op
LOOP_LEFT (f a -> g a
f f a
l)
    LAMBDA VarAnn
ann Ty
tl Ty
tr f a
r -> VarAnn -> Ty -> Ty -> g a -> InstrAbstract g a
forall (f :: * -> *) op.
VarAnn -> Ty -> Ty -> f op -> InstrAbstract f op
LAMBDA VarAnn
ann Ty
tl Ty
tr (f a -> g a
f f a
r)
    LAMBDA_REC VarAnn
ann Ty
tl Ty
tr f a
r -> VarAnn -> Ty -> Ty -> g a -> InstrAbstract g a
forall (f :: * -> *) op.
VarAnn -> Ty -> Ty -> f op -> InstrAbstract f op
LAMBDA_REC VarAnn
ann Ty
tl Ty
tr (f a -> g a
f f a
r)
    DIP f a
l -> g a -> InstrAbstract g a
forall (f :: * -> *) op. f op -> InstrAbstract f op
DIP (f a -> g a
f f a
l)
    DIPN Word
w f a
r -> Word -> g a -> InstrAbstract g a
forall (f :: * -> *) op. Word -> f op -> InstrAbstract f op
DIPN Word
w (f a -> g a
f f a
r)
    PUSH VarAnn
va Ty
x Value' f a
y               -> VarAnn -> Ty -> Value' g a -> InstrAbstract g a
forall (f :: * -> *) op.
VarAnn -> Ty -> Value' f op -> InstrAbstract f op
PUSH VarAnn
va Ty
x (Value' g a -> InstrAbstract g a)
-> Value' g a -> InstrAbstract g a
forall a b. (a -> b) -> a -> b
$ (f a -> g a) -> Value' f a -> Value' g a
forall {k} (n :: (k -> *) -> k -> *) (f :: k -> *) (a :: k)
       (g :: k -> *).
HoistInstr n =>
(f a -> g a) -> n f a -> n g a
forall (f :: * -> *) a (g :: * -> *).
(f a -> g a) -> Value' f a -> Value' g a
hoistInstr f a -> g a
f Value' f a
y
    ---
    DROPN Word
va                  -> Word -> InstrAbstract g a
forall (f :: * -> *) op. Word -> InstrAbstract f op
DROPN Word
va
    InstrAbstract f a
DROP                      -> InstrAbstract g a
forall (f :: * -> *) op. InstrAbstract f op
DROP
    DUP VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
DUP VarAnn
va
    DUPN VarAnn
va Word
x                 -> VarAnn -> Word -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> Word -> InstrAbstract f op
DUPN VarAnn
va Word
x
    InstrAbstract f a
SWAP                      -> InstrAbstract g a
forall (f :: * -> *) op. InstrAbstract f op
SWAP
    DIG Word
va                    -> Word -> InstrAbstract g a
forall (f :: * -> *) op. Word -> InstrAbstract f op
DIG Word
va
    DUG Word
va                    -> Word -> InstrAbstract g a
forall (f :: * -> *) op. Word -> InstrAbstract f op
DUG Word
va
    SOME TypeAnn
va VarAnn
x                 -> TypeAnn -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. TypeAnn -> VarAnn -> InstrAbstract f op
SOME TypeAnn
va VarAnn
x
    NONE TypeAnn
va VarAnn
x Ty
y               -> TypeAnn -> VarAnn -> Ty -> InstrAbstract g a
forall (f :: * -> *) op.
TypeAnn -> VarAnn -> Ty -> InstrAbstract f op
NONE TypeAnn
va VarAnn
x Ty
y
    UNIT TypeAnn
va VarAnn
x                 -> TypeAnn -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. TypeAnn -> VarAnn -> InstrAbstract f op
UNIT TypeAnn
va VarAnn
x
    PAIR TypeAnn
va VarAnn
x FieldAnn
y FieldAnn
z             -> TypeAnn -> VarAnn -> FieldAnn -> FieldAnn -> InstrAbstract g a
forall (f :: * -> *) op.
TypeAnn -> VarAnn -> FieldAnn -> FieldAnn -> InstrAbstract f op
PAIR TypeAnn
va VarAnn
x FieldAnn
y FieldAnn
z
    UNPAIR VarAnn
va VarAnn
x FieldAnn
y FieldAnn
z           -> VarAnn -> VarAnn -> FieldAnn -> FieldAnn -> InstrAbstract g a
forall (f :: * -> *) op.
VarAnn -> VarAnn -> FieldAnn -> FieldAnn -> InstrAbstract f op
UNPAIR VarAnn
va VarAnn
x FieldAnn
y FieldAnn
z
    PAIRN VarAnn
va Word
x                -> VarAnn -> Word -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> Word -> InstrAbstract f op
PAIRN VarAnn
va Word
x
    UNPAIRN Word
va                -> Word -> InstrAbstract g a
forall (f :: * -> *) op. Word -> InstrAbstract f op
UNPAIRN Word
va
    CAR VarAnn
va FieldAnn
x                  -> VarAnn -> FieldAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> FieldAnn -> InstrAbstract f op
CAR VarAnn
va FieldAnn
x
    CDR VarAnn
va FieldAnn
x                  -> VarAnn -> FieldAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> FieldAnn -> InstrAbstract f op
CDR VarAnn
va FieldAnn
x
    LEFT TypeAnn
va VarAnn
x FieldAnn
y FieldAnn
z Ty
w           -> TypeAnn
-> VarAnn -> FieldAnn -> FieldAnn -> Ty -> InstrAbstract g a
forall (f :: * -> *) op.
TypeAnn
-> VarAnn -> FieldAnn -> FieldAnn -> Ty -> InstrAbstract f op
LEFT TypeAnn
va VarAnn
x FieldAnn
y FieldAnn
z Ty
w
    RIGHT TypeAnn
va VarAnn
x FieldAnn
y FieldAnn
z Ty
w          -> TypeAnn
-> VarAnn -> FieldAnn -> FieldAnn -> Ty -> InstrAbstract g a
forall (f :: * -> *) op.
TypeAnn
-> VarAnn -> FieldAnn -> FieldAnn -> Ty -> InstrAbstract f op
RIGHT TypeAnn
va VarAnn
x FieldAnn
y FieldAnn
z Ty
w
    NIL TypeAnn
va VarAnn
x Ty
y                -> TypeAnn -> VarAnn -> Ty -> InstrAbstract g a
forall (f :: * -> *) op.
TypeAnn -> VarAnn -> Ty -> InstrAbstract f op
NIL TypeAnn
va VarAnn
x Ty
y
    CONS VarAnn
va                   -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
CONS VarAnn
va
    SIZE VarAnn
va                   -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SIZE VarAnn
va
    EMPTY_SET TypeAnn
va VarAnn
x Ty
y          -> TypeAnn -> VarAnn -> Ty -> InstrAbstract g a
forall (f :: * -> *) op.
TypeAnn -> VarAnn -> Ty -> InstrAbstract f op
EMPTY_SET TypeAnn
va VarAnn
x Ty
y
    EMPTY_MAP TypeAnn
va VarAnn
x Ty
y Ty
z        -> TypeAnn -> VarAnn -> Ty -> Ty -> InstrAbstract g a
forall (f :: * -> *) op.
TypeAnn -> VarAnn -> Ty -> Ty -> InstrAbstract f op
EMPTY_MAP TypeAnn
va VarAnn
x Ty
y Ty
z
    EMPTY_BIG_MAP TypeAnn
va VarAnn
x Ty
y Ty
z    -> TypeAnn -> VarAnn -> Ty -> Ty -> InstrAbstract g a
forall (f :: * -> *) op.
TypeAnn -> VarAnn -> Ty -> Ty -> InstrAbstract f op
EMPTY_BIG_MAP TypeAnn
va VarAnn
x Ty
y Ty
z
    MEM VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
MEM VarAnn
va
    GET VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
GET VarAnn
va
    GETN VarAnn
va Word
x                 -> VarAnn -> Word -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> Word -> InstrAbstract f op
GETN VarAnn
va Word
x
    UPDATE VarAnn
va                 -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
UPDATE VarAnn
va
    UPDATEN VarAnn
va Word
x              -> VarAnn -> Word -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> Word -> InstrAbstract f op
UPDATEN VarAnn
va Word
x
    GET_AND_UPDATE VarAnn
va         -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
GET_AND_UPDATE VarAnn
va
    EXEC VarAnn
va                   -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
EXEC VarAnn
va
    APPLY VarAnn
va                  -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
APPLY VarAnn
va
    InstrAbstract f a
FAILWITH                  -> InstrAbstract g a
forall (f :: * -> *) op. InstrAbstract f op
FAILWITH
    CAST VarAnn
va Ty
x                 -> VarAnn -> Ty -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> Ty -> InstrAbstract f op
CAST VarAnn
va Ty
x
    RENAME VarAnn
va                 -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
RENAME VarAnn
va
    PACK VarAnn
va                   -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
PACK VarAnn
va
    UNPACK TypeAnn
va VarAnn
x Ty
y             -> TypeAnn -> VarAnn -> Ty -> InstrAbstract g a
forall (f :: * -> *) op.
TypeAnn -> VarAnn -> Ty -> InstrAbstract f op
UNPACK TypeAnn
va VarAnn
x Ty
y
    CONCAT VarAnn
va                 -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
CONCAT VarAnn
va
    SLICE VarAnn
va                  -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SLICE VarAnn
va
    ISNAT VarAnn
va                  -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
ISNAT VarAnn
va
    ADD VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
ADD VarAnn
va
    SUB VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SUB VarAnn
va
    SUB_MUTEZ VarAnn
va              -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SUB_MUTEZ VarAnn
va
    MUL VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
MUL VarAnn
va
    EDIV VarAnn
va                   -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
EDIV VarAnn
va
    ABS VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
ABS VarAnn
va
    NEG VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
NEG VarAnn
va
    LSL VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
LSL VarAnn
va
    LSR VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
LSR VarAnn
va
    OR VarAnn
va                     -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
OR VarAnn
va
    AND VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
AND VarAnn
va
    XOR VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
XOR VarAnn
va
    NOT VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
NOT VarAnn
va
    COMPARE VarAnn
va                -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
COMPARE VarAnn
va
    EQ VarAnn
va                     -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
EQ VarAnn
va
    NEQ VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
NEQ VarAnn
va
    LT VarAnn
va                     -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
LT VarAnn
va
    GT VarAnn
va                     -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
GT VarAnn
va
    LE VarAnn
va                     -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
LE VarAnn
va
    GE VarAnn
va                     -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
GE VarAnn
va
    INT VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
INT VarAnn
va
    VIEW VarAnn
va ViewName
x Ty
y               -> VarAnn -> ViewName -> Ty -> InstrAbstract g a
forall (f :: * -> *) op.
VarAnn -> ViewName -> Ty -> InstrAbstract f op
VIEW VarAnn
va ViewName
x Ty
y
    SELF VarAnn
va FieldAnn
x                 -> VarAnn -> FieldAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> FieldAnn -> InstrAbstract f op
SELF VarAnn
va FieldAnn
x
    CONTRACT VarAnn
va FieldAnn
x Ty
y           -> VarAnn -> FieldAnn -> Ty -> InstrAbstract g a
forall (f :: * -> *) op.
VarAnn -> FieldAnn -> Ty -> InstrAbstract f op
CONTRACT VarAnn
va FieldAnn
x Ty
y
    TRANSFER_TOKENS VarAnn
va        -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
TRANSFER_TOKENS VarAnn
va
    SET_DELEGATE VarAnn
va           -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SET_DELEGATE VarAnn
va
    CREATE_CONTRACT VarAnn
va VarAnn
x Contract' a
y    -> VarAnn -> VarAnn -> Contract' a -> InstrAbstract g a
forall (f :: * -> *) op.
VarAnn -> VarAnn -> Contract' op -> InstrAbstract f op
CREATE_CONTRACT VarAnn
va VarAnn
x Contract' a
y
    IMPLICIT_ACCOUNT VarAnn
va       -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
IMPLICIT_ACCOUNT VarAnn
va
    NOW VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
NOW VarAnn
va
    AMOUNT VarAnn
va                 -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
AMOUNT VarAnn
va
    BALANCE VarAnn
va                -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
BALANCE VarAnn
va
    VOTING_POWER VarAnn
va           -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
VOTING_POWER VarAnn
va
    TOTAL_VOTING_POWER VarAnn
va     -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
TOTAL_VOTING_POWER VarAnn
va
    CHECK_SIGNATURE VarAnn
va        -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
CHECK_SIGNATURE VarAnn
va
    SHA256 VarAnn
va                 -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SHA256 VarAnn
va
    SHA512 VarAnn
va                 -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SHA512 VarAnn
va
    BLAKE2B VarAnn
va                -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
BLAKE2B VarAnn
va
    SHA3 VarAnn
va                   -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SHA3 VarAnn
va
    KECCAK VarAnn
va                 -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
KECCAK VarAnn
va
    HASH_KEY VarAnn
va               -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
HASH_KEY VarAnn
va
    PAIRING_CHECK VarAnn
va          -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
PAIRING_CHECK VarAnn
va
    SOURCE VarAnn
va                 -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SOURCE VarAnn
va
    SENDER VarAnn
va                 -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SENDER VarAnn
va
    ADDRESS VarAnn
va                -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
ADDRESS VarAnn
va
    CHAIN_ID VarAnn
va               -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
CHAIN_ID VarAnn
va
    LEVEL VarAnn
va                  -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
LEVEL VarAnn
va
    SELF_ADDRESS VarAnn
va           -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SELF_ADDRESS VarAnn
va
    InstrAbstract f a
NEVER                     -> InstrAbstract g a
forall (f :: * -> *) op. InstrAbstract f op
NEVER
    TICKET VarAnn
va                 -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
TICKET VarAnn
va
    TICKET_DEPRECATED VarAnn
va      -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
TICKET_DEPRECATED VarAnn
va
    READ_TICKET VarAnn
va            -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
READ_TICKET VarAnn
va
    SPLIT_TICKET VarAnn
va           -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SPLIT_TICKET VarAnn
va
    JOIN_TICKETS VarAnn
va           -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
JOIN_TICKETS VarAnn
va
    OPEN_CHEST VarAnn
va             -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
OPEN_CHEST VarAnn
va
    SAPLING_EMPTY_STATE VarAnn
va Natural
x  -> VarAnn -> Natural -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> Natural -> InstrAbstract f op
SAPLING_EMPTY_STATE VarAnn
va Natural
x
    SAPLING_VERIFY_UPDATE VarAnn
va  -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
SAPLING_VERIFY_UPDATE VarAnn
va
    MIN_BLOCK_TIME [AnyAnn]
va         -> [AnyAnn] -> InstrAbstract g a
forall (f :: * -> *) op. [AnyAnn] -> InstrAbstract f op
MIN_BLOCK_TIME [AnyAnn]
va
    EMIT VarAnn
va FieldAnn
x Maybe Ty
y               -> VarAnn -> FieldAnn -> Maybe Ty -> InstrAbstract g a
forall (f :: * -> *) op.
VarAnn -> FieldAnn -> Maybe Ty -> InstrAbstract f op
EMIT VarAnn
va FieldAnn
x Maybe Ty
y
    BYTES VarAnn
va                  -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
BYTES VarAnn
va
    NAT VarAnn
va                    -> VarAnn -> InstrAbstract g a
forall (f :: * -> *) op. VarAnn -> InstrAbstract f op
NAT VarAnn
va

-- | Michelson instruction with abstract parameter @op@.  This
-- parameter is necessary, because at different stages of our pipeline
-- it will be different. Initially it can contain macros and
-- non-flattened instructions, but then it contains only vanilla
-- Michelson instructions.
data InstrAbstract f op
  = EXT               (ExtInstrAbstract f op)
  | DROPN              Word
  -- ^ "DROP n" instruction.
  -- Note: reference implementation permits int16 here.
  -- Negative numbers are parsed successfully there, but rejected later.
  -- Morley is more permissive, so we use 'Word' here,
  -- i. e. permit more positive numbers. We do not permit negative numbers
  -- at type level.
  -- In practice, probably nobody will ever have numbers greater than ≈1000
  -- here, at least due to gas limits.
  -- Same reasoning applies to other instructions which have a numeric
  -- parameter representing number of elements on stack.
  | DROP
  -- ^ 'DROP' is essentially as special case for 'DROPN', but we need
  -- both because they are packed differently.
  | DUP               VarAnn
  | DUPN              VarAnn Word
  | SWAP
  | DIG               Word
  | DUG               Word
  | PUSH              VarAnn Ty (Value' f op)
  | SOME              TypeAnn VarAnn
  | NONE              TypeAnn VarAnn Ty
  | UNIT              TypeAnn VarAnn
  | IF_NONE           (f op) (f op)
  | PAIR              TypeAnn VarAnn FieldAnn FieldAnn
  | UNPAIR            VarAnn VarAnn FieldAnn FieldAnn
  | PAIRN             VarAnn Word
  | UNPAIRN           Word
  | CAR               VarAnn FieldAnn
  | CDR               VarAnn FieldAnn
  | LEFT              TypeAnn VarAnn FieldAnn FieldAnn Ty
  | RIGHT             TypeAnn VarAnn FieldAnn FieldAnn Ty
  | IF_LEFT           (f op) (f op)
  | NIL               TypeAnn VarAnn Ty
  | CONS              VarAnn
  | IF_CONS           (f op) (f op)
  | SIZE              VarAnn
  | EMPTY_SET         TypeAnn VarAnn Ty
  | EMPTY_MAP         TypeAnn VarAnn Ty Ty
  | EMPTY_BIG_MAP     TypeAnn VarAnn Ty Ty
  | MAP               VarAnn (f op)
  | ITER              (f op)
  | MEM               VarAnn
  | GET               VarAnn
  | GETN              VarAnn Word
  | UPDATE            VarAnn
  | UPDATEN           VarAnn Word
  | GET_AND_UPDATE    VarAnn
  | IF                (f op) (f op)
  | LOOP              (f op)
  | LOOP_LEFT         (f op)
  | LAMBDA            VarAnn Ty Ty (f op)
  | LAMBDA_REC        VarAnn Ty Ty (f op)
  | EXEC              VarAnn
  | APPLY             VarAnn
  | DIP               (f op)
  | DIPN              Word (f op)
  | FAILWITH
  | CAST              VarAnn Ty
  | RENAME            VarAnn
  | PACK              VarAnn
  | UNPACK            TypeAnn VarAnn Ty
  | CONCAT            VarAnn
  | SLICE             VarAnn
  | ISNAT             VarAnn
  | ADD               VarAnn
  | SUB               VarAnn
  | SUB_MUTEZ         VarAnn
  | MUL               VarAnn
  | EDIV              VarAnn
  | ABS               VarAnn
  | NEG               VarAnn
  | LSL               VarAnn
  | LSR               VarAnn
  | OR                VarAnn
  | AND               VarAnn
  | XOR               VarAnn
  | NOT               VarAnn
  | COMPARE           VarAnn
  | EQ                VarAnn
  | NEQ               VarAnn
  | LT                VarAnn
  | GT                VarAnn
  | LE                VarAnn
  | GE                VarAnn
  | INT               VarAnn
  | VIEW              VarAnn ViewName Ty
  | SELF              VarAnn FieldAnn
  | CONTRACT          VarAnn FieldAnn Ty
  | TRANSFER_TOKENS   VarAnn
  | SET_DELEGATE      VarAnn
  | CREATE_CONTRACT   VarAnn VarAnn (Contract' op)
  | IMPLICIT_ACCOUNT  VarAnn
  | NOW               VarAnn
  | AMOUNT            VarAnn
  | BALANCE           VarAnn
  | VOTING_POWER      VarAnn
  | TOTAL_VOTING_POWER VarAnn
  | CHECK_SIGNATURE   VarAnn
  | SHA256            VarAnn
  | SHA512            VarAnn
  | BLAKE2B           VarAnn
  | SHA3              VarAnn
  | KECCAK            VarAnn
  | HASH_KEY          VarAnn
  | PAIRING_CHECK     VarAnn
  | SOURCE            VarAnn
  | SENDER            VarAnn
  | ADDRESS           VarAnn
  | CHAIN_ID          VarAnn
  | LEVEL             VarAnn
  | SELF_ADDRESS      VarAnn
  | NEVER
  | TICKET            VarAnn
  | TICKET_DEPRECATED VarAnn
  | READ_TICKET       VarAnn
  | SPLIT_TICKET      VarAnn
  | JOIN_TICKETS      VarAnn
  | OPEN_CHEST        VarAnn
  | SAPLING_EMPTY_STATE VarAnn Natural
  | SAPLING_VERIFY_UPDATE VarAnn
  | MIN_BLOCK_TIME    [AnyAnn]
  | EMIT              VarAnn FieldAnn (Maybe Ty)
  | BYTES             VarAnn
  | NAT               VarAnn
  deriving stock (InstrAbstract f op -> InstrAbstract f op -> Bool
(InstrAbstract f op -> InstrAbstract f op -> Bool)
-> (InstrAbstract f op -> InstrAbstract f op -> Bool)
-> Eq (InstrAbstract f op)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (f :: * -> *) op.
(Eq op, Eq (f op)) =>
InstrAbstract f op -> InstrAbstract f op -> Bool
$c== :: forall (f :: * -> *) op.
(Eq op, Eq (f op)) =>
InstrAbstract f op -> InstrAbstract f op -> Bool
== :: InstrAbstract f op -> InstrAbstract f op -> Bool
$c/= :: forall (f :: * -> *) op.
(Eq op, Eq (f op)) =>
InstrAbstract f op -> InstrAbstract f op -> Bool
/= :: InstrAbstract f op -> InstrAbstract f op -> Bool
Eq, (forall a b. (a -> b) -> InstrAbstract f a -> InstrAbstract f b)
-> (forall a b. a -> InstrAbstract f b -> InstrAbstract f a)
-> Functor (InstrAbstract f)
forall a b. a -> InstrAbstract f b -> InstrAbstract f a
forall a b. (a -> b) -> InstrAbstract f a -> InstrAbstract f b
forall (f :: * -> *) a b.
Functor f =>
a -> InstrAbstract f b -> InstrAbstract f a
forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> InstrAbstract f a -> InstrAbstract f b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> InstrAbstract f a -> InstrAbstract f b
fmap :: forall a b. (a -> b) -> InstrAbstract f a -> InstrAbstract f b
$c<$ :: forall (f :: * -> *) a b.
Functor f =>
a -> InstrAbstract f b -> InstrAbstract f a
<$ :: forall a b. a -> InstrAbstract f b -> InstrAbstract f a
Functor, Typeable (InstrAbstract f op)
Typeable (InstrAbstract f op)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g)
    -> InstrAbstract f op
    -> c (InstrAbstract f op))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (InstrAbstract f op))
-> (InstrAbstract f op -> Constr)
-> (InstrAbstract f op -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (InstrAbstract f op)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (InstrAbstract f op)))
-> ((forall b. Data b => b -> b)
    -> InstrAbstract f op -> InstrAbstract f op)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> InstrAbstract f op -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> InstrAbstract f op -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> InstrAbstract f op -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> InstrAbstract f op -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> InstrAbstract f op -> m (InstrAbstract f op))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> InstrAbstract f op -> m (InstrAbstract f op))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> InstrAbstract f op -> m (InstrAbstract f op))
-> Data (InstrAbstract f op)
InstrAbstract f op -> Constr
InstrAbstract f op -> DataType
(forall b. Data b => b -> b)
-> InstrAbstract f op -> InstrAbstract f op
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) -> InstrAbstract f op -> u
forall u. (forall d. Data d => d -> u) -> InstrAbstract f op -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> InstrAbstract f op -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> InstrAbstract f op -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> InstrAbstract f op -> m (InstrAbstract f op)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> InstrAbstract f op -> m (InstrAbstract f op)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (InstrAbstract f op)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> InstrAbstract f op
-> c (InstrAbstract f op)
forall {f :: * -> *} {op}.
(Typeable f, Data op, Data (f op)) =>
Typeable (InstrAbstract f op)
forall (f :: * -> *) op.
(Typeable f, Data op, Data (f op)) =>
InstrAbstract f op -> Constr
forall (f :: * -> *) op.
(Typeable f, Data op, Data (f op)) =>
InstrAbstract f op -> DataType
forall (f :: * -> *) op.
(Typeable f, Data op, Data (f op)) =>
(forall b. Data b => b -> b)
-> InstrAbstract f op -> InstrAbstract f op
forall (f :: * -> *) op u.
(Typeable f, Data op, Data (f op)) =>
Int -> (forall d. Data d => d -> u) -> InstrAbstract f op -> u
forall (f :: * -> *) op u.
(Typeable f, Data op, Data (f op)) =>
(forall d. Data d => d -> u) -> InstrAbstract f op -> [u]
forall (f :: * -> *) op r r'.
(Typeable f, Data op, Data (f op)) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> InstrAbstract f op -> r
forall (f :: * -> *) op r r'.
(Typeable f, Data op, Data (f op)) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> InstrAbstract f op -> r
forall (f :: * -> *) op (m :: * -> *).
(Typeable f, Data op, Data (f op), Monad m) =>
(forall d. Data d => d -> m d)
-> InstrAbstract f op -> m (InstrAbstract f op)
forall (f :: * -> *) op (m :: * -> *).
(Typeable f, Data op, Data (f op), MonadPlus m) =>
(forall d. Data d => d -> m d)
-> InstrAbstract f op -> m (InstrAbstract f op)
forall (f :: * -> *) op (c :: * -> *).
(Typeable f, Data op, Data (f op)) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (InstrAbstract f op)
forall (f :: * -> *) op (c :: * -> *).
(Typeable f, Data op, Data (f op)) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> InstrAbstract f op
-> c (InstrAbstract f op)
forall (f :: * -> *) op (t :: * -> *) (c :: * -> *).
(Typeable f, Data op, Data (f op), Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (InstrAbstract f op))
forall (f :: * -> *) op (t :: * -> * -> *) (c :: * -> *).
(Typeable f, Data op, Data (f op), Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (InstrAbstract f op))
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (InstrAbstract f op))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (InstrAbstract f op))
$cgfoldl :: forall (f :: * -> *) op (c :: * -> *).
(Typeable f, Data op, Data (f op)) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> InstrAbstract f op
-> c (InstrAbstract f op)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> InstrAbstract f op
-> c (InstrAbstract f op)
$cgunfold :: forall (f :: * -> *) op (c :: * -> *).
(Typeable f, Data op, Data (f op)) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (InstrAbstract f op)
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (InstrAbstract f op)
$ctoConstr :: forall (f :: * -> *) op.
(Typeable f, Data op, Data (f op)) =>
InstrAbstract f op -> Constr
toConstr :: InstrAbstract f op -> Constr
$cdataTypeOf :: forall (f :: * -> *) op.
(Typeable f, Data op, Data (f op)) =>
InstrAbstract f op -> DataType
dataTypeOf :: InstrAbstract f op -> DataType
$cdataCast1 :: forall (f :: * -> *) op (t :: * -> *) (c :: * -> *).
(Typeable f, Data op, Data (f op), Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (InstrAbstract f op))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (InstrAbstract f op))
$cdataCast2 :: forall (f :: * -> *) op (t :: * -> * -> *) (c :: * -> *).
(Typeable f, Data op, Data (f op), Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (InstrAbstract f op))
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (InstrAbstract f op))
$cgmapT :: forall (f :: * -> *) op.
(Typeable f, Data op, Data (f op)) =>
(forall b. Data b => b -> b)
-> InstrAbstract f op -> InstrAbstract f op
gmapT :: (forall b. Data b => b -> b)
-> InstrAbstract f op -> InstrAbstract f op
$cgmapQl :: forall (f :: * -> *) op r r'.
(Typeable f, Data op, Data (f op)) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> InstrAbstract f op -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> InstrAbstract f op -> r
$cgmapQr :: forall (f :: * -> *) op r r'.
(Typeable f, Data op, Data (f op)) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> InstrAbstract f op -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> InstrAbstract f op -> r
$cgmapQ :: forall (f :: * -> *) op u.
(Typeable f, Data op, Data (f op)) =>
(forall d. Data d => d -> u) -> InstrAbstract f op -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> InstrAbstract f op -> [u]
$cgmapQi :: forall (f :: * -> *) op u.
(Typeable f, Data op, Data (f op)) =>
Int -> (forall d. Data d => d -> u) -> InstrAbstract f op -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> InstrAbstract f op -> u
$cgmapM :: forall (f :: * -> *) op (m :: * -> *).
(Typeable f, Data op, Data (f op), Monad m) =>
(forall d. Data d => d -> m d)
-> InstrAbstract f op -> m (InstrAbstract f op)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> InstrAbstract f op -> m (InstrAbstract f op)
$cgmapMp :: forall (f :: * -> *) op (m :: * -> *).
(Typeable f, Data op, Data (f op), MonadPlus m) =>
(forall d. Data d => d -> m d)
-> InstrAbstract f op -> m (InstrAbstract f op)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> InstrAbstract f op -> m (InstrAbstract f op)
$cgmapMo :: forall (f :: * -> *) op (m :: * -> *).
(Typeable f, Data op, Data (f op), MonadPlus m) =>
(forall d. Data d => d -> m d)
-> InstrAbstract f op -> m (InstrAbstract f op)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> InstrAbstract f op -> m (InstrAbstract f op)
Data, (forall x. InstrAbstract f op -> Rep (InstrAbstract f op) x)
-> (forall x. Rep (InstrAbstract f op) x -> InstrAbstract f op)
-> Generic (InstrAbstract f op)
forall x. Rep (InstrAbstract f op) x -> InstrAbstract f op
forall x. InstrAbstract f op -> Rep (InstrAbstract f op) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (f :: * -> *) op x.
Rep (InstrAbstract f op) x -> InstrAbstract f op
forall (f :: * -> *) op x.
InstrAbstract f op -> Rep (InstrAbstract f op) x
$cfrom :: forall (f :: * -> *) op x.
InstrAbstract f op -> Rep (InstrAbstract f op) x
from :: forall x. InstrAbstract f op -> Rep (InstrAbstract f op) x
$cto :: forall (f :: * -> *) op x.
Rep (InstrAbstract f op) x -> InstrAbstract f op
to :: forall x. Rep (InstrAbstract f op) x -> InstrAbstract f op
Generic, Int -> InstrAbstract f op -> ShowS
[InstrAbstract f op] -> ShowS
InstrAbstract f op -> String
(Int -> InstrAbstract f op -> ShowS)
-> (InstrAbstract f op -> String)
-> ([InstrAbstract f op] -> ShowS)
-> Show (InstrAbstract f op)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (f :: * -> *) op.
(Show op, Show (f op)) =>
Int -> InstrAbstract f op -> ShowS
forall (f :: * -> *) op.
(Show op, Show (f op)) =>
[InstrAbstract f op] -> ShowS
forall (f :: * -> *) op.
(Show op, Show (f op)) =>
InstrAbstract f op -> String
$cshowsPrec :: forall (f :: * -> *) op.
(Show op, Show (f op)) =>
Int -> InstrAbstract f op -> ShowS
showsPrec :: Int -> InstrAbstract f op -> ShowS
$cshow :: forall (f :: * -> *) op.
(Show op, Show (f op)) =>
InstrAbstract f op -> String
show :: InstrAbstract f op -> String
$cshowList :: forall (f :: * -> *) op.
(Show op, Show (f op)) =>
[InstrAbstract f op] -> ShowS
showList :: [InstrAbstract f op] -> ShowS
Show)

instance (NFData op, NFData (f op)) => NFData (InstrAbstract f op)

instance (RenderDoc op, Foldable f) => RenderDoc (InstrAbstract f op) where
  renderDoc :: RenderContext -> InstrAbstract f op -> Doc
renderDoc RenderContext
pn = \case
    EXT ExtInstrAbstract f op
extInstr            -> RenderContext -> ExtInstrAbstract f op -> Doc
forall a. RenderDoc a => RenderContext -> a -> Doc
renderDoc RenderContext
pn ExtInstrAbstract f op
extInstr
    InstrAbstract f op
DROP                    -> Doc
"DROP"
    DROPN Word
n                 -> Doc
"DROP" Doc -> Doc -> Doc
<+> Word -> Doc
forall a. Buildable a => a -> Doc
build Word
n
    DUP VarAnn
va                  -> Doc
"DUP" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    DUPN VarAnn
va Word
n               -> Doc
"DUP" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va Doc -> Doc -> Doc
<+> Word -> Doc
forall a. Buildable a => a -> Doc
build Word
n
    InstrAbstract f op
SWAP                    -> Doc
"SWAP"
    DIG Word
n                   -> Doc
"DIG" Doc -> Doc -> Doc
<+> Word -> Doc
forall a. Buildable a => a -> Doc
build Word
n
    DUG Word
n                   -> Doc
"DUG" Doc -> Doc -> Doc
<+> Word -> Doc
forall a. Buildable a => a -> Doc
build Word
n
    PUSH VarAnn
va Ty
t Value' f op
v             ->
      Text -> Doc -> [Doc] -> Doc
renderArgs Text
"PUSH" (VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va) [Ty -> Doc
renderTy Ty
t, RenderContext -> Value' f op -> Doc
forall a. RenderDoc a => RenderContext -> a -> Doc
renderDoc RenderContext
needsParens Value' f op
v]
    SOME TypeAnn
ta VarAnn
va              -> Doc
"SOME" Doc -> Doc -> Doc
<+> [TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn
ta] [] [VarAnn
va]
    NONE TypeAnn
ta VarAnn
va Ty
t            -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"NONE" ([TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn
ta] [] [VarAnn
va]) [Ty -> Doc
renderTy Ty
t]
    UNIT TypeAnn
ta VarAnn
va              -> Doc
"UNIT" Doc -> Doc -> Doc
<+> [TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn
ta] [] [VarAnn
va]
    IF_NONE f op
x f op
y             -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"IF_NONE" Doc
forall a. Monoid a => a
mempty [f op -> Doc
renderOps f op
x, f op -> Doc
renderOps f op
y]
    PAIR TypeAnn
ta VarAnn
va FieldAnn
fa1 FieldAnn
fa2      -> Doc
"PAIR" Doc -> Doc -> Doc
<+> [TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn
ta] [FieldAnn
fa1, FieldAnn
fa2] [VarAnn
va]
    UNPAIR VarAnn
va1 VarAnn
va2 FieldAnn
fa1 FieldAnn
fa2  -> Doc
"UNPAIR" Doc -> Doc -> Doc
<+> [TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [] [FieldAnn
fa1, FieldAnn
fa2] [VarAnn
va1, VarAnn
va2]
    PAIRN VarAnn
va Word
n              -> Doc
"PAIR" Doc -> Doc -> Doc
<+> [TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [] [] [VarAnn
va] Doc -> Doc -> Doc
<+> Word -> Doc
forall a. Buildable a => a -> Doc
build Word
n
    UNPAIRN Word
n               -> Doc
"UNPAIR" Doc -> Doc -> Doc
<+> Word -> Doc
forall a. Buildable a => a -> Doc
build Word
n
    CAR VarAnn
va FieldAnn
fa               -> Doc
"CAR" Doc -> Doc -> Doc
<+> [TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [] [FieldAnn
fa] [VarAnn
va]
    CDR VarAnn
va FieldAnn
fa               -> Doc
"CDR" Doc -> Doc -> Doc
<+> [TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [] [FieldAnn
fa] [VarAnn
va]
    LEFT TypeAnn
ta VarAnn
va FieldAnn
fa1 FieldAnn
fa2 Ty
t    -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"LEFT" ([TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn
ta] [FieldAnn
fa1, FieldAnn
fa2] [VarAnn
va]) [Ty -> Doc
renderTy Ty
t]
    RIGHT TypeAnn
ta VarAnn
va FieldAnn
fa1 FieldAnn
fa2 Ty
t   -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"RIGHT" ([TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn
ta] [FieldAnn
fa1, FieldAnn
fa2] [VarAnn
va]) [Ty -> Doc
renderTy Ty
t]
    IF_LEFT f op
x f op
y             -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"IF_LEFT" Doc
forall a. Monoid a => a
mempty [f op -> Doc
renderOps f op
x, f op -> Doc
renderOps f op
y]
    NIL TypeAnn
ta VarAnn
va Ty
t             -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"NIL" ([TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn
ta] [] [VarAnn
va]) [Ty -> Doc
renderTy Ty
t]
    CONS VarAnn
va                 -> Doc
"CONS" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    IF_CONS f op
x f op
y             -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"IF_CONS" Doc
forall a. Monoid a => a
mempty [f op -> Doc
renderOps f op
x, f op -> Doc
renderOps f op
y]
    SIZE VarAnn
va                 -> Doc
"SIZE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    EMPTY_SET TypeAnn
ta VarAnn
va Ty
t       -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"EMPTY_SET" ([TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn
ta] [] [VarAnn
va]) [Ty -> Doc
renderComp Ty
t]
    EMPTY_MAP TypeAnn
ta VarAnn
va Ty
c Ty
t     ->
      Text -> Doc -> [Doc] -> Doc
renderArgs Text
"EMPTY_MAP" ([TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn
ta] [] [VarAnn
va]) [Ty -> Doc
renderComp Ty
c, Ty -> Doc
renderTy Ty
t]
    EMPTY_BIG_MAP TypeAnn
ta VarAnn
va Ty
c Ty
t ->
      Text -> Doc -> [Doc] -> Doc
renderArgs Text
"EMPTY_BIG_MAP" ([TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn
ta] [] [VarAnn
va]) [Ty -> Doc
renderComp Ty
c, Ty -> Doc
renderTy Ty
t]
    MAP VarAnn
va f op
s                -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"MAP" (VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va) [f op -> Doc
renderOps f op
s]
    ITER f op
s                  -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"ITER" Doc
forall a. Monoid a => a
mempty [f op -> Doc
renderOps f op
s]
    MEM VarAnn
va                  -> Doc
"MEM" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    GET VarAnn
va                  -> Doc
"GET" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    GETN VarAnn
va Word
n               -> Doc
"GET" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va Doc -> Doc -> Doc
<+> Word -> Doc
forall a. Buildable a => a -> Doc
build Word
n
    UPDATE VarAnn
va               -> Doc
"UPDATE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    UPDATEN VarAnn
va Word
n            -> Doc
"UPDATE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va Doc -> Doc -> Doc
<+> Word -> Doc
forall a. Buildable a => a -> Doc
build Word
n
    GET_AND_UPDATE VarAnn
va       -> Doc
"GET_AND_UPDATE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    IF f op
x f op
y                  -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"IF" Doc
forall a. Monoid a => a
mempty [f op -> Doc
renderOps f op
x, f op -> Doc
renderOps f op
y]
    LOOP f op
s                  -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"LOOP" Doc
forall a. Monoid a => a
mempty [f op -> Doc
renderOps f op
s]
    LOOP_LEFT f op
s             -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"LOOP_LEFT" Doc
forall a. Monoid a => a
mempty [f op -> Doc
renderOps f op
s]
    LAMBDA VarAnn
va Ty
t Ty
r f op
s         ->
      Text -> Doc -> [Doc] -> Doc
renderArgs Text
"LAMBDA" (VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va) [Ty -> Doc
renderTy Ty
t, Ty -> Doc
renderTy Ty
r, f op -> Doc
renderOps f op
s]
    LAMBDA_REC VarAnn
va Ty
t Ty
r f op
s     ->
      Text -> Doc -> [Doc] -> Doc
renderArgs Text
"LAMBDA_REC" (VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va) [Ty -> Doc
renderTy Ty
t, Ty -> Doc
renderTy Ty
r, f op -> Doc
renderOps f op
s]
    EXEC VarAnn
va                 -> Doc
"EXEC" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    APPLY VarAnn
va                -> Doc
"APPLY" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    DIP f op
s                   -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"DIP" Doc
forall a. Monoid a => a
mempty [f op -> Doc
renderOps f op
s]
    DIPN Word
n f op
s                -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"DIP" Doc
forall a. Monoid a => a
mempty [Word -> Doc
forall a. Buildable a => a -> Doc
build Word
n, f op -> Doc
renderOps f op
s]
    InstrAbstract f op
FAILWITH                -> Doc
"FAILWITH"
    CAST VarAnn
va Ty
t               -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"CAST" (VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va) [Ty -> Doc
renderTy Ty
t]
    RENAME VarAnn
va               -> Doc
"RENAME" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    PACK VarAnn
va                 -> Doc
"PACK" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    UNPACK TypeAnn
ta VarAnn
va Ty
t          -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"UNPACK" ([TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn
ta] [] [VarAnn
va]) [Ty -> Doc
renderTy Ty
t]
    CONCAT VarAnn
va               -> Doc
"CONCAT" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    SLICE VarAnn
va                -> Doc
"SLICE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    ISNAT VarAnn
va                -> Doc
"ISNAT" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    ADD VarAnn
va                  -> Doc
"ADD" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    SUB VarAnn
va                  -> Doc
"SUB" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    SUB_MUTEZ VarAnn
va            -> Doc
"SUB_MUTEZ" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    MUL VarAnn
va                  -> Doc
"MUL" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    EDIV VarAnn
va                 -> Doc
"EDIV" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    ABS VarAnn
va                  -> Doc
"ABS" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    NEG VarAnn
va                  -> Doc
"NEG" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    LSL VarAnn
va                  -> Doc
"LSL" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    LSR VarAnn
va                  -> Doc
"LSR" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    OR  VarAnn
va                  -> Doc
"OR" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    AND VarAnn
va                  -> Doc
"AND" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    XOR VarAnn
va                  -> Doc
"XOR" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    NOT VarAnn
va                  -> Doc
"NOT" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    COMPARE VarAnn
va              -> Doc
"COMPARE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    EQ VarAnn
va                   -> Doc
"EQ" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    NEQ VarAnn
va                  -> Doc
"NEQ" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    LT VarAnn
va                   -> Doc
"LT" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    GT VarAnn
va                   -> Doc
"GT" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    LE VarAnn
va                   -> Doc
"LE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    GE VarAnn
va                   -> Doc
"GE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    INT VarAnn
va                  -> Doc
"INT" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    VIEW VarAnn
va ViewName
name Ty
ty         ->
      Text -> Doc -> [Doc] -> Doc
renderArgs Text
"VIEW" (VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va) [ViewName -> Doc
renderViewName ViewName
name, Ty -> Doc
renderTy Ty
ty]
    SELF VarAnn
va FieldAnn
fa              -> Doc
"SELF" Doc -> Doc -> Doc
<+> [TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [] [FieldAnn
fa] [VarAnn
va]
    CONTRACT VarAnn
va FieldAnn
fa Ty
t        -> Text -> Doc -> [Doc] -> Doc
renderArgs Text
"CONTRACT" ([TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [] [FieldAnn
fa] [VarAnn
va]) [Ty -> Doc
renderTy Ty
t]
    TRANSFER_TOKENS VarAnn
va      -> Doc
"TRANSFER_TOKENS" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    SET_DELEGATE VarAnn
va         -> Doc
"SET_DELEGATE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    CREATE_CONTRACT VarAnn
va1 VarAnn
va2 Contract' op
contract -> let
      body :: Doc
body = Doc -> Doc -> Doc -> Doc
forall ann. Doc ann -> Doc ann -> Doc ann -> Doc ann
enclose Doc
forall ann. Doc ann
space Doc
forall ann. Doc ann
space (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> Doc
forall ann. Doc ann -> Doc ann
align (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ RenderContext -> Contract' op -> Doc
forall a. RenderDoc a => RenderContext -> a -> Doc
renderDoc RenderContext
doesntNeedParens Contract' op
contract
      in Text -> Doc -> [Doc] -> Doc
renderArgs Text
"CREATE_CONTRACT" ([TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [] [] [VarAnn
va1, VarAnn
va2]) [Doc -> Doc
forall ann. Doc ann -> Doc ann
braces (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Doc
body]
    IMPLICIT_ACCOUNT VarAnn
va      -> Doc
"IMPLICIT_ACCOUNT" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    NOW VarAnn
va                   -> Doc
"NOW" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    AMOUNT VarAnn
va                -> Doc
"AMOUNT" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    BALANCE VarAnn
va               -> Doc
"BALANCE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    VOTING_POWER VarAnn
va          -> Doc
"VOTING_POWER" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    TOTAL_VOTING_POWER VarAnn
va    -> Doc
"TOTAL_VOTING_POWER" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    CHECK_SIGNATURE VarAnn
va       -> Doc
"CHECK_SIGNATURE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    SHA256 VarAnn
va                -> Doc
"SHA256" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    SHA512 VarAnn
va                -> Doc
"SHA512" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    BLAKE2B VarAnn
va               -> Doc
"BLAKE2B" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    SHA3 VarAnn
va                  -> Doc
"SHA3" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    KECCAK VarAnn
va                -> Doc
"KECCAK" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    HASH_KEY VarAnn
va              -> Doc
"HASH_KEY" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    PAIRING_CHECK VarAnn
va         -> Doc
"PAIRING_CHECK" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    SOURCE VarAnn
va                -> Doc
"SOURCE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    SENDER VarAnn
va                -> Doc
"SENDER" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    ADDRESS VarAnn
va               -> Doc
"ADDRESS" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    CHAIN_ID VarAnn
va              -> Doc
"CHAIN_ID" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    LEVEL VarAnn
va                 -> Doc
"LEVEL" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    SELF_ADDRESS VarAnn
va          -> Doc
"SELF_ADDRESS" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    InstrAbstract f op
NEVER                    -> Doc
"NEVER"
    TICKET VarAnn
va                -> Doc
"TICKET" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    TICKET_DEPRECATED VarAnn
va     -> Doc
"TICKET_DEPRECATED" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    READ_TICKET VarAnn
va           -> Doc
"READ_TICKET" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    SPLIT_TICKET VarAnn
va          -> Doc
"SPLIT_TICKET" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    JOIN_TICKETS VarAnn
va          -> Doc
"JOIN_TICKETS" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    OPEN_CHEST VarAnn
va            -> Doc
"OPEN_CHEST" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    EMIT VarAnn
va FieldAnn
fa Maybe Ty
ty            ->
      Text -> Doc -> [Doc] -> Doc
renderArgs Text
"EMIT" ([TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [] [FieldAnn
fa] [VarAnn
va]) ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ Maybe Doc -> [Doc]
forall a. Maybe a -> [a]
maybeToList (Maybe Doc -> [Doc]) -> Maybe Doc -> [Doc]
forall a b. (a -> b) -> a -> b
$ Ty -> Doc
renderTy (Ty -> Doc) -> Maybe Ty -> Maybe Doc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Ty
ty
    SAPLING_EMPTY_STATE VarAnn
va Natural
n -> Doc
"SAPLING_EMPTY_STATE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va Doc -> Doc -> Doc
<+> Natural -> Doc
forall a. Buildable a => a -> Doc
build Natural
n
    SAPLING_VERIFY_UPDATE VarAnn
va -> Doc
"SAPLING_VERIFY_UPDATE" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    MIN_BLOCK_TIME [AnyAnn]
anns      -> Doc
"MIN_BLOCK_TIME" Doc -> Doc -> Doc
<+> [AnyAnn] -> Doc
renderAnyAnns [AnyAnn]
anns
    BYTES VarAnn
va                 -> Doc
"BYTES" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    NAT VarAnn
va                   -> Doc
"NAT" Doc -> Doc -> Doc
<+> VarAnn -> Doc
forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot VarAnn
va
    where
      renderTy :: Ty -> Doc
renderTy = forall a. RenderDoc a => RenderContext -> a -> Doc
renderDoc @Ty RenderContext
needsParens
      renderComp :: Ty -> Doc
renderComp = forall a. RenderDoc a => RenderContext -> a -> Doc
renderDoc @Ty RenderContext
needsParens
      renderOps :: f op -> Doc
renderOps = Bool -> f op -> Doc
forall op (f :: * -> *).
(RenderDoc op, Foldable f) =>
Bool -> f op -> Doc
renderOpsList Bool
False

      renderAnnot :: KnownAnnTag tag => Annotation tag -> Doc
      renderAnnot :: forall tag. KnownAnnTag tag => Annotation tag -> Doc
renderAnnot = RenderContext -> AnnotationSet -> Doc
forall a. RenderDoc a => RenderContext -> a -> Doc
renderDoc RenderContext
doesntNeedParens (AnnotationSet -> Doc)
-> (Annotation tag -> AnnotationSet) -> Annotation tag -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Annotation tag -> AnnotationSet
forall tag. KnownAnnTag tag => Annotation tag -> AnnotationSet
singleAnnSet

      renderAnnots :: [TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
      renderAnnots :: [TypeAnn] -> [FieldAnn] -> [VarAnn] -> Doc
renderAnnots [TypeAnn]
ts [FieldAnn]
fs [VarAnn]
vs = RenderContext -> AnnotationSet -> Doc
forall a. RenderDoc a => RenderContext -> a -> Doc
renderDoc RenderContext
doesntNeedParens (AnnotationSet -> Doc) -> AnnotationSet -> Doc
forall a b. (a -> b) -> a -> b
$ [TypeAnn] -> [FieldAnn] -> [VarAnn] -> AnnotationSet
fullAnnSet [TypeAnn]
ts [FieldAnn]
fs [VarAnn]
vs

      renderArgs :: Text -> Doc -> [Doc] -> Doc
      renderArgs :: Text -> Doc -> [Doc] -> Doc
renderArgs Text
name Doc
annots [Doc]
args
        | Doc -> Bool
isEmpty Doc
annots Bool -> Bool -> Bool
forall a. Boolean a => a -> a -> a
&& Text -> Int
forall i a.
(Integral i, Container a,
 DefaultToInt (IsIntSubType Length i) i) =>
a -> i
length Text
name Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
3
        = Doc -> Doc
forall ann. Doc ann -> Doc ann
group (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Text -> Doc
forall a. Buildable a => a -> Doc
build Text
name Doc -> Doc -> Doc
<+> Doc
annots Doc -> Doc -> Doc
<+> Doc -> Doc
forall ann. Doc ann -> Doc ann
PP.align ([Doc] -> Doc
forall ann. [Doc ann] -> Doc ann
PP.vsep [Doc]
args)
        | Bool
otherwise
        = Doc -> Doc
forall ann. Doc ann -> Doc ann
group (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Int -> Doc -> Doc
forall ann. Int -> Doc ann -> Doc ann
PP.hang Int
2 (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
forall ann. [Doc ann] -> Doc ann
PP.vsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ Text -> Doc
forall a. Buildable a => a -> Doc
build Text
name Doc -> Doc -> Doc
<+> Doc
annots Doc -> [Doc] -> [Doc]
forall a. a -> [a] -> [a]
: [Doc]
args

  isRenderable :: InstrAbstract f op -> Bool
isRenderable = \case
    EXT ExtInstrAbstract f op
extInstr -> ExtInstrAbstract f op -> Bool
forall a. RenderDoc a => a -> Bool
isRenderable ExtInstrAbstract f op
extInstr
    InstrAbstract f op
_ -> Bool
True

instance (Foldable f, RenderDoc op, Buildable op)
  => Buildable (InstrAbstract f op) where
  build :: InstrAbstract f op -> Doc
build = \case
    EXT ExtInstrAbstract f op
ext -> ExtInstrAbstract f op -> Doc
forall a. Buildable a => a -> Doc
build ExtInstrAbstract f op
ext
    InstrAbstract f op
mi -> Doc -> Doc
forall ann. Doc ann -> Doc ann
group (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ RenderContext -> InstrAbstract f op -> Doc
forall a. RenderDoc a => RenderContext -> a -> Doc
renderDoc RenderContext
doesntNeedParens InstrAbstract f op
mi

----------------------------------------------------------------------------
-- JSON serialization
----------------------------------------------------------------------------

instance (FromJSON op, FromJSON (f op)) => FromJSON (InstrAbstract f op) where
    parseJSON :: Value -> Parser (InstrAbstract f op)
parseJSON = Options -> Value -> Parser (InstrAbstract f op)
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
morleyAesonOptions
instance (ToJSON op, ToJSON (f op)) => ToJSON (InstrAbstract f op) where
    toJSON :: InstrAbstract f op -> Value
toJSON     = Options -> InstrAbstract f op -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
morleyAesonOptions
    toEncoding :: InstrAbstract f op -> Encoding
toEncoding = Options -> InstrAbstract f op -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
genericToEncoding Options
morleyAesonOptions

deriveJSON morleyAesonOptions ''ExpandedOp