module Clash.Core.PartialEval where
import Control.Concurrent.Supply (Supply)
import Data.IntMap.Strict (IntMap)
import Clash.Core.PartialEval.AsTerm
import Clash.Core.PartialEval.Monad
import Clash.Core.PartialEval.NormalForm
import Clash.Core.Term (Term)
import Clash.Core.TyCon (TyConMap)
import Clash.Core.Var (Id)
import Clash.Core.VarEnv (InScopeSet)
import Clash.Driver.Types (Binding(..), BindingMap)
data Evaluator = Evaluator
{ Evaluator -> Term -> Eval Value
evalWhnf :: Term -> Eval Value
, Evaluator -> Value -> Eval Normal
quoteNf :: Value -> Eval Normal
}
whnf
:: Evaluator
-> GlobalEnv
-> Bool
-> Id
-> Term
-> IO (Term, GlobalEnv)
whnf :: Evaluator
-> GlobalEnv -> Bool -> Id -> Term -> IO (Term, GlobalEnv)
whnf Evaluator
e GlobalEnv
g Bool
isSubj Id
i Term
x =
let l :: LocalEnv
l = Id -> Map TyVar Type -> Map Id Value -> Word -> Bool -> LocalEnv
LocalEnv Id
i Map TyVar Type
forall a. Monoid a => a
mempty Map Id Value
forall a. Monoid a => a
mempty (GlobalEnv -> Word
genvFuel GlobalEnv
g) Bool
isSubj
in GlobalEnv -> LocalEnv -> Eval Term -> IO (Term, GlobalEnv)
forall a. GlobalEnv -> LocalEnv -> Eval a -> IO (a, GlobalEnv)
runEval GlobalEnv
g LocalEnv
l (Value -> Term
forall a. AsTerm a => a -> Term
asTerm (Value -> Term) -> Eval Value -> Eval Term
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Evaluator -> Term -> Eval Value
evalWhnf Evaluator
e Term
x)
nf
:: Evaluator
-> GlobalEnv
-> Bool
-> Id
-> Term
-> IO (Term, GlobalEnv)
nf :: Evaluator
-> GlobalEnv -> Bool -> Id -> Term -> IO (Term, GlobalEnv)
nf Evaluator
e GlobalEnv
g Bool
isSubj Id
i Term
x =
let l :: LocalEnv
l = Id -> Map TyVar Type -> Map Id Value -> Word -> Bool -> LocalEnv
LocalEnv Id
i Map TyVar Type
forall a. Monoid a => a
mempty Map Id Value
forall a. Monoid a => a
mempty (GlobalEnv -> Word
genvFuel GlobalEnv
g) Bool
isSubj
in GlobalEnv -> LocalEnv -> Eval Term -> IO (Term, GlobalEnv)
forall a. GlobalEnv -> LocalEnv -> Eval a -> IO (a, GlobalEnv)
runEval GlobalEnv
g LocalEnv
l (Normal -> Term
forall a. AsTerm a => a -> Term
asTerm (Normal -> Term) -> Eval Normal -> Eval Term
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Evaluator -> Term -> Eval Value
evalWhnf Evaluator
e Term
x Eval Value -> (Value -> Eval Normal) -> Eval Normal
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= Evaluator -> Value -> Eval Normal
quoteNf Evaluator
e))
mkGlobalEnv
:: BindingMap
-> TyConMap
-> InScopeSet
-> Supply
-> Word
-> IntMap Value
-> Int
-> GlobalEnv
mkGlobalEnv :: BindingMap
-> TyConMap
-> InScopeSet
-> Supply
-> Word
-> IntMap Value
-> Int
-> GlobalEnv
mkGlobalEnv BindingMap
bm TyConMap
tcm InScopeSet
iss Supply
ids Word
fuel IntMap Value
heap Int
addr =
VarEnv (Binding Value)
-> TyConMap
-> InScopeSet
-> Supply
-> Word
-> IntMap Value
-> Int
-> VarEnv Bool
-> GlobalEnv
GlobalEnv ((Binding Term -> Binding Value)
-> BindingMap -> VarEnv (Binding Value)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Binding Term -> Binding Value
asThunk BindingMap
bm) TyConMap
tcm InScopeSet
iss Supply
ids Word
fuel IntMap Value
heap Int
addr VarEnv Bool
forall a. Monoid a => a
mempty
where
asThunk :: Binding Term -> Binding Value
asThunk b :: Binding Term
b@Binding{bindingId :: forall a. Binding a -> Id
bindingId=Id
i,bindingTerm :: forall a. Binding a -> a
bindingTerm=Term
t} =
Binding Term
b { bindingTerm :: Value
bindingTerm = Term -> LocalEnv -> Value
VThunk Term
t (Id -> Map TyVar Type -> Map Id Value -> Word -> Bool -> LocalEnv
LocalEnv Id
i Map TyVar Type
forall a. Monoid a => a
mempty Map Id Value
forall a. Monoid a => a
mempty Word
fuel Bool
False) }