2 -- This module contains functions that manipulate binders in various ways.
4 module CLasH.Utils.Core.BinderTools where
7 import Data.Accessor.Monad.Trans.State as MonadState
12 import qualified UniqSupply
13 import qualified Unique
14 import qualified OccName
17 import qualified SrcLoc
18 import qualified IdInfo
19 import qualified CoreUtils
20 import qualified CoreSubst
21 import qualified VarSet
22 import qualified HscTypes
25 import CLasH.Translator.TranslatorTypes
27 -- Create a new Unique
28 mkUnique :: TranslatorSession Unique.Unique
30 us <- MonadState.get tsUniqSupply
31 let (us', us'') = UniqSupply.splitUniqSupply us
32 MonadState.set tsUniqSupply us'
33 return $ UniqSupply.uniqFromSupply us''
35 -- Create a new internal var with the given name and type. A Unique is
36 -- appended to the given name, to ensure uniqueness (not strictly neccesary,
37 -- since the Unique is also stored in the name, but this ensures variable
38 -- names are unique in the output).
39 mkInternalVar :: String -> Type.Type -> TranslatorSession Var.Var
40 mkInternalVar str ty = do
42 let occname = OccName.mkVarOcc (str ++ show uniq)
43 let name = Name.mkInternalName uniq occname SrcLoc.noSrcSpan
44 return $ Var.mkLocalVar IdInfo.VanillaId name ty IdInfo.vanillaIdInfo
46 -- Create a new type variable with the given name and kind. A Unique is
47 -- appended to the given name, to ensure uniqueness (not strictly neccesary,
48 -- since the Unique is also stored in the name, but this ensures variable
49 -- names are unique in the output).
50 mkTypeVar :: String -> Type.Kind -> TranslatorSession Var.Var
51 mkTypeVar str kind = do
53 let occname = OccName.mkVarOcc (str ++ show uniq)
54 let name = Name.mkInternalName uniq occname SrcLoc.noSrcSpan
55 return $ Var.mkTyVar name kind
57 -- Creates a binder for the given expression with the given name. This
58 -- works for both value and type level expressions, so it can return a Var or
59 -- TyVar (which is just an alias for Var).
60 mkBinderFor :: CoreExpr -> String -> TranslatorSession Var.Var
61 mkBinderFor (Type ty) string = mkTypeVar string (Type.typeKind ty)
62 mkBinderFor expr string = mkInternalVar string (CoreUtils.exprType expr)
64 -- Creates a reference to the given variable. This works for both a normal
65 -- variable as well as a type variable
66 mkReferenceTo :: Var.Var -> CoreExpr
67 mkReferenceTo var | Var.isTyVar var = (Type $ Type.mkTyVarTy var)
68 | otherwise = (Var var)
70 cloneVar :: Var.Var -> TranslatorSession Var.Var
73 -- Swap out the unique, and reset the IdInfo (I'm not 100% sure what it
74 -- contains, but vannillaIdInfo is always correct, since it means "no info").
75 return $ Var.lazySetIdInfo (Var.setVarUnique v uniq) IdInfo.vanillaIdInfo
77 -- Creates a new function with the same name as the given binder (but with a
78 -- new unique) and with the given function body. Returns the new binder for
80 mkFunction :: CoreBndr -> CoreExpr -> TranslatorSession CoreBndr
81 mkFunction bndr body = do
82 let ty = CoreUtils.exprType body
84 let newid = Var.setVarType id ty
85 addGlobalBind newid body