module UHC.Light.Compiler.CodeGen.CVar
( CVarInfo' (..)
, cvarShowKind
, CVarMp' (..), cvarMpLookup
, cvarLoc, cvarArg
, cvarIsLocOrArg, cvarIsGlobExt
, cvarGlob
, CVarNmModuleCfg (..), emptyCVarNmModuleCfg
, cvarToDef, cvarToRef
, cvarToDefHsName
, hsnJavaLikeVar )
where
import qualified Data.Map as Map
import Data.Bits
import Data.List
import Data.Char
import UHC.Light.Compiler.Base.HsName.Builtin
import UHC.Light.Compiler.CodeGen.BuiltinSizeInfo
import UHC.Util.Pretty
import UHC.Util.Utils
import qualified UHC.Util.FastSeq as Seq
import UHC.Light.Compiler.Opts.Base
import UHC.Light.Compiler.Base.HsName
import UHC.Light.Compiler.Base.Common
import UHC.Light.Compiler.CodeGen.BasicAnnot
import UHC.Light.Compiler.Foreign.Extract
data CVarInfo' tag ty varref datafldref tupfldref
= CVar_This
{ cvarType :: ty
}
| CVar_Local
{ cvarType :: ty
, cvarOffset :: !varref
}
| CVar_Arg
{ cvarType :: ty
, cvarOffset :: !varref
}
| CVar_DataFld
{ cvarType :: ty
, cvarData :: !(CVarInfo' tag ty varref datafldref tupfldref)
, cvarTag :: !tag
, cvarFld :: !datafldref
}
| CVar_DataTag
{ cvarType :: ty
, cvarData :: !(CVarInfo' tag ty varref datafldref tupfldref)
}
| CVar_TupFld
{ cvarType :: ty
, cvarTuple :: !(CVarInfo' tag ty varref datafldref tupfldref)
, cvarInx :: !(Either tupfldref HsName)
}
| CVar_GlobalExtern
{ cvarType :: ty
, cvarModNm :: !HsName
, cvarFldNm :: !HsName
}
| CVar_GlobalIntern
{ cvarType :: ty
, cvarMbModNm :: !(Maybe HsName)
, cvarFldNm :: !HsName
}
| CVar_None
| CVar_Error
{ cvarNm :: HsName
}
deriving (Eq,Ord)
cvarShowKind :: CVarInfo' tag ty varref datafldref tupfldref -> String
cvarShowKind cvi = case cvi of
CVar_This {} -> "Th"
CVar_Local {} -> "Lc"
CVar_Arg {} -> "Ar"
CVar_DataFld {} -> "DtFl"
CVar_DataTag {} -> "DtTg"
CVar_TupFld {} -> "TpFl"
CVar_GlobalExtern {} -> "GlEx"
CVar_GlobalIntern {} -> "GlIn"
CVar_None -> "No"
CVar_Error {} -> "Er"
type CVarMp' tag ty varref datafldref tupfldref = Map.Map HsName (CVarInfo' tag ty varref datafldref tupfldref)
cvarMpLookup :: HsName -> CVarMp' tag ty varref datafldref tupfldref -> Maybe (CVarInfo' tag ty varref datafldref tupfldref)
cvarMpLookup = Map.lookup
instance (Show datafldref, Show tupfldref, Show varref) => Show (CVarInfo' tag ty varref datafldref tupfldref) where
show (CVar_This { }) = "this"
show (CVar_Local { cvarOffset=n }) = show n
show (CVar_Arg { cvarOffset=n }) = show n
show (CVar_DataFld {cvarData=d , cvarFld=n }) = show d ++ "." ++ show n
show (CVar_DataTag {cvarData=d }) = show d ++ ".tag"
show (CVar_TupFld {cvarTuple=d , cvarInx=n }) = show d ++ "." ++ either show show n
show (CVar_GlobalExtern {cvarModNm=m , cvarFldNm=n }) = show m ++ "." ++ show n
show (CVar_GlobalIntern {cvarMbModNm=mbm , cvarFldNm=n }) = maybe "" (\m -> show m ++ ".") mbm ++ show n
show (CVar_Error { cvarNm=n }) = "#ERRREF#" ++ show n
show _ = "?CVar?"
instance (Show datafldref, Show tupfldref, Show varref) => PP (CVarInfo' tag ty varref datafldref tupfldref) where
pp = pp . show
cvarLoc :: ty -> varref -> CVarInfo' tag ty varref datafldref tupfldref
cvarLoc = CVar_Local
cvarArg :: ty -> varref -> CVarInfo' tag ty varref datafldref tupfldref
cvarArg = CVar_Arg
cvarIsLocOrArg (CVar_Local {}) = True
cvarIsLocOrArg (CVar_Arg {}) = True
cvarIsLocOrArg _ = False
cvarIsGlobExt (CVar_GlobalExtern {}) = True
cvarIsGlobExt _ = False
cvarGlob :: CVarNmModuleCfg -> ty -> HsName -> HsName -> CVarInfo' tag ty varref datafldref tupfldref
cvarGlob cfg ty mbModNm varNm
= CVar_GlobalExtern ty clNm' varNm
where clNm' = maybe (cvnmcfgModInTop cfg) (\m -> hsnSetQual m $ hsnQualified m) $ hsnQualifier mbModNm
data CVarNmModuleCfg = CVarNmModuleCfg
{ cvnmcfgPkg :: HsName
, cvnmcfgTopInPkg :: HsName
, cvnmcfgModInTop :: HsName
}
emptyCVarNmModuleCfg = CVarNmModuleCfg hsnUnknown hsnUnknown hsnUnknown
cvarToRef
:: ( HsName -> e
, ty -> e
, ty -> varref -> e
, ty -> varref -> e
, ty -> HsName -> HsName -> e
, ty -> Maybe HsName -> HsName -> e
, ty -> e -> taginfo -> datafldref -> e
, ty -> e -> e
, e -> e -> e
, tupfldref -> e
, CVarNmModuleCfg -> tag -> taginfo
, CVarNmModuleCfg -> Bool -> HsName -> HsName
)
-> CVarNmModuleCfg
-> CVarMp' tag ty varref datafldref tupfldref
-> CVarInfo' tag ty varref datafldref tupfldref
-> e
cvarToDef
:: ( HsName -> e
, ty -> varref -> e
, ty -> varref -> e
, ty -> HsName -> HsName -> e
, ty -> Maybe HsName -> HsName -> e
, ty -> e -> taginfo -> datafldref -> e
, ty -> e -> e
, e -> e -> e
, tupfldref -> e
, CVarNmModuleCfg -> tag -> taginfo
, CVarNmModuleCfg -> Bool -> HsName -> HsName
)
-> CVarNmModuleCfg
-> CVarMp' tag ty varref datafldref tupfldref
-> CVarInfo' tag ty varref datafldref tupfldref
-> e
(cvarToDef, cvarToRef)
= ( \(mkErrorRef,mkLocal,mkArg,mkGlobalExt,mkGlobalInt,mkDataFld,mkDataTag,mkTupFld,mkOffset,mkTag,mkSafeName)
cfg cvarMp vi -> let ref vi
= case vi of
CVar_This t -> panic "CVar.cvarToDef.CVar_This"
CVar_Local t o -> mkLocal t o
CVar_Arg t o -> mkArg t o
CVar_GlobalExtern t m f -> mkGlEx mkGlobalExt cfg mkSafeName t m f
CVar_GlobalIntern t m f -> mkGlIn mkGlobalInt cfg mkSafeName t m f
CVar_DataFld t cvid cl f -> mkDtFl ref cfg mkDataFld mkTag t cvid cl f
CVar_DataTag t cvid -> mkDtTg ref mkDataTag t cvid
CVar_TupFld t cvit f -> mkTpFl ref cvarMp mkTupFld mkOffset t cvit f
CVar_None -> panic "CVar.cvarToDef.CVar_None"
CVar_Error n -> mkErrorRef n
in ref vi
, \(mkErrorRef,mkThis,mkLocal,mkArg,mkGlobalExt,mkGlobalInt,mkDataFld,mkDataTag,mkTupFld,mkOffset,mkTag,mkSafeName)
cfg cvarMp vi -> let ref vi
= case vi of
CVar_This t -> mkThis t
CVar_Local t o -> mkLocal t o
CVar_Arg t o -> mkArg t o
CVar_GlobalExtern t m f -> mkGlEx mkGlobalExt cfg mkSafeName t m f
CVar_GlobalIntern t m f -> mkGlIn mkGlobalInt cfg mkSafeName t m f
CVar_DataFld t cvid cl f -> mkDtFl ref cfg mkDataFld mkTag t cvid cl f
CVar_DataTag t cvid -> mkDtTg ref mkDataTag t cvid
CVar_TupFld t cvit f -> mkTpFl ref cvarMp mkTupFld mkOffset t cvit f
CVar_None -> panic "CVar.cvarToRef.CVar_None"
CVar_Error n -> mkErrorRef n
in ref vi
)
where mkGlIn mkGlobal cfg mkSafeName t m f = mkGlobal t m (mkSafeName cfg True f)
mkGlEx = mkGlIn
mkDtFl ref cfg mkDataFld mkTag t cvid cl f = mkDataFld t (ref cvid) (mkTag cfg cl) f
mkDtTg ref mkDataTag t cvid = mkDataTag t (ref cvid)
mkTpFl ref cvarMp mkTupFld mkOffset t cvit f = mkTupFld (ref cvit) o
where o = case f of
Left o -> mkOffset o
Right n -> ref $ panicJust "CVar.cvarTo{RD}ef.CVar_TupFld" $ cvarMpLookup n cvarMp
cvarToDefHsName
:: ( String -> HsName
, varref -> HsName
, datafldref -> HsName
, tupfldref -> HsName
, CVarNmModuleCfg -> tag -> taginfo
, CVarNmModuleCfg -> Bool -> HsName -> HsName
)
-> CVarNmModuleCfg
-> CVarMp' tag ty varref datafldref tupfldref
-> CVarInfo' tag ty varref datafldref tupfldref
-> HsName
cvarToDefHsName
(mkError,mkLocal,mkDataFld,mkTupFld,mkTag,mkSafeName)
= cvarToDef
( \r -> mkError $ "cvarToDefHsName.mkErrorRef: " ++ show r
, mkLocArg
, mkLocArg
, \_ _ r -> r
, \_ _ r -> r
, \_ _ _ r -> mkDataFld r
, \_ _ -> mkError "cannot cvarToDefHsName.mkDataTag"
, \_ _ -> mkError "cannot cvarToDefHsName.mkTupFld"
, mkTupFld
, mkTag
, mkSafeName
)
where mkLocArg = \_ r -> mkLocal r
hsnJavaLikeVar
:: ( Bool -> HsName -> HsName
, HsName -> HsName
, String -> String
)
-> CVarNmModuleCfg
-> Bool
-> HsName
-> HsName
hsnJavaLikeVar (preadapt, postprefix, updqual) cfg isglob v
= postprefix $ hsnSafeJavaLike $ handleUpper $ qual $ preadapt isglob v
where handleUpper v
= case hsnBaseUnpack v of
Just (s@(c:vs), mk) | isUpper c -> mk (s ++ "_")
_ -> v
qual v
= case hsnBaseUnpack' v of
Just (q, s, mk) -> mk (map updqual q) s
_ -> v