Since the type of identifiers is not hardwired in the type checker, this module defines some type classes that capture what the type checker needs to do with identifiers.
module TiNames where
import Char(isAlphaNum)
import HsIdent
import HsName(ModuleName)
import HsConstants(mod_Prelude)
import SrcLoc(SrcLoc,srcFile,srcLoc)
import SrcLocPretty(shLineCol)
import PrettyPrint(Printable,pp)
import SpecialNames
import TypedIds(IdTy(..),HasIdTy(..))
import UniqueNames(PN)
type SrcName = String
class ValueId i where
topName :: Maybe SrcLoc -> ModuleName -> SrcName -> IdTy (PN String) -> i
localVal' :: SrcName -> Maybe SrcLoc -> i
--instName :: ModuleName -> SrcLoc -> i
dictName' :: Int -> Maybe SrcLoc -> i
superName :: i -> Int -> i
defaultName :: i -> i
class HasIdTy n i => TypedId n i | i->n where
idName :: i -> n
isCon i =
case idTy i of
ConstrOf {} -> True
_ -> False
dictName i = dictName' i Nothing
conName' s m n t ty = topName s m n (ConstrOf t ty)
conName m = conName' Nothing m
prelCon c = conName mod_Prelude c
localVal n = localVal' n Nothing
topVal' m n s = topName s m n Value
topVal m n = topVal' m n Nothing
prelVal' n = topVal' mod_Prelude n
prelVal n = prelVal' n Nothing
instName generates context-independent, unique names for instance declarations. The module name is included so that the instance names remain unique when mutually recursive groups of modules are combined into one module.
instName m s inst =
--topName (Just s) m ("inst__"++pp m++"_"++shLineCol s) Value
topName (Just s) m ("inst__"++dots2uscore (pp m)++"_"++mangle (pp inst)) Value
where
-- A quick hack: !!!
mangle = concatMap mangle1
mangle1 c =
case c of
' ' -> "_"
'(' -> "_l_"
')' -> "_r_"
_ -> if isAlphaNum c then [c] else "_"++show (fromEnum c)
instName' modmap s = instName (modmap (srcFile s)) s
derivedInstName' modmap cl = derivedInstName m cl
where
s = srcLoc cl
m = modmap (srcFile s)
derivedInstName m cl tn =
topName (Just s) m ("derived__"++dots2uscore (pp m)++"_"++pp cl++"_"++n) Value
where
s = srcLoc cl
ts = pp tn
n = if all isAlphaNum' ts
then ts
else shLineCol s
isAlphaNum' c = c `elem` "_'" || isAlphaNum c
-- For the annoying 'hierarchical' module name extension:
dots2uscore = map dot2uscore
dot2uscore '.' = '_'
dot2uscore c = c
class (HasSpecialNames i,IsSpecialName i) => TypeCon i where
topType :: ModuleName -> SrcName -> i
prelType n = topType mod_Prelude n
class (Ord i,Printable i) => TypeVar i where
tvar :: Int -> i
ltvar :: SrcName -> i
class (TypeCon i,TypeVar i) => TypeId i
-- Prelude values and constructors
pv n = HsVar (prelVal n)
pc n = HsCon (prelVal n)