{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PatternSynonyms #-}
module EVM.Opcode
(
Opcode
, Opcode'(..)
, OpcodeSpec(..)
, opcodeSpec
, jump
, jumpi
, jumpdest
, jumpAnnot
, jumpdestAnnot
, concrete
, opcodeText
, opcodeSize
, toHex
, pack
, toBytes
, isDUP
, isSWAP
, isLOG
, isPUSH
, readDUP
, readSWAP
, readLOG
, readPUSH
, readOp
, pattern DUP1, pattern DUP2, pattern DUP3, pattern DUP4
, pattern DUP5, pattern DUP6, pattern DUP7, pattern DUP8
, pattern DUP9, pattern DUP10, pattern DUP11, pattern DUP12
, pattern DUP13, pattern DUP14, pattern DUP15, pattern DUP16
, pattern SWAP1, pattern SWAP2, pattern SWAP3, pattern SWAP4
, pattern SWAP5, pattern SWAP6, pattern SWAP7, pattern SWAP8
, pattern SWAP9, pattern SWAP10, pattern SWAP11, pattern SWAP12
, pattern SWAP13, pattern SWAP14, pattern SWAP15, pattern SWAP16
, pattern LOG0, pattern LOG1, pattern LOG2, pattern LOG3, pattern LOG4
) where
import Prelude hiding (LT, EQ, GT)
import Control.Applicative ((<|>))
import Control.Monad (guard)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Data.DoubleWord (Word256, fromHiAndLo)
import Data.Maybe (isJust)
import qualified Data.Serialize.Get as Cereal
import Data.String (IsString, fromString)
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.List as List
import Data.Word (Word8, Word64)
import Text.Printf (printf)
import EVM.Opcode.Internal
type Opcode = Opcode' ()
instance {-# OVERLAPPING #-} Show Opcode where
show :: Opcode -> String
show (PUSH Word256
n) = String
"PUSH " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Word256 -> String
forall a. Show a => a -> String
show Word256
n
show Opcode
opcode = Text -> String
Text.unpack (Text -> Text
Text.toUpper (Opcode -> Text
opcodeText Opcode
opcode))
jump :: Opcode
jump :: Opcode
jump = () -> Opcode
forall j. j -> Opcode' j
JUMP ()
jumpi :: Opcode
jumpi :: Opcode
jumpi = () -> Opcode
forall j. j -> Opcode' j
JUMPI ()
jumpdest :: Opcode
jumpdest :: Opcode
jumpdest = () -> Opcode
forall j. j -> Opcode' j
JUMPDEST ()
isDUP :: Word8 -> Bool
isDUP :: Word8 -> Bool
isDUP = Maybe Opcode -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Opcode -> Bool) -> (Word8 -> Maybe Opcode) -> Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Maybe Opcode
readDUP
isSWAP :: Word8 -> Bool
isSWAP :: Word8 -> Bool
isSWAP = Maybe Opcode -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Opcode -> Bool) -> (Word8 -> Maybe Opcode) -> Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Maybe Opcode
readSWAP
isLOG :: Word8 -> Bool
isLOG :: Word8 -> Bool
isLOG = Maybe Opcode -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Opcode -> Bool) -> (Word8 -> Maybe Opcode) -> Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Maybe Opcode
readLOG
isPUSH :: Word8 -> ByteString -> Bool
isPUSH :: Word8 -> ByteString -> Bool
isPUSH Word8
b ByteString
bs = Maybe Opcode -> Bool
forall a. Maybe a -> Bool
isJust (Word8 -> ByteString -> Maybe Opcode
readPUSH Word8
b ByteString
bs)
readDUP :: Word8 -> Maybe Opcode
readDUP :: Word8 -> Maybe Opcode
readDUP Word8
b = do
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Word8
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x80 Bool -> Bool -> Bool
&& Word8
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x8f)
Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ord16 -> Opcode
forall j. Ord16 -> Opcode' j
DUP (Word8 -> Ord16
forall e. Enum e => Word8 -> e
fromWord8 (Word8
b Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
0x80)))
readSWAP :: Word8 -> Maybe Opcode
readSWAP :: Word8 -> Maybe Opcode
readSWAP Word8
b = do
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Word8
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x90 Bool -> Bool -> Bool
&& Word8
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x9f)
Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ord16 -> Opcode
forall j. Ord16 -> Opcode' j
SWAP (Word8 -> Ord16
forall e. Enum e => Word8 -> e
fromWord8 (Word8
b Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
0x90)))
readLOG :: Word8 -> Maybe Opcode
readLOG :: Word8 -> Maybe Opcode
readLOG Word8
b = do
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Word8
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0xa0 Bool -> Bool -> Bool
&& Word8
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0xa4)
Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ord5 -> Opcode
forall j. Ord5 -> Opcode' j
LOG (Word8 -> Ord5
forall e. Enum e => Word8 -> e
fromWord8 (Word8
b Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
0xa0)))
readPUSH :: Word8 -> ByteString -> Maybe Opcode
readPUSH :: Word8 -> ByteString -> Maybe Opcode
readPUSH Word8
b ByteString
bs = do
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Word8
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x60 Bool -> Bool -> Bool
&& Word8
b Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x7f)
let n :: Int
n = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8
b Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
0x60 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
1)
Word256 -> Opcode
forall j. Word256 -> Opcode' j
PUSH (Word256 -> Opcode) -> Maybe Word256 -> Maybe Opcode
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Maybe Word256
word256 (Int -> ByteString -> ByteString
BS.take Int
n ByteString
bs)
readOp :: Word8 -> ByteString -> Maybe Opcode
readOp :: Word8 -> ByteString -> Maybe Opcode
readOp Word8
word ByteString
bs
= Word8 -> Maybe Opcode
readDUP Word8
word
Maybe Opcode -> Maybe Opcode -> Maybe Opcode
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Word8 -> Maybe Opcode
readSWAP Word8
word
Maybe Opcode -> Maybe Opcode -> Maybe Opcode
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Word8 -> Maybe Opcode
readLOG Word8
word
Maybe Opcode -> Maybe Opcode -> Maybe Opcode
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Word8 -> ByteString -> Maybe Opcode
readPUSH Word8
word ByteString
bs
Maybe Opcode -> Maybe Opcode -> Maybe Opcode
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> case Word8
word of
Word8
0x00 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
STOP
Word8
0x01 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
ADD
Word8
0x02 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
MUL
Word8
0x03 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SUB
Word8
0x04 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
DIV
Word8
0x05 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SDIV
Word8
0x06 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
MOD
Word8
0x07 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SMOD
Word8
0x08 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
ADDMOD
Word8
0x09 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
MULMOD
Word8
0x0a -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
EXP
Word8
0x0b -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SIGNEXTEND
Word8
0x10 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
LT
Word8
0x11 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
GT
Word8
0x12 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SLT
Word8
0x13 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SGT
Word8
0x14 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
EQ
Word8
0x15 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
ISZERO
Word8
0x16 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
AND
Word8
0x17 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
OR
Word8
0x18 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
XOR
Word8
0x19 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
NOT
Word8
0x1a -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
BYTE
Word8
0x1b -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SHL
Word8
0x1c -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SHR
Word8
0x1d -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SAR
Word8
0x20 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SHA3
Word8
0x30 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
ADDRESS
Word8
0x31 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
BALANCE
Word8
0x32 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
ORIGIN
Word8
0x33 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CALLER
Word8
0x34 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CALLVALUE
Word8
0x35 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CALLDATALOAD
Word8
0x36 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CALLDATASIZE
Word8
0x37 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CALLDATACOPY
Word8
0x38 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CODESIZE
Word8
0x39 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CODECOPY
Word8
0x3a -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
GASPRICE
Word8
0x3b -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
EXTCODESIZE
Word8
0x3c -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
EXTCODECOPY
Word8
0x3d -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
RETURNDATASIZE
Word8
0x3e -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
RETURNDATACOPY
Word8
0x3f -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
EXTCODEHASH
Word8
0x40 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
BLOCKHASH
Word8
0x41 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
COINBASE
Word8
0x42 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
TIMESTAMP
Word8
0x43 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
NUMBER
Word8
0x44 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
DIFFICULTY
Word8
0x45 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
GASLIMIT
Word8
0x46 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CHAINID
Word8
0x47 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SELFBALANCE
Word8
0x50 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
POP
Word8
0x51 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
MLOAD
Word8
0x52 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
MSTORE
Word8
0x53 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
MSTORE8
Word8
0x54 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SLOAD
Word8
0x55 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SSTORE
Word8
0x56 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
jump
Word8
0x57 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
jumpi
Word8
0x58 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
PC
Word8
0x59 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
MSIZE
Word8
0x5a -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
GAS
Word8
0x5b -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
jumpdest
Word8
0xf0 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CREATE
Word8
0xf1 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CALL
Word8
0xf2 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CALLCODE
Word8
0xf3 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
RETURN
Word8
0xf4 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
DELEGATECALL
Word8
0xf5 -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
CREATE2
Word8
0xfa -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
STATICCALL
Word8
0xfd -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
REVERT
Word8
0xfe -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
INVALID
Word8
0xff -> Opcode -> Maybe Opcode
forall (f :: * -> *) a. Applicative f => a -> f a
pure Opcode
forall j. Opcode' j
SELFDESTRUCT
Word8
_ -> Maybe Opcode
forall a. Maybe a
Nothing
word256 :: ByteString -> Maybe Word256
word256 :: ByteString -> Maybe Word256
word256 = Either String Word256 -> Maybe Word256
forall e a. Either e a -> Maybe a
eitherToMaybe (Either String Word256 -> Maybe Word256)
-> (ByteString -> Either String Word256)
-> ByteString
-> Maybe Word256
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either String Word256
getWord256 (ByteString -> Either String Word256)
-> (ByteString -> ByteString)
-> ByteString
-> Either String Word256
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ByteString -> ByteString
padLeft Int
32
where
getWord256 :: ByteString -> Either String Word256
getWord256 :: ByteString -> Either String Word256
getWord256 = Get Word256 -> ByteString -> Either String Word256
forall a. Get a -> ByteString -> Either String a
Cereal.runGet (Get Word256 -> ByteString -> Either String Word256)
-> Get Word256 -> ByteString -> Either String Word256
forall a b. (a -> b) -> a -> b
$
Word64 -> Word64 -> Word64 -> Word64 -> Word256
fromWord64s (Word64 -> Word64 -> Word64 -> Word64 -> Word256)
-> Get Word64 -> Get (Word64 -> Word64 -> Word64 -> Word256)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word64
Cereal.getWord64be
Get (Word64 -> Word64 -> Word64 -> Word256)
-> Get Word64 -> Get (Word64 -> Word64 -> Word256)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word64
Cereal.getWord64be
Get (Word64 -> Word64 -> Word256)
-> Get Word64 -> Get (Word64 -> Word256)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word64
Cereal.getWord64be
Get (Word64 -> Word256) -> Get Word64 -> Get Word256
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word64
Cereal.getWord64be
fromWord64s :: Word64 -> Word64 -> Word64 -> Word64 -> Word256
fromWord64s :: Word64 -> Word64 -> Word64 -> Word64 -> Word256
fromWord64s Word64
a Word64
b Word64
c Word64
d = HiWord Word256 -> LoWord Word256 -> Word256
forall w. DoubleWord w => HiWord w -> LoWord w -> w
fromHiAndLo (HiWord Word128 -> LoWord Word128 -> Word128
forall w. DoubleWord w => HiWord w -> LoWord w -> w
fromHiAndLo Word64
HiWord Word128
a Word64
LoWord Word128
b) (HiWord Word128 -> LoWord Word128 -> Word128
forall w. DoubleWord w => HiWord w -> LoWord w -> w
fromHiAndLo Word64
HiWord Word128
c Word64
LoWord Word128
d)
padLeft :: Int -> ByteString -> ByteString
padLeft :: Int -> ByteString -> ByteString
padLeft Int
n ByteString
xs = Int -> Word8 -> ByteString
BS.replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
BS.length ByteString
xs) Word8
0 ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
xs
eitherToMaybe :: Either e a -> Maybe a
eitherToMaybe :: Either e a -> Maybe a
eitherToMaybe = (e -> Maybe a) -> (a -> Maybe a) -> Either e a -> Maybe a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe a -> e -> Maybe a
forall a b. a -> b -> a
const Maybe a
forall a. Maybe a
Nothing) a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
opcodeText :: Opcode -> Text
opcodeText :: Opcode -> Text
opcodeText = OpcodeSpec -> Text
opcodeName (OpcodeSpec -> Text) -> (Opcode -> OpcodeSpec) -> Opcode -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Opcode -> OpcodeSpec
forall j. Opcode' j -> OpcodeSpec
opcodeSpec
opcodeSize :: Num i => Opcode -> i
opcodeSize :: Opcode -> i
opcodeSize (PUSH Word256
n) = [Word8] -> i
forall i a. Num i => [a] -> i
List.genericLength ([Word8] -> i)
-> ((Word8, [Word8]) -> [Word8]) -> (Word8, [Word8]) -> i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8 -> [Word8] -> [Word8]) -> (Word8, [Word8]) -> [Word8]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:) ((Word8, [Word8]) -> i) -> (Word8, [Word8]) -> i
forall a b. (a -> b) -> a -> b
$ Word256 -> (Word8, [Word8])
push' Word256
n
opcodeSize Opcode
_opcode = i
1
toHex :: IsString s => [Opcode] -> s
toHex :: [Opcode] -> s
toHex = String -> s
forall a. IsString a => String -> a
fromString (String -> s) -> ([Opcode] -> String) -> [Opcode] -> s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8 -> String) -> [Word8] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
List.concatMap (String -> Word8 -> String
forall r. PrintfType r => String -> r
printf String
"%02x") ([Word8] -> String) -> ([Opcode] -> [Word8]) -> [Opcode] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Opcode -> [Word8]) -> [Opcode] -> [Word8]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
List.concatMap Opcode -> [Word8]
toBytes
pack :: [Opcode] -> ByteString
pack :: [Opcode] -> ByteString
pack = [Word8] -> ByteString
BS.pack ([Word8] -> ByteString)
-> ([Opcode] -> [Word8]) -> [Opcode] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Opcode -> [Word8]) -> [Opcode] -> [Word8]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
List.concatMap Opcode -> [Word8]
toBytes
toBytes :: Opcode -> [Word8]
toBytes :: Opcode -> [Word8]
toBytes (PUSH Word256
n) = (Word8 -> [Word8] -> [Word8]) -> (Word8, [Word8]) -> [Word8]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:) (Word256 -> (Word8, [Word8])
push' Word256
n)
toBytes Opcode
opcode = [ OpcodeSpec -> Word8
opcodeEncoding (Opcode -> OpcodeSpec
forall j. Opcode' j -> OpcodeSpec
opcodeSpec Opcode
opcode) ]