module UHC.Light.Compiler.CodeGen.Const
( module UHC.Light.Compiler.CodeGen.BasicAnnot
, CFld, ConstRef (..)
, cfldGlobInx
, Const (..)
, isFFIConst
, ConstSt (..), emptyConstSt
, add
, addStr, addNm, addFFIFun, addFFICallEncWrapper )
where
import UHC.Light.Compiler.Base.Common
import UHC.Light.Compiler.Base.HsName.Builtin
import UHC.Light.Compiler.CodeGen.RefGenerator
import UHC.Util.Utils
import UHC.Util.Pretty as Pretty
import Data.Bits
import Data.Maybe
import qualified UHC.Util.FastSeq as Seq
import qualified Data.Map as Map
import qualified Data.Set as Set
import Control.Monad
import Control.Monad.State
import UHC.Light.Compiler.CodeGen.BasicAnnot
data ConstRef = ConstRef
{ constrefGlobal :: !Int
, constrefInCateg :: !Int
}
instance Show ConstRef where
show r = "CRef_" ++ show (constrefGlobal r) ++ "_" ++ show (constrefInCateg r)
type CFld = Fld' ConstRef
instance RefOfFld CFld Int where
refOfFld = constrefGlobal . fromJust . _fldInx
instance RefOfFld CFld HsName where
refOfFld = fromJust . _fldNm
cfldGlobInx :: CFld -> Int
cfldGlobInx = refOfFld
data Const
= Const_FFIFunction
{ constFFIFunNm :: !String
}
| Const_FFICallEncWrapper
{ constFFIArgSizes :: ![BasicSize]
}
| Const_String
{ constString :: !String
}
| Const_Nm
{ constNm :: !HsName
}
deriving(Eq,Ord,Show)
isFFIConst :: Const -> Bool
isFFIConst (Const_FFIFunction {}) = True
isFFIConst (Const_FFICallEncWrapper {}) = True
isFFIConst _ = False
categ :: Const -> String
categ (Const_FFIFunction {}) = "funffi"
categ (Const_FFICallEncWrapper {}) = "encffi"
categ (Const_String {}) = "str"
categ (Const_Nm {}) = "nm"
data ConstSt = ConstSt
{ conststMp :: !(Map.Map Const CFld)
, conststGlobalCnt :: !Int
, conststInCategCntMp :: !(Map.Map String Int)
}
emptyConstSt = ConstSt Map.empty 0 Map.empty
addM :: Const -> State ConstSt CFld
addM c = do
st <- get
case Map.lookup c (conststMp st) of
Just r -> return r
_ -> do put $ st
{ conststMp = Map.insert c ref (conststMp st)
, conststGlobalCnt = ginx+1
, conststInCategCntMp = Map.insert cat (cinx+1) (conststInCategCntMp st)
}
return ref
where ginx = conststGlobalCnt st
cat = categ c
cinx = Map.findWithDefault 0 cat $ conststInCategCntMp st
ref = Fld (Just $ mkHNm $ cat ++ show cinx) (Just $ ConstRef ginx cinx)
add :: Const -> ConstSt -> (CFld,ConstSt)
add c = runState $ addM c
addStr :: String -> ConstSt -> (CFld,ConstSt)
addStr s = add (Const_String s)
addNm :: HsName -> ConstSt -> (CFld,ConstSt)
addNm nm = add (Const_Nm nm)
addFFIFun :: String -> ConstSt -> (CFld,ConstSt)
addFFIFun nm = add (Const_FFIFunction nm)
addFFICallEncWrapper :: [BasicSize] -> ConstSt -> (CFld,ConstSt)
addFFICallEncWrapper szs = add (Const_FFICallEncWrapper szs)