{-# LANGUAGE DataKinds #-}

-- | This module contains the highest-level user-facing functions.
-- Typically, code using this library will want to call `readTIFile`
-- on a file name.
module Data.TI85.Parsers (
    -- * General TI Files
    readTIFile,
    parseTIHeader,
    parseTIFile,
    -- * Backup Files
    -- ** High-level Parsers
    parseTIBackupHeader,
    readUserMem,
    -- ** Lower-level Parsers
    readVarMem,
    extractVar,
    -- * Variable Files
    -- ** High-level Parsers
    readVariable,
    parseVariable,
    -- ** Lower-level Parsers
    parseProgram,
    parseTINumber,
    parseToken
    ) where

import Prelude hiding (take,takeWhile,putStrLn)
import Data.Char
import Data.Bits
import Data.Word
import Data.Array.Unboxed (Array, UArray, array, listArray, (!))
import Data.ByteString (ByteString, foldr')
import qualified Data.ByteString as BS
import Data.Text (Text)
import qualified Data.Text as T
import Data.Text.IO (putStrLn)
import Data.Attoparsec.ByteString
import Data.Attoparsec.Combinator (lookAhead)
import Control.Applicative
import Control.Monad (guard, when, forM)

import Data.TI85.Var
import Data.TI85.Var.Pic
import Data.TI85.Encoding
import Data.TI85.Token
import Data.TI85.File

bytes2Int :: ByteString -> Int
bytes2Int :: ByteString -> Int
bytes2Int = (Word8 -> Int -> Int) -> Int -> ByteString -> Int
forall a. (Word8 -> a -> a) -> a -> ByteString -> a
BS.foldr' (\Word8
w Int
x -> Int
256Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall a. Enum a => a -> Int
fromEnum Word8
w) Int
0

anyWord16 :: Parser Word16
anyWord16 :: Parser Word16
anyWord16 = do
    ByteString
bytes <- Int -> Parser ByteString
take Int
2
    let val :: Int
val = ByteString -> Int
bytes2Int ByteString
bytes
    Word16 -> Parser Word16
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Word16
forall a. Enum a => Int -> a
toEnum Int
val)

-- | Parse a general TI file, which might be
-- a variable file or backup file.
parseTIFile :: Parser TIFile
parseTIFile :: Parser TIFile
parseTIFile = do
    TIHeader
header <- Parser TIHeader
parseTIHeader
    (Word16
checksum, Word16
calcSum) <- Parser ByteString (Word16, Word16)
-> Parser ByteString (Word16, Word16)
forall i a. Parser i a -> Parser i a
lookAhead (Word16 -> Parser ByteString (Word16, Word16)
calculateSum (Word16 -> Parser ByteString (Word16, Word16))
-> Word16 -> Parser ByteString (Word16, Word16)
forall a b. (a -> b) -> a -> b
$ TIHeader -> Word16
hdrDataLen TIHeader
header)

    Bool -> Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word16
calcSum Word16 -> Word16 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word16
checksum) ([Char] -> Parser ByteString ()
forall a. HasCallStack => [Char] -> a
error [Char]
"Checkum check failed")

    TIFileData
contents <- 
        TIBackupData -> TIFileData
BackupData (TIBackupData -> TIFileData)
-> Parser ByteString TIBackupData -> Parser ByteString TIFileData
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString TIBackupData
parseTIBackupData
        Parser ByteString TIFileData
-> Parser ByteString TIFileData -> Parser ByteString TIFileData
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> TIVarData -> TIFileData
VariableData (TIVarData -> TIFileData)
-> Parser ByteString TIVarData -> Parser ByteString TIFileData
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString TIVarData
parseTIVarData

    TIFile -> Parser TIFile
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TIFile -> Parser TIFile) -> TIFile -> Parser TIFile
forall a b. (a -> b) -> a -> b
$ TIFile {
        tiHeader :: TIHeader
tiHeader = TIHeader
header,
        tiData :: TIFileData
tiData = TIFileData
contents,
        tiChecksum :: Word16
tiChecksum = Word16
checksum
        }
  where
    calculateSum :: Word16 -> Parser (Word16,Word16)
    calculateSum :: Word16 -> Parser ByteString (Word16, Word16)
calculateSum Word16
len = do
        ByteString
bytes <- Int -> Parser ByteString
take (Word16 -> Int
forall a. Enum a => a -> Int
fromEnum Word16
len)
        let sum :: Int
sum = (Word8 -> Int -> Int) -> Int -> ByteString -> Int
forall a. (Word8 -> a -> a) -> a -> ByteString -> a
foldr' (\Word8
w Int
s -> Word8 -> Int
forall a. Enum a => a -> Int
fromEnum Word8
w Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
s) (Int
0::Int) ByteString
bytes
        Word16
checksum <- Parser Word16
anyWord16
        (Word16, Word16) -> Parser ByteString (Word16, Word16)
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word16
checksum, Int -> Word16
forall a. Enum a => Int -> a
toEnum (Int -> Word16) -> Int -> Word16
forall a b. (a -> b) -> a -> b
$ Int
sum Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0xffff)

-- | Read a general TI file, which might be
-- a variable file or backup file.
readTIFile :: FilePath -> IO TIFile
readTIFile :: [Char] -> IO TIFile
readTIFile [Char]
fileName = do
    ByteString
contents <- [Char] -> IO ByteString
BS.readFile [Char]
fileName
    let tiFile :: Either [Char] TIFile
tiFile = Parser TIFile -> ByteString -> Either [Char] TIFile
forall a. Parser a -> ByteString -> Either [Char] a
parseOnly Parser TIFile
parseTIFile ByteString
contents
    ([Char] -> IO TIFile)
-> (TIFile -> IO TIFile) -> Either [Char] TIFile -> IO TIFile
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [Char] -> IO TIFile
forall a. HasCallStack => [Char] -> a
error TIFile -> IO TIFile
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Either [Char] TIFile
tiFile

-- | The backup header is a second header after
-- the top-level file header (`TIFile`).
-- It contains sizes of the three data sections
-- and the location of user memory in RAM (which
-- can use used with the variable table to look
-- up variable data).
parseTIBackupHeader :: Parser TIBackupHeader
parseTIBackupHeader :: Parser TIBackupHeader
parseTIBackupHeader = do
    ByteString
dataOffset <- ByteString -> Parser ByteString
string ByteString
"\x09\x00"
    Word16
len1 <- Parser Word16
anyWord16
    Word8
typeId <- Word8 -> Parser Word8
word8 Word8
0x1d
    Word16
len2 <- Parser Word16
anyWord16
    Word16
len3 <- Parser Word16
anyWord16
    Word16
addr <- Parser Word16
anyWord16
    TIBackupHeader -> Parser TIBackupHeader
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TIBackupHeader -> Parser TIBackupHeader)
-> TIBackupHeader -> Parser TIBackupHeader
forall a b. (a -> b) -> a -> b
$ TIBackupHeader {
        hdrDataLenOffset :: Word16
hdrDataLenOffset = Word16
0x9,
        hdrData1Len :: Word16
hdrData1Len = Word16
len1,
        hdrTypeID :: Word8
hdrTypeID = Word8
typeId,
        hdrData2Len :: Word16
hdrData2Len = Word16
len2,
        hdrData3Len :: Word16
hdrData3Len = Word16
len2,
        hdrData2Addr :: Word16
hdrData2Addr = Word16
addr
        }

parseVarTableEntry :: Parser VarTableEntry
parseVarTableEntry :: Parser VarTableEntry
parseVarTableEntry = do
    Word8
entId <- Parser Word8
anyWord8
    Word16
entAddr <- Parser Word16
anyWord16
    Word8
len <- Parser Word8
anyWord8
    ByteString
name <- Int -> Parser ByteString
take (Word8 -> Int
forall a. Enum a => a -> Int
fromEnum Word8
len)
    VarTableEntry -> Parser VarTableEntry
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (VarTableEntry -> Parser VarTableEntry)
-> VarTableEntry -> Parser VarTableEntry
forall a b. (a -> b) -> a -> b
$ VarTableEntry {
        entryId :: Word8
entryId = Word8
entId,
        entryAddr :: Word16
entryAddr = Word16
entAddr,
        entryNameLen :: Word8
entryNameLen = Word8
len,
        entryName :: ByteString
entryName = ByteString
name
        }

parseTIBackupData :: Parser TIBackupData
parseTIBackupData :: Parser ByteString TIBackupData
parseTIBackupData = do
    TIBackupHeader
backupHdr <- Parser TIBackupHeader
parseTIBackupHeader
    Word16
len1 <- Parser Word16
anyWord16
    ByteString
data1 <- Int -> Parser ByteString
take (Int -> Parser ByteString) -> Int -> Parser ByteString
forall a b. (a -> b) -> a -> b
$ Word16 -> Int
forall a. Enum a => a -> Int
fromEnum Word16
len1
    Word16
len2 <- Parser Word16
anyWord16
    ByteString
data2 <- Int -> Parser ByteString
take (Int -> Parser ByteString) -> Int -> Parser ByteString
forall a b. (a -> b) -> a -> b
$ Word16 -> Int
forall a. Enum a => a -> Int
fromEnum Word16
len2
    Word16
len3 <- Parser Word16
anyWord16
    ByteString
data3 <- Int -> Parser ByteString
take (Int -> Parser ByteString) -> Int -> Parser ByteString
forall a b. (a -> b) -> a -> b
$ Word16 -> Int
forall a. Enum a => a -> Int
fromEnum Word16
len3
    let vars :: Either [Char] [VarTableEntry]
vars = Parser [VarTableEntry]
-> ByteString -> Either [Char] [VarTableEntry]
forall a. Parser a -> ByteString -> Either [Char] a
parseOnly (Parser VarTableEntry -> Parser [VarTableEntry]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many' Parser VarTableEntry
parseVarTableEntry) (ByteString -> ByteString
BS.reverse ByteString
data3)
    TIBackupData -> Parser ByteString TIBackupData
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TIBackupData -> Parser ByteString TIBackupData)
-> TIBackupData -> Parser ByteString TIBackupData
forall a b. (a -> b) -> a -> b
$ TIBackupData {
        backupHeader :: TIBackupHeader
backupHeader = TIBackupHeader
backupHdr,
        data1Len :: Word16
data1Len = Word16
len1,
        data1 :: ByteString
data1 = ByteString
data1,
        data2Len :: Word16
data2Len = Word16
len2,
        data2 :: ByteString
data2 = ByteString
data2,
        varTableLen :: Word16
varTableLen = Word16
len3,
        varTable :: [VarTableEntry]
varTable = ([Char] -> [VarTableEntry])
-> ([VarTableEntry] -> [VarTableEntry])
-> Either [Char] [VarTableEntry]
-> [VarTableEntry]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [Char] -> [VarTableEntry]
forall a. HasCallStack => [Char] -> a
error [VarTableEntry] -> [VarTableEntry]
forall a. a -> a
id Either [Char] [VarTableEntry]
vars
        }

-- |The TI-85 header is common between backup files
-- and variable files.
--
-- +--------+---+---------------------------------+
-- | 8 Byte | 3 | 42 Byte                         |
-- +========+===+=================================+
-- |**TI85**|xyz| Comment                         |
-- +--------+---+---------------------------------+
--
-- where @xyz@ is always @0x1a,0x0c,0x00@.
parseTIHeader :: Parser TIHeader
parseTIHeader :: Parser TIHeader
parseTIHeader = do
    ByteString -> Parser ByteString
string ByteString
"**TI85**"
    ByteString -> Parser ByteString
string ByteString
"\x1a\x0c\x00"
    ByteString
rawComment <- Int -> Parser ByteString
take Int
42
    Word16
dataLen <- Parser Word16
anyWord16
    TIHeader -> Parser TIHeader
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TIHeader -> Parser TIHeader) -> TIHeader -> Parser TIHeader
forall a b. (a -> b) -> a -> b
$ TIHeader {
        hdrSig :: ByteString
hdrSig = ByteString
"**TI85**",
        hdrSig2 :: ByteString
hdrSig2 = ByteString
"\x1a\x0c\x00",
        hdrComment :: ByteString
hdrComment = (Word8 -> Bool) -> ByteString -> ByteString
BS.takeWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
0x0) ByteString
rawComment,
        hdrDataLen :: Word16
hdrDataLen = Word16
dataLen
        }

parseTIVar :: Parser TIVar
parseTIVar :: Parser TIVar
parseTIVar = do
    Word16
offset <- Parser Word16
anyWord16
    Word16
len <- Parser Word16
anyWord16
    Word8
varType <- Parser Word8
anyWord8
    Word8
nameLen <- Parser Word8
anyWord8
    ByteString
name <- Int -> Parser ByteString
take (Word8 -> Int
forall a. Enum a => a -> Int
fromEnum Word8
nameLen)
    Word16
dataLen <- Parser Word16
anyWord16
    ByteString
var <- Int -> Parser ByteString
take (Word16 -> Int
forall a. Enum a => a -> Int
fromEnum Word16
dataLen)
    TIVar -> Parser TIVar
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TIVar -> Parser TIVar) -> TIVar -> Parser TIVar
forall a b. (a -> b) -> a -> b
$ TIVar {
       varOffset :: Word16
varOffset = Word16
offset,
       varLen :: Word16
varLen = Word16
len,
       varId :: Word8
varId = Word8
varType,
       varNameLen :: Word8
varNameLen = Word8
nameLen,
       varName :: ByteString
varName = ByteString
name,
       varDataLen :: Word16
varDataLen = Word16
dataLen,
       varData :: ByteString
varData = ByteString
var
       }

parseTIVarData :: Parser TIVarData
parseTIVarData :: Parser ByteString TIVarData
parseTIVarData = [TIVar] -> TIVarData
TIVarData ([TIVar] -> TIVarData)
-> Parser ByteString [TIVar] -> Parser ByteString TIVarData
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TIVar -> Parser ByteString [TIVar]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many1' Parser TIVar
parseTIVar

-- |Programs are either plain text, ot encoded in a
-- tokenized format. See "Data.TI85.Token" for the 
-- mapping.
parseProgram :: Parser Program
parseProgram :: Parser Program
parseProgram = do
    Int
len <- Word16 -> Int
forall a. Enum a => a -> Int
fromEnum (Word16 -> Int) -> Parser Word16 -> Parser ByteString Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word16
anyWord16
    Word8
encoding <- Parser Word8
peekWord8'
    case Word8
encoding of
        Word8
0x00 -> do
            Parser Word8
anyWord8
            Text -> Program
PlainText (Text -> Program) -> Parser ByteString Text -> Parser Program
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser ByteString Text
parsePlaintext (Int
lenInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
        Word8
_ -> [Token] -> Program
Tokenized ([Token] -> Program) -> Parser ByteString [Token] -> Parser Program
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser ByteString [Token]
parseTokenized Int
len

parsePlaintext :: Int -> Parser Text
parsePlaintext :: Int -> Parser ByteString Text
parsePlaintext Int
len = do
    ByteString
bytes <- Int -> Parser ByteString
take Int
len
    Text -> Parser ByteString Text
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Parser ByteString Text) -> Text -> Parser ByteString Text
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
tiDecode ByteString
bytes

parseTokenized :: Int -> Parser [Token]
parseTokenized :: Int -> Parser ByteString [Token]
parseTokenized Int
len = do
    ByteString
bytes <- Int -> Parser ByteString
take Int
len
    let tokenResult :: Either [Char] [Token]
tokenResult = Parser ByteString [Token] -> ByteString -> Either [Char] [Token]
forall a. Parser a -> ByteString -> Either [Char] a
parseOnly (Parser ByteString Token -> Parser ByteString [Token]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many' Parser ByteString Token
parseToken) ByteString
bytes
    ([Char] -> Parser ByteString [Token])
-> ([Token] -> Parser ByteString [Token])
-> Either [Char] [Token]
-> Parser ByteString [Token]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [Char] -> Parser ByteString [Token]
forall a. HasCallStack => [Char] -> a
error [Token] -> Parser ByteString [Token]
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return Either [Char] [Token]
tokenResult
        
-- |Interpret data as a token (or token stream)
parseToken :: Parser Token
parseToken :: Parser ByteString Token
parseToken = do
    Word8
tokenByte <- Parser Word8
anyWord8
    let token :: TokenDef
token = Array Word8 TokenDef
tokenTable Array Word8 TokenDef -> Word8 -> TokenDef
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Word8
tokenByte
    Text
tokenText <- case TokenDef
token of
        TokenDef
Invalid -> Text -> Parser ByteString Text
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return Text
T.empty
        Fixed Text
t -> Text -> Parser ByteString Text
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return Text
t
        TokenDef
QuoteText -> do
            Text
t <- Parser ByteString Text
zeroTerminated
            Text -> Parser ByteString Text
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Parser ByteString Text) -> Text -> Parser ByteString Text
forall a b. (a -> b) -> a -> b
$  Char
'"' Char -> Text -> Text
`T.cons` Text
t Text -> Char -> Text
`T.snoc` Char
'"'
        TokenDef
NameLength -> Parser ByteString Text
varLength
        FixedLength Int
n -> ByteString -> Text
tiDecode (ByteString -> Text) -> Parser ByteString -> Parser ByteString Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser ByteString
take Int
n
        TokenDef
Extended -> do
            Word8
extToken <- Parser Word8
anyWord8
            case Array Word8 TokenDef
tokenTableExtended Array Word8 TokenDef -> Word8 -> TokenDef
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Word8
extToken of
                Fixed Text
ext -> Text -> Parser ByteString Text
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return Text
ext
                TokenDef
_ -> Text -> Parser ByteString Text
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return Text
T.empty
        TokenDef
Conversion -> do
            Text
unit1 <- Parser ByteString Text
varLength
            Text
unit2 <- Parser ByteString Text
varLength
            Text -> Parser ByteString Text
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Parser ByteString Text) -> Text -> Parser ByteString Text
forall a b. (a -> b) -> a -> b
$ Text -> [Text] -> Text
T.intercalate Text
"->" [Text
unit1,Text
unit2]
        TokenDef
Literal -> Parser ByteString Text
zeroTerminated
        TokenDef
Label -> do
            Text
label <- Parser ByteString Text
zeroTerminated
            Text -> Parser ByteString Text
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Parser ByteString Text) -> Text -> Parser ByteString Text
forall a b. (a -> b) -> a -> b
$ Text
"Lbl " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
label
        TokenDef
Goto -> do
            Word16
mystery <- Parser Word16
anyWord16
            Text
label <- Parser ByteString Text
zeroTerminated
            Text -> Parser ByteString Text
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Parser ByteString Text) -> Text -> Parser ByteString Text
forall a b. (a -> b) -> a -> b
$ Text
"Goto " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
label
    Token -> Parser ByteString Token
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> Parser ByteString Token)
-> Token -> Parser ByteString Token
forall a b. (a -> b) -> a -> b
$ TokenDef -> Text -> Token
Token TokenDef
token Text
tokenText
  where
    zeroTerminated :: Parser ByteString Text
zeroTerminated = do
        ByteString
bytes <- (Word8 -> Bool) -> Parser ByteString
takeWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
0x0)
        Word8
zero <- Word8 -> Parser Word8
word8 Word8
0x0
        Text -> Parser ByteString Text
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Parser ByteString Text) -> Text -> Parser ByteString Text
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
tiDecode ByteString
bytes
    varLength :: Parser ByteString Text
varLength = do
        Word8
len <- Parser Word8
anyWord8
        ByteString
bytes <- Int -> Parser ByteString
take (Word8 -> Int
forall a. Enum a => a -> Int
fromEnum Word8
len)
        Text -> Parser ByteString Text
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Parser ByteString Text) -> Text -> Parser ByteString Text
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
tiDecode ByteString
bytes

bcd :: ByteString -> Double
bcd :: ByteString -> Double
bcd ByteString
bytes = (Int, Double) -> Double
forall a b. (a, b) -> b
snd ((Int, Double) -> Double) -> (Int, Double) -> Double
forall a b. (a -> b) -> a -> b
$ ((Int, Double) -> Word8 -> (Int, Double))
-> (Int, Double) -> ByteString -> (Int, Double)
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
BS.foldl' (Int, Double) -> Word8 -> (Int, Double)
accDecimal (Int
0,Double
0.0) ByteString
bytes
  where
    accDecimal :: (Int, Double) -> Word8 -> (Int, Double)
    accDecimal :: (Int, Double) -> Word8 -> (Int, Double)
accDecimal (Int
place, Double
value) Word8
byte =
        let (Word8
high,Word8
low) = Word8 -> (Word8, Word8)
toNibbles Word8
byte
            highVal :: Double
highVal = Word8 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
high Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
10.0 Double -> Double -> Double
forall a. Floating a => a -> a -> a
** Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
place
            lowVal :: Double
lowVal = Word8 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
low Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
10.0 Double -> Double -> Double
forall a. Floating a => a -> a -> a
** Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
placeInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
        in (Int
placeInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
2, Double
valueDouble -> Double -> Double
forall a. Num a => a -> a -> a
+Double
highValDouble -> Double -> Double
forall a. Num a => a -> a -> a
+Double
lowVal)
    toNibbles :: Word8 -> (Word8,Word8)
    toNibbles :: Word8 -> (Word8, Word8)
toNibbles Word8
byte =
        let low :: Word8
low = Word8
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x0f
            high :: Word8
high = Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
shiftR Word8
byte Int
4 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x0f
        in (Word8
high,Word8
low)

-- |Numeric values can either be real or complex, and most variable
-- types can store either.
parseTINumber :: Parser TINumber
parseTINumber :: Parser TINumber
parseTINumber = do
    (Word8
realFlags, Double
realPart) <- Parser (Word8, Double)
parseReal
    let isComplex :: Bool
isComplex = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
realFlags Int
0
    if Bool
isComplex
        then do
            (Word8
_imagFlags, Double
imagPart) <- Parser (Word8, Double)
parseReal
            TINumber -> Parser TINumber
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TINumber -> Parser TINumber) -> TINumber -> Parser TINumber
forall a b. (a -> b) -> a -> b
$ Double -> Double -> TINumber
TIComplex Double
realPart Double
imagPart
        else TINumber -> Parser TINumber
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TINumber -> Parser TINumber) -> TINumber -> Parser TINumber
forall a b. (a -> b) -> a -> b
$ Double -> TINumber
TIReal Double
realPart
  where
    parseReal :: Parser (Word8, Double)
    parseReal :: Parser (Word8, Double)
parseReal = do
        Word8
flags <- Parser Word8
anyWord8
        Word16
expRaw <- Parser Word16
anyWord16
        let exp :: Int
exp = Word16 -> Int
forall a. Enum a => a -> Int
fromEnum Word16
expRaw Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
0xFC00
        Double
mantissa <- ByteString -> Double
bcd (ByteString -> Double)
-> Parser ByteString -> Parser ByteString Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser ByteString
take Int
7
        let sign :: Bool
sign = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
flags Int
7
        let value :: Double
value = Double
mantissa Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
10 Double -> Double -> Double
forall a. Floating a => a -> a -> a
** Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
exp
        let signedValue :: Double
signedValue = if Bool
sign
            then -Double
1.0 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
value
            else Double
value
        (Word8, Double) -> Parser (Word8, Double)
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
flags,Double
signedValue)

parsePicture :: Parser TIBitmap
parsePicture :: Parser TIBitmap
parsePicture = do
    Word8 -> Parser Word8
word8 Word8
0xf0
    Word8 -> Parser Word8
word8 Word8
0x03
    ByteString
pic <- Int -> Parser ByteString
take Int
1008
    case ByteString -> Maybe TIBitmap
fromBytes ByteString
pic of
        Just TIBitmap
tiPic -> TIBitmap -> Parser TIBitmap
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return TIBitmap
tiPic
        Maybe TIBitmap
Nothing -> [Char] -> Parser TIBitmap
forall a. [Char] -> Parser ByteString a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail [Char]
"Wrong size of picture bitmap"

-- |Parser for the elements contained a variable file
-- that has possibly more than one 
parseVariable :: VarType -> Parser Variable
parseVariable :: VarType -> Parser Variable
parseVariable (VarValue VarField
_) = TINumber -> Variable
TIScalar (TINumber -> Variable) -> Parser TINumber -> Parser Variable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TINumber
parseTINumber
parseVariable (VarVector VarField
_) = do
    Word8
alwaysOne <- Parser Word8
anyWord8
    Int
len <- Word8 -> Int
forall a. Enum a => a -> Int
fromEnum (Word8 -> Int) -> Parser Word8 -> Parser ByteString Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8
anyWord8
    [TINumber]
vals <- Int -> Parser TINumber -> Parser ByteString [TINumber]
forall (m :: * -> *) a. Monad m => Int -> m a -> m [a]
count Int
len Parser TINumber
parseTINumber
    Variable -> Parser Variable
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Variable -> Parser Variable) -> Variable -> Parser Variable
forall a b. (a -> b) -> a -> b
$ [TINumber] -> Variable
TIVector [TINumber]
vals
parseVariable (VarList VarField
_) = do
    Int
len <- Word16 -> Int
forall a. Enum a => a -> Int
fromEnum (Word16 -> Int) -> Parser Word16 -> Parser ByteString Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word16
anyWord16
    [TINumber]
vals <- Int -> Parser TINumber -> Parser ByteString [TINumber]
forall (m :: * -> *) a. Monad m => Int -> m a -> m [a]
count Int
len Parser TINumber
parseTINumber
    Variable -> Parser Variable
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Variable -> Parser Variable) -> Variable -> Parser Variable
forall a b. (a -> b) -> a -> b
$ [TINumber] -> Variable
TIList [TINumber]
vals
parseVariable (VarMatrix VarField
_) = do
    Int
numCols <- Word8 -> Int
forall a. Enum a => a -> Int
fromEnum (Word8 -> Int) -> Parser Word8 -> Parser ByteString Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8
anyWord8
    Int
numRows <- Word8 -> Int
forall a. Enum a => a -> Int
fromEnum (Word8 -> Int) -> Parser Word8 -> Parser ByteString Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8
anyWord8
    [[TINumber]]
vals <- Int
-> Parser ByteString [TINumber] -> Parser ByteString [[TINumber]]
forall (m :: * -> *) a. Monad m => Int -> m a -> m [a]
count Int
numRows (Int -> Parser TINumber -> Parser ByteString [TINumber]
forall (m :: * -> *) a. Monad m => Int -> m a -> m [a]
count Int
numCols Parser TINumber
parseTINumber)
    Variable -> Parser Variable
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Variable -> Parser Variable) -> Variable -> Parser Variable
forall a b. (a -> b) -> a -> b
$ [[TINumber]] -> Variable
TIMatrix [[TINumber]]
vals
parseVariable (VarConstant VarField
_) = TINumber -> Variable
TIConstant (TINumber -> Variable) -> Parser TINumber -> Parser Variable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TINumber
parseTINumber
parseVariable VarType
VarEquation = do
    Int
len <- Word16 -> Int
forall a. Enum a => a -> Int
fromEnum (Word16 -> Int) -> Parser Word16 -> Parser ByteString Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word16
anyWord16
    [Token]
tokens <- Int -> Parser ByteString [Token]
parseTokenized Int
len
    let tokenText :: [Text]
tokenText = (Token -> Text) -> [Token] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (\(Token TokenDef
_ Text
t) -> Text
t) [Token]
tokens
    let eqText :: Text
eqText = [Text] -> Text
T.concat [Text]
tokenText
    Variable -> Parser Variable
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Variable -> Parser Variable) -> Variable -> Parser Variable
forall a b. (a -> b) -> a -> b
$ Text -> Variable
TIEquation Text
eqText
parseVariable VarType
VarString = do
    Int
len <- Word16 -> Int
forall a. Enum a => a -> Int
fromEnum (Word16 -> Int) -> Parser Word16 -> Parser ByteString Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word16
anyWord16
    Text -> Variable
TIString (Text -> Variable) -> Parser ByteString Text -> Parser Variable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser ByteString Text
parsePlaintext Int
len
parseVariable VarType
VarProgram = Program -> Variable
TIProgram (Program -> Variable) -> Parser Program -> Parser Variable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Program
parseProgram
parseVariable VarType
VarPicture = TIBitmap -> Variable
TIPicture (TIBitmap -> Variable) -> Parser TIBitmap -> Parser Variable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TIBitmap
parsePicture
parseVariable VarType
VarSettingsFunc = FuncSettings -> Variable
TIFuncSettings (FuncSettings -> Variable)
-> Parser ByteString FuncSettings -> Parser Variable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString FuncSettings
parseFuncSettings
parseVariable VarType
VarSettingsPolar = PolarSettings -> Variable
TIPolarSettings (PolarSettings -> Variable)
-> Parser ByteString PolarSettings -> Parser Variable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString PolarSettings
parsePolarSettings
parseVariable VarType
VarSettingsParam = ParamSettings -> Variable
TIParamSettings (ParamSettings -> Variable)
-> Parser ByteString ParamSettings -> Parser Variable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ParamSettings
parseParamSettings
parseVariable VarType
VarSettingsDiff = DiffEqSettings -> Variable
TIDiffEqSettings (DiffEqSettings -> Variable)
-> Parser ByteString DiffEqSettings -> Parser Variable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString DiffEqSettings
parseDiffEqSettings
parseVariable VarType
VarSavedWinSize = SavedWinSettings -> Variable
TIZRCL (SavedWinSettings -> Variable)
-> Parser ByteString SavedWinSettings -> Parser Variable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString SavedWinSettings
parseWinSettings
parseVariable VarType
VarGDBFunc = GDB 'Func -> Variable
TIFuncGDB (GDB 'Func -> Variable)
-> Parser ByteString (GDB 'Func) -> Parser Variable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString (GDB 'Func)
parseFuncGDB
parseVariable VarType
VarUnknown = Variable -> Parser Variable
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Variable -> Parser Variable) -> Variable -> Parser Variable
forall a b. (a -> b) -> a -> b
$ Text -> Variable
TIString Text
"?"
parseVariable VarType
_ = Variable -> Parser Variable
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Variable -> Parser Variable) -> Variable -> Parser Variable
forall a b. (a -> b) -> a -> b
$ Text -> Variable
TIString Text
"(not implemented)"

parseModeSettings :: Parser ModeSettings
parseModeSettings :: Parser ModeSettings
parseModeSettings = do
    Word8
modeByte <- Parser Word8
anyWord8
    let drawDot :: Bool
drawDot = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
modeByte Int
0
        simulG :: Bool
simulG = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
modeByte Int
1
        gridOn :: Bool
gridOn = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
modeByte Int
2
        polarGC :: Bool
polarGC = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
modeByte Int
3
        coordOff :: Bool
coordOff = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
modeByte Int
4
        axesOff :: Bool
axesOff = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
modeByte Int
5
        labelOb :: Bool
labelOb = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
modeByte Int
6
    ModeSettings -> Parser ModeSettings
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (ModeSettings -> Parser ModeSettings)
-> ModeSettings -> Parser ModeSettings
forall a b. (a -> b) -> a -> b
$ ModeSettings {
        modeDrawDot :: Bool
modeDrawDot = Bool
drawDot,
        modeSimulG :: Bool
modeSimulG = Bool
simulG,
        modeGridOn :: Bool
modeGridOn = Bool
gridOn,
        modePolarGC :: Bool
modePolarGC = Bool
polarGC,
        modeCoordOff :: Bool
modeCoordOff = Bool
coordOff,
        modeAxesOff :: Bool
modeAxesOff = Bool
axesOff,
        modeLabelOn :: Bool
modeLabelOn = Bool
labelOb
        }

parseFuncGDB :: Parser (GDB Func)
parseFuncGDB :: Parser ByteString (GDB 'Func)
parseFuncGDB = do
    Word16
len <- Parser Word16
anyWord16
    ModeSettings
mode <- Parser ModeSettings
parseModeSettings
    FuncSettings
settings <- Parser ByteString FuncSettings
parseBareFuncSettings
    Int
numFunc <- Word8 -> Int
forall a. Enum a => a -> Int
fromEnum (Word8 -> Int) -> Parser Word8 -> Parser ByteString Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word8 -> Bool) -> Parser Word8
satisfy (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<=Word8
99)
    [GDBLibEntry 'Func]
lib <- Int
-> Parser ByteString (GDBLibEntry 'Func)
-> Parser ByteString [GDBLibEntry 'Func]
forall (m :: * -> *) a. Monad m => Int -> m a -> m [a]
count Int
numFunc Parser ByteString (GDBLibEntry 'Func)
parseFuncEntry
    GDB 'Func -> Parser ByteString (GDB 'Func)
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (GDB 'Func -> Parser ByteString (GDB 'Func))
-> GDB 'Func -> Parser ByteString (GDB 'Func)
forall a b. (a -> b) -> a -> b
$ GDB {
        gdbMode :: ModeSettings
gdbMode = ModeSettings
mode,
        gdbSettings :: GDBSettings 'Func
gdbSettings = GDBSettings 'Func
FuncSettings
settings,
        gdbLib :: [GDBLibEntry 'Func]
gdbLib = [GDBLibEntry 'Func]
lib
        }

parseFuncEntry :: Parser (GDBLibEntry Func)
parseFuncEntry :: Parser ByteString (GDBLibEntry 'Func)
parseFuncEntry = do
    Word8
idByte <- Parser Word8
anyWord8
    let selected :: Bool
selected = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
idByte Int
7
        funcId :: Word8
funcId = Word8
idByte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x7f
    (TIEquation Text
eqn) <- VarType -> Parser Variable
parseVariable VarType
VarEquation
    GDBLibEntry 'Func -> Parser ByteString (GDBLibEntry 'Func)
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (GDBLibEntry 'Func -> Parser ByteString (GDBLibEntry 'Func))
-> GDBLibEntry 'Func -> Parser ByteString (GDBLibEntry 'Func)
forall a b. (a -> b) -> a -> b
$ GDBLibEntry {
        libId :: Int
libId = Word8 -> Int
forall a. Enum a => a -> Int
fromEnum Word8
funcId,
        libSelected :: Bool
libSelected = Bool
selected,
        libEqn :: GDBEqn 'Func
libEqn = Text
GDBEqn 'Func
eqn
        }
{-
0 	2 bytes 	Length, in bytes, of GDB, minus two.
2 	1 byte 	Mode settings (see mode setting table below)
3 	10 bytes 	A real number: xMin
13 (Dh) 	10 bytes 	A real number: xMax
23 (17h) 	10 bytes 	A real number: xScl
33 (21h) 	10 bytes 	A real number: yMin
43 (2Bh) 	10 bytes 	A real number: yMax
53 (35h) 	10 bytes 	A real number: yScl
63 (3Fh) 	10 bytes 	A real number: xRes
73 (49h) 	1 byte 	Number of functions defined (up to 99)
74 (4Ah) 	n bytes 	Function table - several function definitions one after another (see function table below)
-}

parseBareFuncSettings :: Parser FuncSettings
parseBareFuncSettings :: Parser ByteString FuncSettings
parseBareFuncSettings = do
    TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> FuncSettings
FuncSettings
        (TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> FuncSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber -> TINumber -> TINumber -> TINumber -> FuncSettings)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TINumber
parseTINumber -- fXMin
        Parser
  ByteString
  (TINumber
   -> TINumber -> TINumber -> TINumber -> TINumber -> FuncSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber -> TINumber -> TINumber -> TINumber -> FuncSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- fXMax
        Parser
  ByteString
  (TINumber -> TINumber -> TINumber -> TINumber -> FuncSettings)
-> Parser TINumber
-> Parser
     ByteString (TINumber -> TINumber -> TINumber -> FuncSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- fXScl
        Parser
  ByteString (TINumber -> TINumber -> TINumber -> FuncSettings)
-> Parser TINumber
-> Parser ByteString (TINumber -> TINumber -> FuncSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- fYMin
        Parser ByteString (TINumber -> TINumber -> FuncSettings)
-> Parser TINumber -> Parser ByteString (TINumber -> FuncSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- fYMax
        Parser ByteString (TINumber -> FuncSettings)
-> Parser TINumber -> Parser ByteString FuncSettings
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- fYScl

parseFuncSettings :: Parser FuncSettings
parseFuncSettings :: Parser ByteString FuncSettings
parseFuncSettings = do
    Word8 -> Parser Word8
word8 Word8
0x51
    Word8 -> Parser Word8
word8 Word8
0x00
    Parser Word8
anyWord8
    FuncSettings
val <- Parser ByteString FuncSettings
parseBareFuncSettings
    Int -> Parser ByteString
take Int
20
    FuncSettings -> Parser ByteString FuncSettings
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return FuncSettings
val

parsePolarSettings :: Parser PolarSettings
parsePolarSettings :: Parser ByteString PolarSettings
parsePolarSettings = do
    Word8 -> Parser Word8
word8 Word8
0x5b
    Word8 -> Parser Word8
word8 Word8
0x00
    Parser Word8
anyWord8
    TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> PolarSettings
PolarSettings
        (TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> PolarSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> PolarSettings)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TINumber
parseTINumber -- polThetaMin
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> PolarSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> PolarSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- polThetaMax
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> PolarSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> PolarSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- polThetaStep
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> PolarSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber -> TINumber -> TINumber -> TINumber -> PolarSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- polXMin
        Parser
  ByteString
  (TINumber
   -> TINumber -> TINumber -> TINumber -> TINumber -> PolarSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber -> TINumber -> TINumber -> TINumber -> PolarSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- polXMax
        Parser
  ByteString
  (TINumber -> TINumber -> TINumber -> TINumber -> PolarSettings)
-> Parser TINumber
-> Parser
     ByteString (TINumber -> TINumber -> TINumber -> PolarSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- polXScl
        Parser
  ByteString (TINumber -> TINumber -> TINumber -> PolarSettings)
-> Parser TINumber
-> Parser ByteString (TINumber -> TINumber -> PolarSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- polYMin
        Parser ByteString (TINumber -> TINumber -> PolarSettings)
-> Parser TINumber -> Parser ByteString (TINumber -> PolarSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- polYMax
        Parser ByteString (TINumber -> PolarSettings)
-> Parser TINumber -> Parser ByteString PolarSettings
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- polYScl

parseParamSettings :: Parser ParamSettings
parseParamSettings :: Parser ByteString ParamSettings
parseParamSettings = do
    Word8 -> Parser Word8
word8 Word8
0x5b
    Word8 -> Parser Word8
word8 Word8
0x00
    Parser Word8
anyWord8
    TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> ParamSettings
ParamSettings
        (TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> ParamSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> ParamSettings)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TINumber
parseTINumber -- parTMin
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> ParamSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> ParamSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- parTMax
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> ParamSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> ParamSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- parTStep
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> ParamSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber -> TINumber -> TINumber -> TINumber -> ParamSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- parXMin
        Parser
  ByteString
  (TINumber
   -> TINumber -> TINumber -> TINumber -> TINumber -> ParamSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber -> TINumber -> TINumber -> TINumber -> ParamSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- parXMax
        Parser
  ByteString
  (TINumber -> TINumber -> TINumber -> TINumber -> ParamSettings)
-> Parser TINumber
-> Parser
     ByteString (TINumber -> TINumber -> TINumber -> ParamSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- parXScl
        Parser
  ByteString (TINumber -> TINumber -> TINumber -> ParamSettings)
-> Parser TINumber
-> Parser ByteString (TINumber -> TINumber -> ParamSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- parYMin
        Parser ByteString (TINumber -> TINumber -> ParamSettings)
-> Parser TINumber -> Parser ByteString (TINumber -> ParamSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- parYMax
        Parser ByteString (TINumber -> ParamSettings)
-> Parser TINumber -> Parser ByteString ParamSettings
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- parYScl

parseDiffEqSettings :: Parser DiffEqSettings
parseDiffEqSettings :: Parser ByteString DiffEqSettings
parseDiffEqSettings = do
    Word8 -> Parser Word8
word8 Word8
0x71
    Word8 -> Parser Word8
word8 Word8
0x00
    Parser Word8
anyWord8
    TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> DiffEqAxis
-> DiffEqAxis
-> DiffEqSettings
DiffEqSettings
        (TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> DiffEqAxis
 -> DiffEqAxis
 -> DiffEqSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> DiffEqAxis
      -> DiffEqAxis
      -> DiffEqSettings)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TINumber
parseTINumber -- diffTol
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> DiffEqAxis
   -> DiffEqAxis
   -> DiffEqSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> DiffEqAxis
      -> DiffEqAxis
      -> DiffEqSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- diffTPlot
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> DiffEqAxis
   -> DiffEqAxis
   -> DiffEqSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> DiffEqAxis
      -> DiffEqAxis
      -> DiffEqSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- diffTMin
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> DiffEqAxis
   -> DiffEqAxis
   -> DiffEqSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> DiffEqAxis
      -> DiffEqAxis
      -> DiffEqSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- diffTMax
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> DiffEqAxis
   -> DiffEqAxis
   -> DiffEqSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> DiffEqAxis
      -> DiffEqAxis
      -> DiffEqSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- diffTStep
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> DiffEqAxis
   -> DiffEqAxis
   -> DiffEqSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> DiffEqAxis
      -> DiffEqAxis
      -> DiffEqSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- diffXMin
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> DiffEqAxis
   -> DiffEqAxis
   -> DiffEqSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> DiffEqAxis
      -> DiffEqAxis
      -> DiffEqSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- diffXMax
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> DiffEqAxis
   -> DiffEqAxis
   -> DiffEqSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> DiffEqAxis
      -> DiffEqAxis
      -> DiffEqSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- diffXScl
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> DiffEqAxis
   -> DiffEqAxis
   -> DiffEqSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber -> DiffEqAxis -> DiffEqAxis -> DiffEqSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- diffYMin
        Parser
  ByteString
  (TINumber
   -> TINumber -> DiffEqAxis -> DiffEqAxis -> DiffEqSettings)
-> Parser TINumber
-> Parser
     ByteString (TINumber -> DiffEqAxis -> DiffEqAxis -> DiffEqSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- diffYMax
        Parser
  ByteString (TINumber -> DiffEqAxis -> DiffEqAxis -> DiffEqSettings)
-> Parser TINumber
-> Parser ByteString (DiffEqAxis -> DiffEqAxis -> DiffEqSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- diffYScl
        Parser ByteString (DiffEqAxis -> DiffEqAxis -> DiffEqSettings)
-> Parser ByteString DiffEqAxis
-> Parser ByteString (DiffEqAxis -> DiffEqSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString DiffEqAxis
parseAxis -- diffXAxis
        Parser ByteString (DiffEqAxis -> DiffEqSettings)
-> Parser ByteString DiffEqAxis -> Parser ByteString DiffEqSettings
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString DiffEqAxis
parseAxis -- diffYAxis
  where
    parseAxis :: Parser DiffEqAxis
    parseAxis :: Parser ByteString DiffEqAxis
parseAxis = do
        Word8
axisCode <- Parser Word8
anyWord8
        DiffEqAxis -> Parser ByteString DiffEqAxis
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (DiffEqAxis -> Parser ByteString DiffEqAxis)
-> DiffEqAxis -> Parser ByteString DiffEqAxis
forall a b. (a -> b) -> a -> b
$ case Word8
axisCode of
            Word8
0x0 -> DiffEqAxis
AxisT
            Word8
w | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x10 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x19 ->
                AxisInd -> DiffEqAxis
AxisQ (Int -> AxisInd
forall a. Enum a => Int -> a
toEnum (Word8 -> Int
forall a. Enum a => a -> Int
fromEnum Word8
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
0x10))
            Word8
w | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
0x20 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x29 ->
                AxisInd -> DiffEqAxis
AxisQ' (Int -> AxisInd
forall a. Enum a => Int -> a
toEnum (Word8 -> Int
forall a. Enum a => a -> Int
fromEnum Word8
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
0x20))
            Word8
_ -> [Char] -> DiffEqAxis
forall a. HasCallStack => [Char] -> a
error [Char]
"Invalid axis code"

parseWinSettings :: Parser SavedWinSettings
parseWinSettings :: Parser ByteString SavedWinSettings
parseWinSettings = do
    Word8 -> Parser Word8
word8 Word8
0x82
    Word8 -> Parser Word8
word8 Word8
0x00
    TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> TINumber
-> SavedWinSettings
SavedWinSettings
        (TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> TINumber
 -> SavedWinSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> SavedWinSettings)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TINumber
parseTINumber -- zThetaMin
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> SavedWinSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> SavedWinSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- zThetaMax
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> SavedWinSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> SavedWinSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- zThetaStep
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> SavedWinSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> SavedWinSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- ztPlot
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> SavedWinSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> SavedWinSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- ztMin
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> SavedWinSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> SavedWinSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- ztMax
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> SavedWinSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> SavedWinSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- ztStep
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> SavedWinSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> TINumber
      -> SavedWinSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- zxMin
        Parser
  ByteString
  (TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> TINumber
   -> SavedWinSettings)
-> Parser TINumber
-> Parser
     ByteString
     (TINumber -> TINumber -> TINumber -> TINumber -> SavedWinSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- zxMax
        Parser
  ByteString
  (TINumber -> TINumber -> TINumber -> TINumber -> SavedWinSettings)
-> Parser TINumber
-> Parser
     ByteString (TINumber -> TINumber -> TINumber -> SavedWinSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- zxScl
        Parser
  ByteString (TINumber -> TINumber -> TINumber -> SavedWinSettings)
-> Parser TINumber
-> Parser ByteString (TINumber -> TINumber -> SavedWinSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- zyMin
        Parser ByteString (TINumber -> TINumber -> SavedWinSettings)
-> Parser TINumber
-> Parser ByteString (TINumber -> SavedWinSettings)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- zyMax
        Parser ByteString (TINumber -> SavedWinSettings)
-> Parser TINumber -> Parser ByteString SavedWinSettings
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TINumber
parseTINumber -- zyScl

parseUserMem :: Word16 -> VarTable -> Parser [Variable]
parseUserMem :: Word16 -> [VarTableEntry] -> Parser [Variable]
parseUserMem Word16
baseAddr [VarTableEntry]
vars = do
    [VarTableEntry]
-> (VarTableEntry -> Parser Variable) -> Parser [Variable]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [VarTableEntry]
vars (Word16 -> VarTableEntry -> Parser Variable
extractVar Word16
baseAddr)

-- | Parse a variable out of user memory, without
-- consuming any input (hence "extract"). This allows
-- many calls on the same memory. The base address
-- is required for converting the variable addresses
-- in the table to offsets into the user memory backup.
extractVar :: Word16 -> VarTableEntry -> Parser Variable
extractVar :: Word16 -> VarTableEntry -> Parser Variable
extractVar Word16
baseAddr (VarTableEntry Word8
idNum Word16
addr Word8
_ ByteString
name) = do
    let offset :: Int
offset = Word16 -> Int
forall a. Enum a => a -> Int
fromEnum (Word16 -> Int) -> Word16 -> Int
forall a b. (a -> b) -> a -> b
$ Word16
addr Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
- Word16
baseAddr
    Parser Variable -> Parser Variable
forall i a. Parser i a -> Parser i a
lookAhead (Parser Variable -> Parser Variable)
-> Parser Variable -> Parser Variable
forall a b. (a -> b) -> a -> b
$ Int -> Parser ByteString
take Int
offset Parser ByteString -> Parser Variable -> Parser Variable
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> VarType -> Parser Variable
parseVariable (Word8 -> VarType
idToType Word8
idNum)

-- | Given a bytestring of user memory, look up the variable
-- table entry and return a `Variable`.
readVarMem :: Word16 -> VarTableEntry -> ByteString -> Variable
readVarMem :: Word16 -> VarTableEntry -> ByteString -> Variable
readVarMem Word16
baseAddr VarTableEntry
entry ByteString
userData =
    let var :: Either [Char] Variable
var = Parser Variable -> ByteString -> Either [Char] Variable
forall a. Parser a -> ByteString -> Either [Char] a
parseOnly (Word16 -> VarTableEntry -> Parser Variable
extractVar Word16
baseAddr VarTableEntry
entry) ByteString
userData
    in ([Char] -> Variable)
-> (Variable -> Variable) -> Either [Char] Variable -> Variable
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [Char] -> Variable
forall a. HasCallStack => [Char] -> a
error Variable -> Variable
forall a. a -> a
id Either [Char] Variable
var

-- | Read all ofthe variables contained in a user memory
-- backup, according to a variable table.
readUserMem :: Word16 -> VarTable -> ByteString -> [Variable]
readUserMem :: Word16 -> [VarTableEntry] -> ByteString -> [Variable]
readUserMem Word16
baseAddr [VarTableEntry]
table ByteString
userData =
    let vars :: Either [Char] [Variable]
vars = Parser [Variable] -> ByteString -> Either [Char] [Variable]
forall a. Parser a -> ByteString -> Either [Char] a
parseOnly (Word16 -> [VarTableEntry] -> Parser [Variable]
parseUserMem Word16
baseAddr [VarTableEntry]
table) ByteString
userData
    in ([Char] -> [Variable])
-> ([Variable] -> [Variable])
-> Either [Char] [Variable]
-> [Variable]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [Char] -> [Variable]
forall a. HasCallStack => [Char] -> a
error [Variable] -> [Variable]
forall a. a -> a
id Either [Char] [Variable]
vars

-- |Convert raw variable data into a Variable.
readVariable :: TIVar -> Variable
readVariable :: TIVar -> Variable
readVariable TIVar
var =
    let varType :: VarType
varType = Word8 -> VarType
idToType (TIVar -> Word8
varId TIVar
var)
        parsedVar :: Either [Char] Variable
parsedVar = Parser Variable -> ByteString -> Either [Char] Variable
forall a. Parser a -> ByteString -> Either [Char] a
parseOnly (VarType -> Parser Variable
parseVariable VarType
varType) (TIVar -> ByteString
varData TIVar
var)
    in ([Char] -> Variable)
-> (Variable -> Variable) -> Either [Char] Variable -> Variable
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [Char] -> Variable
forall a. HasCallStack => [Char] -> a
error Variable -> Variable
forall a. a -> a
id Either [Char] Variable
parsedVar