module Compiler.Bytecode.DisasmFinal
( disasmFinal
) where
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text as T
import Data.Text (Text)
import Data.Bits
import Data.Word (Word8, Word16)
import Data.Int (Int8, Int16)
import Data.Binary.Get
import Data.ByteString (ByteString)
import Data.Maybe (fromMaybe)
import Compiler.Instruction (Immediate(..), immediateSize)
import Common.Type.Integer (IntValue(..))
disasmFinal :: ByteString -> Either Text [(Int, String)]
disasmFinal :: ByteString -> Either Text [(Int, String)]
disasmFinal ByteString
bs =
case Get [(Int, String)]
-> ByteString
-> Either
(ByteString, Int64, String) (ByteString, Int64, [(Int, String)])
forall a.
Get a
-> ByteString
-> Either (ByteString, Int64, String) (ByteString, Int64, a)
runGetOrFail Get [(Int, String)]
disasmAll (ByteString -> ByteString
BL.fromStrict ByteString
bs) of
Left (ByteString
_, Int64
off, String
msg) ->
Text -> Either Text [(Int, String)]
forall a b. a -> Either a b
Left (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ String
"Disasm error at " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int64 -> String
forall a. Show a => a -> String
show Int64
off String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
msg)
Right (ByteString
_, Int64
_, [(Int, String)]
xs) -> [(Int, String)] -> Either Text [(Int, String)]
forall a b. b -> Either a b
Right [(Int, String)]
xs
disasmAll :: Get [(Int, String)]
disasmAll :: Get [(Int, String)]
disasmAll = do
done <- Get Bool
isEmpty
if done then return [] else do
off <- fromIntegral <$> bytesRead
instr <- disasmInstr
rest <- disasmAll
return ((off, instr) : rest)
disasmInstr :: Get String
disasmInstr :: Get String
disasmInstr = Get Word8
getWord8 Get Word8 -> (Word8 -> Get String) -> Get String
forall a b. Get a -> (a -> Get b) -> Get b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Word8 -> Get String
decodeOp
decodeOp :: Word8 -> Get String
decodeOp :: Word8 -> Get String
decodeOp Word8
0x00 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"PADDING"
decodeOp Word8
0xFF = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"NOP"
decodeOp Word8
0x01 = Get String
decodePush
decodeOp Word8
0x60 = Get String
decodeMakeClosure
decodeOp Word8
0xFE = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"CHECK_STACK " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeOp Word8
op | Word8
op Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x30 Bool -> Bool -> Bool
&& Word8
op Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x39 = Word8 -> Get String
decodeJump Word8
op
decodeOp Word8
op | Word8
op Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x40 Bool -> Bool -> Bool
&& Word8
op Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x49 = Word8 -> Get String
decodeCall Word8
op
decodeOp Word8
op | Word8
op Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x50 Bool -> Bool -> Bool
&& Word8
op Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x59 = Word8 -> Get String
decodeMem Word8
op
decodeOp Word8
op | Word8
op Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x61 Bool -> Bool -> Bool
&& Word8
op Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x69 = Word8 -> Get String
decodeStruct Word8
op
decodeOp Word8
0x80 = (Word8 -> String) -> Get Word8 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"CAST " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Word8 -> String) -> Word8 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> String
forall a. Show a => a -> String
show) Get Word8
getWord8
decodeOp Word8
0x81 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"TYPEOF"
decodeOp Word8
op | Word8
op Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0xB0 Bool -> Bool -> Bool
&& Word8
op Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0xB4 = Word8 -> Get String
decodeIO Word8
op
decodeOp Word8
0x70 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"PRINT"
decodeOp Word8
0x71 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"HALT"
decodeOp Word8
0x72 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"EXIT"
decodeOp Word8
op = String -> Get String
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Get String) -> String -> Get String
forall a b. (a -> b) -> a -> b
$ String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe
(String
"<UNKNOWN 0x" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
showHex2 Word8
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
">") (Word8 -> Maybe String
lookupSimple Word8
op)
decodePush :: Get String
decodePush :: Get String
decodePush = Get Word8
getWord8 Get Word8 -> (Word8 -> Get String) -> Get String
forall a b. Get a -> (a -> Get b) -> Get b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Word8 -> Get String
decodePushVal
decodePushVal :: Word8 -> Get String
decodePushVal :: Word8 -> Get String
decodePushVal Word8
0x00 = do
b <- Get Word8
getWord8
pure $ "PUSH BOOL " ++ (if b == 0 then "False" else "True")
decodePushVal Word8
0x01 = (Word8 -> String) -> Get Word8 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"PUSH I8 " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Word8 -> String) -> Word8 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int8 -> String
forall a. Show a => a -> String
show (Int8 -> String) -> (Word8 -> Int8) -> Word8 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(Word8 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Word8 -> Int8)) Get Word8
getWord8
decodePushVal Word8
0x02 = (Word8 -> String) -> Get Word8 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"PUSH UI8 " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Word8 -> String) -> Word8 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> String
forall a. Show a => a -> String
show) Get Word8
getWord8
decodePushVal Word8
0x03 = (Word16 -> String) -> Get Word16 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"PUSH I16 " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Word16 -> String) -> Word16 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int16 -> String
forall a. Show a => a -> String
show (Int16 -> String) -> (Word16 -> Int16) -> Word16 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(Word16 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Word16 -> Int16)) Get Word16
getWord16be
decodePushVal Word8
0x04 = (Word16 -> String) -> Get Word16 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"PUSH UI16 " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Word16 -> String) -> Word16 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> String
forall a. Show a => a -> String
show) Get Word16
getWord16be
decodePushVal Word8
0x05 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"PUSH I32 " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodePushVal Word8
0x06 = (Word32 -> String) -> Get Word32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"PUSH UI32 " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Word32 -> String) -> Word32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> String
forall a. Show a => a -> String
show) Get Word32
getWord32be
decodePushVal Word8
0x07 = (Int64 -> String) -> Get Int64 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"PUSH I64 " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int64 -> String) -> Int64 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> String
forall a. Show a => a -> String
show) Get Int64
getInt64be
decodePushVal Word8
0x08 = (Word64 -> String) -> Get Word64 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"PUSH UI64 " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Word64 -> String) -> Word64 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> String
forall a. Show a => a -> String
show) Get Word64
getWord64be
decodePushVal Word8
0x09 = (Word8 -> String) -> Get Word8 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"PUSH CHAR " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Word8 -> String) -> Word8 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> String
forall a. Show a => a -> String
show (Char -> String) -> (Word8 -> Char) -> Word8 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(Int -> Char
forall a. Enum a => Int -> a
toEnum :: Int -> Char) (Int -> Char) -> (Word8 -> Int) -> Word8 -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Get Word8
getWord8
decodePushVal Word8
t = Int -> Get ()
skip (Word8 -> Int
immSize Word8
t) Get () -> Get String -> Get String
forall a b. Get a -> Get b -> Get b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String
"PUSH (Type " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show Word8
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")")
decodeJump :: Word8 -> Get String
decodeJump :: Word8 -> Get String
decodeJump Word8
0x30 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"JUMP " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeJump Word8
0x31 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"JUMP_IF_FALSE " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeJump Word8
0x32 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"JUMP_IF_TRUE " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeJump Word8
_ = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"UNKNOWN_JUMP"
decodeCall :: Word8 -> Get String
decodeCall :: Word8 -> Get String
decodeCall Word8
0x40 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"CALL " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeCall Word8
0x41 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"TAILCALL " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeCall Word8
0x42 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"CALL_INDIRECT"
decodeCall Word8
0x43 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"RET"
decodeCall Word8
_ = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"UNKNOWN_CALL"
decodeMem :: Word8 -> Get String
decodeMem :: Word8 -> Get String
decodeMem Word8
0x50 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"LOAD_LOCAL " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeMem Word8
0x51 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"STORE_LOCAL " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeMem Word8
0x52 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"LOAD_GLOBAL " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeMem Word8
0x53 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"STORE_GLOBAL " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeMem Word8
0x54 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"LOAD_CAPTURE " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeMem Word8
0x55 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"STORE_CAPTURE " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeMem Word8
_ = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"UNKNOWN_MEM"
decodeStruct :: Word8 -> Get String
decodeStruct :: Word8 -> Get String
decodeStruct Word8
0x61 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"GET_FUNC_ADDR " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeStruct Word8
0x62 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"BUILD_STRUCT " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeStruct Word8
0x63 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"GET_FIELD " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeStruct Word8
0x64 = (Int32 -> String) -> Get Int32 -> Get String
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String
"SET_FIELD " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int32 -> String) -> Int32 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show) Get Int32
getInt32be
decodeStruct Word8
_ = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"UNKNOWN_STRUCT"
decodeIO :: Word8 -> Get String
decodeIO :: Word8 -> Get String
decodeIO Word8
0xB0 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"OPEN"
decodeIO Word8
0xB1 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"READ"
decodeIO Word8
0xB2 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"WRITE"
decodeIO Word8
0xB3 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"CLOSE"
decodeIO Word8
0xB4 = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"INPUT"
decodeIO Word8
_ = String -> Get String
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"UNKNOWN_IO"
decodeMakeClosure :: Get String
decodeMakeClosure :: Get String
decodeMakeClosure = do
a <- Get Int32
getInt32be
n <- getInt32be
pure $ "MAKE_CLOSURE @" ++ show a ++ ", captures=" ++ show n
lookupSimple :: Word8 -> Maybe String
lookupSimple :: Word8 -> Maybe String
lookupSimple Word8
op = Word8 -> Maybe String
lookupStack Word8
op Maybe String -> (String -> Maybe String) -> Maybe String
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Maybe String
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return
where
lookupStack :: Word8 -> Maybe String
lookupStack Word8
o | Word8
o Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x02 Bool -> Bool -> Bool
&& Word8
o Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x04 = Word8 -> Maybe String
simpleStack Word8
o
| Word8
o Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x10 Bool -> Bool -> Bool
&& Word8
o Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x14 = Word8 -> Maybe String
simpleArith Word8
o
| Word8
o Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x20 Bool -> Bool -> Bool
&& Word8
o Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x25 = Word8 -> Maybe String
simpleLogic Word8
o
| Bool
otherwise = Maybe String
forall a. Maybe a
Nothing
simpleStack :: Word8 -> Maybe String
simpleStack :: Word8 -> Maybe String
simpleStack Word8
0x02 = String -> Maybe String
forall a. a -> Maybe a
Just String
"POP"
simpleStack Word8
0x03 = String -> Maybe String
forall a. a -> Maybe a
Just String
"DUP"
simpleStack Word8
0x04 = String -> Maybe String
forall a. a -> Maybe a
Just String
"SWAP"
simpleStack Word8
_ = Maybe String
forall a. Maybe a
Nothing
simpleArith :: Word8 -> Maybe String
simpleArith :: Word8 -> Maybe String
simpleArith Word8
0x10 = String -> Maybe String
forall a. a -> Maybe a
Just String
"ADD"
simpleArith Word8
0x11 = String -> Maybe String
forall a. a -> Maybe a
Just String
"SUB"
simpleArith Word8
0x12 = String -> Maybe String
forall a. a -> Maybe a
Just String
"MUL"
simpleArith Word8
0x13 = String -> Maybe String
forall a. a -> Maybe a
Just String
"DIV"
simpleArith Word8
0x14 = String -> Maybe String
forall a. a -> Maybe a
Just String
"MOD"
simpleArith Word8
_ = Maybe String
forall a. Maybe a
Nothing
simpleLogic :: Word8 -> Maybe String
simpleLogic :: Word8 -> Maybe String
simpleLogic Word8
0x20 = String -> Maybe String
forall a. a -> Maybe a
Just String
"EQ"
simpleLogic Word8
0x21 = String -> Maybe String
forall a. a -> Maybe a
Just String
"LT"
simpleLogic Word8
0x22 = String -> Maybe String
forall a. a -> Maybe a
Just String
"NOT"
simpleLogic Word8
0x23 = String -> Maybe String
forall a. a -> Maybe a
Just String
"AND"
simpleLogic Word8
0x24 = String -> Maybe String
forall a. a -> Maybe a
Just String
"OR"
simpleLogic Word8
0x25 = String -> Maybe String
forall a. a -> Maybe a
Just String
"LE"
simpleLogic Word8
_ = Maybe String
forall a. Maybe a
Nothing
showHex2 :: Word8 -> String
showHex2 :: Word8 -> String
showHex2 Word8
w = let h :: String
h = String
"0123456789ABCDEF"
hi :: Int
hi = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Word8
w Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`shiftR` Int
4) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0xF)
lo :: Int
lo = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8
w Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0xF)
in [String
h String -> Int -> Char
forall a. HasCallStack => [a] -> Int -> a
!! Int
hi, String
h String -> Int -> Char
forall a. HasCallStack => [a] -> Int -> a
!! Int
lo]
immSize :: Word8 -> Int
immSize :: Word8 -> Int
immSize Word8
op = Int -> (Immediate -> Int) -> Maybe Immediate -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
1 Immediate -> Int
immediateSize (Word8 -> Maybe Immediate
lookupTypeID Word8
op)
lookupTypeID :: Word8 -> Maybe Immediate
lookupTypeID :: Word8 -> Maybe Immediate
lookupTypeID Word8
0x00 = Immediate -> Maybe Immediate
forall a. a -> Maybe a
Just (Bool -> Immediate
ImmBool Bool
False)
lookupTypeID Word8
0x01 = Immediate -> Maybe Immediate
forall a. a -> Maybe a
Just (IntValue -> Immediate
ImmInt (Int8 -> IntValue
I8 Int8
0))
lookupTypeID Word8
0x02 = Immediate -> Maybe Immediate
forall a. a -> Maybe a
Just (IntValue -> Immediate
ImmInt (Word8 -> IntValue
UI8 Word8
0))
lookupTypeID Word8
0x03 = Immediate -> Maybe Immediate
forall a. a -> Maybe a
Just (IntValue -> Immediate
ImmInt (Int16 -> IntValue
I16 Int16
0))
lookupTypeID Word8
0x04 = Immediate -> Maybe Immediate
forall a. a -> Maybe a
Just (IntValue -> Immediate
ImmInt (Word16 -> IntValue
UI16 Word16
0))
lookupTypeID Word8
op = Word8 -> Maybe Immediate
lookupLarge Word8
op
lookupLarge :: Word8 -> Maybe Immediate
lookupLarge :: Word8 -> Maybe Immediate
lookupLarge Word8
0x05 = Immediate -> Maybe Immediate
forall a. a -> Maybe a
Just (IntValue -> Immediate
ImmInt (Int32 -> IntValue
I32 Int32
0))
lookupLarge Word8
0x06 = Immediate -> Maybe Immediate
forall a. a -> Maybe a
Just (IntValue -> Immediate
ImmInt (Word32 -> IntValue
UI32 Word32
0))
lookupLarge Word8
0x07 = Immediate -> Maybe Immediate
forall a. a -> Maybe a
Just (IntValue -> Immediate
ImmInt (Int64 -> IntValue
I64 Int64
0))
lookupLarge Word8
0x08 = Immediate -> Maybe Immediate
forall a. a -> Maybe a
Just (IntValue -> Immediate
ImmInt (Word64 -> IntValue
UI64 Word64
0))
lookupLarge Word8
_ = Maybe Immediate
forall a. Maybe a
Nothing