{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
module Clash.Core.Var
( Var (..)
, IdScope (..)
, Id
, TyVar
, mkId
, mkLocalId
, mkGlobalId
, mkTyVar
, setIdScope
, modifyVarName
, isGlobalId
, isLocalId
)
where
import Control.DeepSeq (NFData (..))
import Data.Binary (Binary)
import Data.Function (on)
import Data.Hashable (Hashable(hashWithSalt))
import GHC.Generics (Generic)
import Clash.Core.Name (Name (..))
import {-# SOURCE #-} Clash.Core.Term (Term, TmName)
import {-# SOURCE #-} Clash.Core.Type (Kind, Type, TyName)
import Clash.Unique
data Var a
= TyVar
{ Var a -> Name a
varName :: !(Name a)
, Var a -> Unique
varUniq :: {-# UNPACK #-} !Unique
, Var a -> Kind
varType :: Kind
}
| Id
{ varName :: !(Name a)
, varUniq :: {-# UNPACK #-} !Unique
, varType :: Type
, Var a -> IdScope
idScope :: IdScope
}
deriving (Unique -> Var a -> ShowS
[Var a] -> ShowS
Var a -> String
(Unique -> Var a -> ShowS)
-> (Var a -> String) -> ([Var a] -> ShowS) -> Show (Var a)
forall a. Unique -> Var a -> ShowS
forall a. [Var a] -> ShowS
forall a. Var a -> String
forall a.
(Unique -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Var a] -> ShowS
$cshowList :: forall a. [Var a] -> ShowS
show :: Var a -> String
$cshow :: forall a. Var a -> String
showsPrec :: Unique -> Var a -> ShowS
$cshowsPrec :: forall a. Unique -> Var a -> ShowS
Show,(forall x. Var a -> Rep (Var a) x)
-> (forall x. Rep (Var a) x -> Var a) -> Generic (Var a)
forall x. Rep (Var a) x -> Var a
forall x. Var a -> Rep (Var a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Var a) x -> Var a
forall a x. Var a -> Rep (Var a) x
$cto :: forall a x. Rep (Var a) x -> Var a
$cfrom :: forall a x. Var a -> Rep (Var a) x
Generic,Var a -> ()
(Var a -> ()) -> NFData (Var a)
forall a. Var a -> ()
forall a. (a -> ()) -> NFData a
rnf :: Var a -> ()
$crnf :: forall a. Var a -> ()
NFData,Get (Var a)
[Var a] -> Put
Var a -> Put
(Var a -> Put) -> Get (Var a) -> ([Var a] -> Put) -> Binary (Var a)
forall a. Get (Var a)
forall a. [Var a] -> Put
forall a. Var a -> Put
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [Var a] -> Put
$cputList :: forall a. [Var a] -> Put
get :: Get (Var a)
$cget :: forall a. Get (Var a)
put :: Var a -> Put
$cput :: forall a. Var a -> Put
Binary)
varKey :: Var a -> (Unique, Maybe IdScope)
varKey :: Var a -> (Unique, Maybe IdScope)
varKey TyVar{Unique
varUniq :: Unique
varUniq :: forall a. Var a -> Unique
varUniq} = (Unique
varUniq, Maybe IdScope
forall a. Maybe a
Nothing)
varKey Id{Unique
varUniq :: Unique
varUniq :: forall a. Var a -> Unique
varUniq,IdScope
idScope :: IdScope
idScope :: forall a. Var a -> IdScope
idScope} = (Unique
varUniq, IdScope -> Maybe IdScope
forall a. a -> Maybe a
Just IdScope
idScope)
instance Hashable (Var a) where
hashWithSalt :: Unique -> Var a -> Unique
hashWithSalt Unique
salt Var a
a = Unique -> (Unique, Maybe IdScope) -> Unique
forall a. Hashable a => Unique -> a -> Unique
hashWithSalt Unique
salt (Var a -> (Unique, Maybe IdScope)
forall a. Var a -> (Unique, Maybe IdScope)
varKey Var a
a)
instance Eq (Var a) where
== :: Var a -> Var a -> Bool
(==) = (Unique, Maybe IdScope) -> (Unique, Maybe IdScope) -> Bool
forall a. Eq a => a -> a -> Bool
(==) ((Unique, Maybe IdScope) -> (Unique, Maybe IdScope) -> Bool)
-> (Var a -> (Unique, Maybe IdScope)) -> Var a -> Var a -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Var a -> (Unique, Maybe IdScope)
forall a. Var a -> (Unique, Maybe IdScope)
varKey
/= :: Var a -> Var a -> Bool
(/=) = (Unique, Maybe IdScope) -> (Unique, Maybe IdScope) -> Bool
forall a. Eq a => a -> a -> Bool
(/=) ((Unique, Maybe IdScope) -> (Unique, Maybe IdScope) -> Bool)
-> (Var a -> (Unique, Maybe IdScope)) -> Var a -> Var a -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Var a -> (Unique, Maybe IdScope)
forall a. Var a -> (Unique, Maybe IdScope)
varKey
instance Ord (Var a) where
compare :: Var a -> Var a -> Ordering
compare = (Unique, Maybe IdScope) -> (Unique, Maybe IdScope) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ((Unique, Maybe IdScope) -> (Unique, Maybe IdScope) -> Ordering)
-> (Var a -> (Unique, Maybe IdScope)) -> Var a -> Var a -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Var a -> (Unique, Maybe IdScope)
forall a. Var a -> (Unique, Maybe IdScope)
varKey
instance Uniquable (Var a) where
getUnique :: Var a -> Unique
getUnique = Var a -> Unique
forall a. Var a -> Unique
varUniq
setUnique :: Var a -> Unique -> Var a
setUnique Var a
var Unique
u = Var a
var {varUniq :: Unique
varUniq=Unique
u, varName :: Name a
varName=(Var a -> Name a
forall a. Var a -> Name a
varName Var a
var){nameUniq :: Unique
nameUniq=Unique
u}}
data IdScope = GlobalId | LocalId
deriving (Unique -> IdScope -> ShowS
[IdScope] -> ShowS
IdScope -> String
(Unique -> IdScope -> ShowS)
-> (IdScope -> String) -> ([IdScope] -> ShowS) -> Show IdScope
forall a.
(Unique -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IdScope] -> ShowS
$cshowList :: [IdScope] -> ShowS
show :: IdScope -> String
$cshow :: IdScope -> String
showsPrec :: Unique -> IdScope -> ShowS
$cshowsPrec :: Unique -> IdScope -> ShowS
Show,(forall x. IdScope -> Rep IdScope x)
-> (forall x. Rep IdScope x -> IdScope) -> Generic IdScope
forall x. Rep IdScope x -> IdScope
forall x. IdScope -> Rep IdScope x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep IdScope x -> IdScope
$cfrom :: forall x. IdScope -> Rep IdScope x
Generic,IdScope -> ()
(IdScope -> ()) -> NFData IdScope
forall a. (a -> ()) -> NFData a
rnf :: IdScope -> ()
$crnf :: IdScope -> ()
NFData,Eq IdScope
Eq IdScope
-> (Unique -> IdScope -> Unique)
-> (IdScope -> Unique)
-> Hashable IdScope
Unique -> IdScope -> Unique
IdScope -> Unique
forall a.
Eq a -> (Unique -> a -> Unique) -> (a -> Unique) -> Hashable a
hash :: IdScope -> Unique
$chash :: IdScope -> Unique
hashWithSalt :: Unique -> IdScope -> Unique
$chashWithSalt :: Unique -> IdScope -> Unique
$cp1Hashable :: Eq IdScope
Hashable,Get IdScope
[IdScope] -> Put
IdScope -> Put
(IdScope -> Put)
-> Get IdScope -> ([IdScope] -> Put) -> Binary IdScope
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [IdScope] -> Put
$cputList :: [IdScope] -> Put
get :: Get IdScope
$cget :: Get IdScope
put :: IdScope -> Put
$cput :: IdScope -> Put
Binary,IdScope -> IdScope -> Bool
(IdScope -> IdScope -> Bool)
-> (IdScope -> IdScope -> Bool) -> Eq IdScope
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IdScope -> IdScope -> Bool
$c/= :: IdScope -> IdScope -> Bool
== :: IdScope -> IdScope -> Bool
$c== :: IdScope -> IdScope -> Bool
Eq,Eq IdScope
Eq IdScope
-> (IdScope -> IdScope -> Ordering)
-> (IdScope -> IdScope -> Bool)
-> (IdScope -> IdScope -> Bool)
-> (IdScope -> IdScope -> Bool)
-> (IdScope -> IdScope -> Bool)
-> (IdScope -> IdScope -> IdScope)
-> (IdScope -> IdScope -> IdScope)
-> Ord IdScope
IdScope -> IdScope -> Bool
IdScope -> IdScope -> Ordering
IdScope -> IdScope -> IdScope
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: IdScope -> IdScope -> IdScope
$cmin :: IdScope -> IdScope -> IdScope
max :: IdScope -> IdScope -> IdScope
$cmax :: IdScope -> IdScope -> IdScope
>= :: IdScope -> IdScope -> Bool
$c>= :: IdScope -> IdScope -> Bool
> :: IdScope -> IdScope -> Bool
$c> :: IdScope -> IdScope -> Bool
<= :: IdScope -> IdScope -> Bool
$c<= :: IdScope -> IdScope -> Bool
< :: IdScope -> IdScope -> Bool
$c< :: IdScope -> IdScope -> Bool
compare :: IdScope -> IdScope -> Ordering
$ccompare :: IdScope -> IdScope -> Ordering
$cp1Ord :: Eq IdScope
Ord)
type Id = Var Term
type TyVar = Var Type
modifyVarName ::
(Name a -> Name a)
-> Var a
-> Var a
modifyVarName :: (Name a -> Name a) -> Var a -> Var a
modifyVarName Name a -> Name a
f (TyVar Name a
n Unique
_ Kind
k) =
let n' :: Name a
n' = Name a -> Name a
f Name a
n
in Name a -> Unique -> Kind -> Var a
forall a. Name a -> Unique -> Kind -> Var a
TyVar Name a
n' (Name a -> Unique
forall a. Name a -> Unique
nameUniq Name a
n') Kind
k
modifyVarName Name a -> Name a
f (Id Name a
n Unique
_ Kind
t IdScope
s) =
let n' :: Name a
n' = Name a -> Name a
f Name a
n
in Name a -> Unique -> Kind -> IdScope -> Var a
forall a. Name a -> Unique -> Kind -> IdScope -> Var a
Id Name a
n' (Name a -> Unique
forall a. Name a -> Unique
nameUniq Name a
n') Kind
t IdScope
s
mkTyVar
:: Kind
-> TyName
-> TyVar
mkTyVar :: Kind -> TyName -> TyVar
mkTyVar Kind
tyKind TyName
tyName = TyName -> Unique -> Kind -> TyVar
forall a. Name a -> Unique -> Kind -> Var a
TyVar TyName
tyName (TyName -> Unique
forall a. Name a -> Unique
nameUniq TyName
tyName) Kind
tyKind
mkId
:: Type
-> IdScope
-> TmName
-> Id
mkId :: Kind -> IdScope -> TmName -> Id
mkId Kind
tmType IdScope
scope TmName
tmName = TmName -> Unique -> Kind -> IdScope -> Id
forall a. Name a -> Unique -> Kind -> IdScope -> Var a
Id TmName
tmName (TmName -> Unique
forall a. Name a -> Unique
nameUniq TmName
tmName) Kind
tmType IdScope
scope
mkLocalId
:: Type
-> TmName
-> Id
mkLocalId :: Kind -> TmName -> Id
mkLocalId Kind
tmType TmName
tmName = TmName -> Unique -> Kind -> IdScope -> Id
forall a. Name a -> Unique -> Kind -> IdScope -> Var a
Id TmName
tmName (TmName -> Unique
forall a. Name a -> Unique
nameUniq TmName
tmName) Kind
tmType IdScope
LocalId
mkGlobalId
:: Type
-> TmName
-> Id
mkGlobalId :: Kind -> TmName -> Id
mkGlobalId Kind
tmType TmName
tmName = TmName -> Unique -> Kind -> IdScope -> Id
forall a. Name a -> Unique -> Kind -> IdScope -> Var a
Id TmName
tmName (TmName -> Unique
forall a. Name a -> Unique
nameUniq TmName
tmName) Kind
tmType IdScope
GlobalId
isGlobalId
:: Var a
-> Bool
isGlobalId :: Var a -> Bool
isGlobalId (Id {idScope :: forall a. Var a -> IdScope
idScope = IdScope
GlobalId}) = Bool
True
isGlobalId Var a
_ = Bool
False
isLocalId
:: Var a
-> Bool
isLocalId :: Var a -> Bool
isLocalId (Id {idScope :: forall a. Var a -> IdScope
idScope = IdScope
LocalId}) = Bool
True
isLocalId Var a
_ = Bool
False
setIdScope
:: IdScope
-> Var a
-> Var a
setIdScope :: IdScope -> Var a -> Var a
setIdScope IdScope
s (Id Name a
nm Unique
u Kind
t IdScope
_) = Name a -> Unique -> Kind -> IdScope -> Var a
forall a. Name a -> Unique -> Kind -> IdScope -> Var a
Id Name a
nm Unique
u Kind
t IdScope
s
setIdScope IdScope
_ Var a
v = Var a
v