module DDC.Core.Llvm.Convert.Base ( ConvertM , LlvmState(..) , llvmStateInit -- * Errors , Error (..) , throw -- * Uniques , newUnique , newUniqueVar , newUniqueNamedVar , newUniqueLabel) where import DDC.Core.Llvm.Convert.Error import DDC.Llvm.Syntax import DDC.Control.Monad.Check import Data.Map (Map) import qualified Data.Map as Map -- ConvertM --------------------------------------------------------------------------------------- -- | The toLLVM conversion monad. type ConvertM = CheckM LlvmState Error -- LlvmState -------------------------------------------------------------------------------------- -- | State for the LLVM conversion. data LlvmState = LlvmState { -- Unique name generator. llvmStateUnique :: Int -- String and array constants collected from the code during conversion. -- These get stored in statically allocated memory. , llvmConstants :: Map Var Lit } -- | Initial LLVM state. llvmStateInit :: LlvmState llvmStateInit = LlvmState { llvmStateUnique = 1 , llvmConstants = Map.empty } -- Unique ----------------------------------------------------------------------------------------- -- | Unique name generation. newUnique :: ConvertM Int newUnique = do s <- get let u = llvmStateUnique s put $ s { llvmStateUnique = u + 1 } return $ u -- | Generate a new unique register variable with the specified `LlvmType`. newUniqueVar :: Type -> ConvertM Var newUniqueVar t = do u <- newUnique return $ Var (NameLocal ("_v" ++ show u)) t -- | Generate a new unique named register variable with the specified `LlvmType`. newUniqueNamedVar :: String -> Type -> ConvertM Var newUniqueNamedVar name t = do u <- newUnique return $ Var (NameLocal ("_v" ++ show u ++ "." ++ name)) t -- | Generate a new unique label. newUniqueLabel :: String -> ConvertM Label newUniqueLabel name = do u <- newUnique return $ Label ("l" ++ show u ++ "." ++ name)