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