{-# LANGUAGE DerivingVia, StandaloneDeriving, ViewPatterns, ImpredicativeTypes #-}
module GHC.Debugger.View.Class
(
DebugView(..)
, VarValue(..)
, VarFields(..)
, VarFieldValue(..)
, simpleValue
, Program(..)
, isThunk
, ifP
, BoringTy(..)
, VarValueIO(..)
, debugValueIOWrapper
, VarFieldsIO(..)
, debugFieldsIOWrapper
)
where
import Data.Int
import Data.Word
class DebugView a where
debugValue :: a -> VarValue
debugFields :: a -> Program VarFields
data Program a where
PureProgram :: a -> Program a
ProgramAp :: Program (a -> b) -> Program a -> Program b
ProgramBranch :: Program Bool -> Program a -> Program a -> Program a
ProgramAskThunk :: a -> Program Bool
instance Functor Program where
fmap :: forall a b. (a -> b) -> Program a -> Program b
fmap a -> b
f Program a
x = Program (a -> b) -> Program a -> Program b
forall a b. Program (a -> b) -> Program a -> Program b
ProgramAp ((a -> b) -> Program (a -> b)
forall a. a -> Program a
PureProgram a -> b
f) Program a
x
instance Applicative Program where
pure :: forall a. a -> Program a
pure = a -> Program a
forall a. a -> Program a
PureProgram
Program (a -> b)
fx <*> :: forall a b. Program (a -> b) -> Program a -> Program b
<*> Program a
fy = Program (a -> b) -> Program a -> Program b
forall a b. Program (a -> b) -> Program a -> Program b
ProgramAp Program (a -> b)
fx Program a
fy
simpleValue :: String -> Bool -> VarValue
simpleValue :: String -> Bool -> VarValue
simpleValue String
s Bool
b = Program String -> Bool -> VarValue
VarValue (String -> Program String
forall a. a -> Program a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
s) Bool
b
isThunk :: a -> Program Bool
isThunk :: forall a. a -> Program Bool
isThunk = a -> Program Bool
forall a. a -> Program Bool
ProgramAskThunk
ifP :: Program Bool -> Program a -> Program a -> Program a
ifP :: forall a. Program Bool -> Program a -> Program a -> Program a
ifP = Program Bool -> Program a -> Program a -> Program a
forall a. Program Bool -> Program a -> Program a -> Program a
ProgramBranch
data VarValue = VarValue
{
VarValue -> Program String
varValue :: Program String
, VarValue -> Bool
varExpandable :: Bool
}
newtype VarFields = VarFields
{ VarFields -> [(String, VarFieldValue)]
varFields :: [(String, VarFieldValue)]
}
data VarFieldValue = forall a. VarFieldValue a
newtype BoringTy a = BoringTy a
instance Show a => DebugView (BoringTy a) where
debugValue :: BoringTy a -> VarValue
debugValue (BoringTy a
x) = String -> Bool -> VarValue
simpleValue (a -> String
forall a. Show a => a -> String
show a
x) Bool
False
debugFields :: BoringTy a -> Program VarFields
debugFields BoringTy a
_ = VarFields -> Program VarFields
forall a. a -> Program a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VarFields -> Program VarFields) -> VarFields -> Program VarFields
forall a b. (a -> b) -> a -> b
$ [(String, VarFieldValue)] -> VarFields
VarFields []
deriving via BoringTy Int instance DebugView Int
deriving via BoringTy Int8 instance DebugView Int8
deriving via BoringTy Int16 instance DebugView Int16
deriving via BoringTy Int32 instance DebugView Int32
deriving via BoringTy Int64 instance DebugView Int64
deriving via BoringTy Word instance DebugView Word
deriving via BoringTy Word8 instance DebugView Word8
deriving via BoringTy Word16 instance DebugView Word16
deriving via BoringTy Word32 instance DebugView Word32
deriving via BoringTy Word64 instance DebugView Word64
deriving via BoringTy Double instance DebugView Double
deriving via BoringTy Float instance DebugView Float
deriving via BoringTy Integer instance DebugView Integer
deriving via BoringTy Char instance DebugView Char
deriving via BoringTy String instance DebugView String
instance DebugView (a, b) where
debugValue :: (a, b) -> VarValue
debugValue (a, b)
_ = String -> Bool -> VarValue
simpleValue String
"( , )" Bool
True
debugFields :: (a, b) -> Program VarFields
debugFields (a
x, b
y) = VarFields -> Program VarFields
forall a. a -> Program a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VarFields -> Program VarFields) -> VarFields -> Program VarFields
forall a b. (a -> b) -> a -> b
$ [(String, VarFieldValue)] -> VarFields
VarFields
[ (String
"fst", a -> VarFieldValue
forall a. a -> VarFieldValue
VarFieldValue a
x)
, (String
"snd", b -> VarFieldValue
forall a. a -> VarFieldValue
VarFieldValue b
y) ]
instance {-# OVERLAPPABLE #-} DebugView [a] where
debugValue :: [a] -> VarValue
debugValue [] = String -> Bool -> VarValue
simpleValue String
"[]" Bool
False
debugValue (a
_:[a]
_) = String -> Bool -> VarValue
simpleValue String
"[...]" Bool
True
debugFields :: [a] -> Program VarFields
debugFields [a]
v = [(String, VarFieldValue)] -> VarFields
VarFields ([(String, VarFieldValue)] -> VarFields)
-> Program [(String, VarFieldValue)] -> Program VarFields
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> [a] -> Program [(String, VarFieldValue)]
go Int
0 [a]
v
where
go :: Int -> [a] -> Program [(String, VarFieldValue)]
go :: Int -> [a] -> Program [(String, VarFieldValue)]
go Int
50 [a]
xs = [(String, VarFieldValue)] -> Program [(String, VarFieldValue)]
forall a. a -> Program a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [(String
"tail", [a] -> VarFieldValue
forall a. a -> VarFieldValue
VarFieldValue [a]
xs)]
go Int
_ [] = [(String, VarFieldValue)] -> Program [(String, VarFieldValue)]
forall a. a -> Program a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
go Int
n (a
x:[a]
xs) = ((Int -> String
forall a. Show a => a -> String
show Int
n, a -> VarFieldValue
forall a. a -> VarFieldValue
VarFieldValue a
x) (String, VarFieldValue)
-> [(String, VarFieldValue)] -> [(String, VarFieldValue)]
forall a. a -> [a] -> [a]
:) ([(String, VarFieldValue)] -> [(String, VarFieldValue)])
-> Program [(String, VarFieldValue)]
-> Program [(String, VarFieldValue)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
(Program Bool
-> Program [(String, VarFieldValue)]
-> Program [(String, VarFieldValue)]
-> Program [(String, VarFieldValue)]
forall a. Program Bool -> Program a -> Program a -> Program a
ifP ([a] -> Program Bool
forall a. a -> Program Bool
isThunk [a]
xs) ([(String, VarFieldValue)] -> Program [(String, VarFieldValue)]
forall a. a -> Program a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([(String, VarFieldValue)] -> Program [(String, VarFieldValue)])
-> [(String, VarFieldValue)] -> Program [(String, VarFieldValue)]
forall a b. (a -> b) -> a -> b
$ [(String
"tail", [a] -> VarFieldValue
forall a. a -> VarFieldValue
VarFieldValue [a]
xs)])
(Int -> [a] -> Program [(String, VarFieldValue)]
go (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [a]
xs))
data VarValueIO = VarValueIO
{ VarValueIO -> Program (IO String)
varValueIO :: Program (IO String)
, VarValueIO -> Bool
varExpandableIO :: Bool
}
debugValueIOWrapper :: DebugView a => a -> IO [VarValueIO]
debugValueIOWrapper :: forall a. DebugView a => a -> IO [VarValueIO]
debugValueIOWrapper a
x = case a -> VarValue
forall a. DebugView a => a -> VarValue
debugValue a
x of
VarValue Program String
str Bool
b ->
[VarValueIO] -> IO [VarValueIO]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Program (IO String) -> Bool -> VarValueIO
VarValueIO (String -> IO String
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> IO String) -> Program String -> Program (IO String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Program String
str) Bool
b]
newtype VarFieldsIO = VarFieldsIO
{ VarFieldsIO -> Program [(IO String, VarFieldValue)]
varFieldsIO :: Program [(IO String, VarFieldValue)]
}
debugFieldsIOWrapper :: DebugView a => a -> IO [VarFieldsIO]
debugFieldsIOWrapper :: forall a. DebugView a => a -> IO [VarFieldsIO]
debugFieldsIOWrapper a
x = [VarFieldsIO] -> IO [VarFieldsIO]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Program [(IO String, VarFieldValue)] -> VarFieldsIO
VarFieldsIO (VarFields -> [(IO String, VarFieldValue)]
toVarFieldsIO (VarFields -> [(IO String, VarFieldValue)])
-> Program VarFields -> Program [(IO String, VarFieldValue)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> Program VarFields
forall a. DebugView a => a -> Program VarFields
debugFields a
x))]
toVarFieldsIO :: VarFields -> [(IO String, VarFieldValue)]
toVarFieldsIO :: VarFields -> [(IO String, VarFieldValue)]
toVarFieldsIO VarFields
x =
case VarFields
x of
VarFields [(String, VarFieldValue)]
fls -> [ (String -> IO String
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
fl_s, VarFieldValue
b) | (String
fl_s, VarFieldValue
b) <- [(String, VarFieldValue)]
fls]