{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TemplateHaskell #-}
module Clash.Core.PartialEval.NormalForm
( Arg
, Args
, Neutral(..)
, Value(..)
, mkValueTicks
, stripValue
, collectValueTicks
, isUndefined
, Normal(..)
, LocalEnv(..)
, GlobalEnv(..)
, workFreeCache
) where
import Control.Concurrent.Supply (Supply)
import Control.Lens (Lens', lens)
import Data.IntMap.Strict (IntMap)
import Data.Map.Strict (Map)
import Clash.Core.DataCon (DataCon)
import Clash.Core.Literal
import Clash.Core.Term (Bind, Term(..), PrimInfo(primName), TickInfo, Pat)
import Clash.Core.TyCon (TyConMap)
import Clash.Core.Type (Type, TyVar)
import Clash.Core.Util (undefinedPrims)
import Clash.Core.Var (Id)
import Clash.Core.VarEnv (VarEnv, InScopeSet)
import Clash.Driver.Types (Binding(..))
type Args a
= [Arg a]
type Arg a
= Either a Type
data Neutral a
= NeVar !Id
| NePrim !PrimInfo !(Args a)
| NeApp !(Neutral a) !a
| NeTyApp !(Neutral a) !Type
| NeLet !(Bind a) !a
| NeCase !a !Type ![(Pat, a)]
deriving (Int -> Neutral a -> ShowS
[Neutral a] -> ShowS
Neutral a -> String
(Int -> Neutral a -> ShowS)
-> (Neutral a -> String)
-> ([Neutral a] -> ShowS)
-> Show (Neutral a)
forall a. Show a => Int -> Neutral a -> ShowS
forall a. Show a => [Neutral a] -> ShowS
forall a. Show a => Neutral a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Neutral a] -> ShowS
$cshowList :: forall a. Show a => [Neutral a] -> ShowS
show :: Neutral a -> String
$cshow :: forall a. Show a => Neutral a -> String
showsPrec :: Int -> Neutral a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Neutral a -> ShowS
Show)
data Value
= VNeutral !(Neutral Value)
| VLiteral !Literal
| VData !DataCon !(Args Value) !LocalEnv
| VLam !Id !Term !LocalEnv
| VTyLam !TyVar !Term !LocalEnv
| VCast !Value !Type !Type
| VTick !Value !TickInfo
| VThunk !Term !LocalEnv
deriving (Int -> Value -> ShowS
[Value] -> ShowS
Value -> String
(Int -> Value -> ShowS)
-> (Value -> String) -> ([Value] -> ShowS) -> Show Value
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Value] -> ShowS
$cshowList :: [Value] -> ShowS
show :: Value -> String
$cshow :: Value -> String
showsPrec :: Int -> Value -> ShowS
$cshowsPrec :: Int -> Value -> ShowS
Show)
mkValueTicks :: Value -> [TickInfo] -> Value
mkValueTicks :: Value -> [TickInfo] -> Value
mkValueTicks = (Value -> TickInfo -> Value) -> Value -> [TickInfo] -> Value
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Value -> TickInfo -> Value
VTick
stripValue :: Value -> Value
stripValue :: Value -> Value
stripValue = (Value, [TickInfo]) -> Value
forall a b. (a, b) -> a
fst ((Value, [TickInfo]) -> Value)
-> (Value -> (Value, [TickInfo])) -> Value -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> (Value, [TickInfo])
collectValueTicks
collectValueTicks :: Value -> (Value, [TickInfo])
collectValueTicks :: Value -> (Value, [TickInfo])
collectValueTicks = [TickInfo] -> Value -> (Value, [TickInfo])
go []
where
go :: [TickInfo] -> Value -> (Value, [TickInfo])
go ![TickInfo]
acc = \case
VTick Value
v TickInfo
tick -> [TickInfo] -> Value -> (Value, [TickInfo])
go (TickInfo
tick TickInfo -> [TickInfo] -> [TickInfo]
forall a. a -> [a] -> [a]
: [TickInfo]
acc) Value
v
Value
value -> (Value
value, [TickInfo]
acc)
isUndefined :: Value -> Bool
isUndefined :: Value -> Bool
isUndefined = \case
VNeutral (NePrim PrimInfo
pr Args Value
_) ->
PrimInfo -> Text
primName PrimInfo
pr Text -> [Text] -> Bool
forall (t :: Type -> Type) a.
(Foldable t, Eq a) =>
a -> t a -> Bool
`elem` [Text]
undefinedPrims
Value
_ -> Bool
False
data Normal
= NNeutral !(Neutral Normal)
| NLiteral !Literal
| NData !DataCon !(Args Normal)
| NLam !Id !Normal !LocalEnv
| NTyLam !TyVar !Normal !LocalEnv
| NCast !Normal !Type !Type
| NTick !Normal !TickInfo
deriving (Int -> Normal -> ShowS
[Normal] -> ShowS
Normal -> String
(Int -> Normal -> ShowS)
-> (Normal -> String) -> ([Normal] -> ShowS) -> Show Normal
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Normal] -> ShowS
$cshowList :: [Normal] -> ShowS
show :: Normal -> String
$cshow :: Normal -> String
showsPrec :: Int -> Normal -> ShowS
$cshowsPrec :: Int -> Normal -> ShowS
Show)
data LocalEnv = LocalEnv
{ LocalEnv -> Id
lenvContext :: Id
, LocalEnv -> Map TyVar Type
lenvTypes :: Map TyVar Type
, LocalEnv -> Map Id Value
lenvValues :: Map Id Value
, LocalEnv -> Word
lenvFuel :: Word
, LocalEnv -> Bool
lenvKeepLifted :: Bool
} deriving (Int -> LocalEnv -> ShowS
[LocalEnv] -> ShowS
LocalEnv -> String
(Int -> LocalEnv -> ShowS)
-> (LocalEnv -> String) -> ([LocalEnv] -> ShowS) -> Show LocalEnv
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LocalEnv] -> ShowS
$cshowList :: [LocalEnv] -> ShowS
show :: LocalEnv -> String
$cshow :: LocalEnv -> String
showsPrec :: Int -> LocalEnv -> ShowS
$cshowsPrec :: Int -> LocalEnv -> ShowS
Show)
data GlobalEnv = GlobalEnv
{ GlobalEnv -> VarEnv (Binding Value)
genvBindings :: VarEnv (Binding Value)
, GlobalEnv -> TyConMap
genvTyConMap :: TyConMap
, GlobalEnv -> InScopeSet
genvInScope :: InScopeSet
, GlobalEnv -> Supply
genvSupply :: Supply
, GlobalEnv -> Word
genvFuel :: Word
, GlobalEnv -> IntMap Value
genvHeap :: IntMap Value
, GlobalEnv -> Int
genvAddr :: Int
, GlobalEnv -> VarEnv Bool
genvWorkCache :: VarEnv Bool
}
workFreeCache :: Lens' GlobalEnv (VarEnv Bool)
workFreeCache :: (VarEnv Bool -> f (VarEnv Bool)) -> GlobalEnv -> f GlobalEnv
workFreeCache = (GlobalEnv -> VarEnv Bool)
-> (GlobalEnv -> VarEnv Bool -> GlobalEnv)
-> Lens GlobalEnv GlobalEnv (VarEnv Bool) (VarEnv Bool)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens GlobalEnv -> VarEnv Bool
genvWorkCache (\GlobalEnv
env VarEnv Bool
x -> GlobalEnv
env { genvWorkCache :: VarEnv Bool
genvWorkCache = VarEnv Bool
x })