Use MD5 checksums for recompilation checking (fixes #1372, #1959)
[ghc-hetmet.git] / compiler / basicTypes / OccName.lhs
index 13a7f81..debaa28 100644 (file)
@@ -1,12 +1,11 @@
-{-% DrIFT (Automatic class derivations for Haskell) v1.1 %-}
 %
+% (c) The University of Glasgow 2006
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 
-\section[OccName]{@OccName@}
-
 \begin{code}
 module OccName (
+        mk_deriv,
        -- * The NameSpace type; abstact
        NameSpace, tcName, clsName, tcClsName, dataName, varName, 
        tvName, srcDataName,
@@ -27,13 +26,19 @@ module OccName (
        setOccNameSpace,
 
        -- ** Derived OccNames
+        isDerivedOccName,
        mkDataConWrapperOcc, mkWorkerOcc, mkDefaultMethodOcc,
-       mkDerivedTyConOcc, mkNewTyCoOcc,
+       mkDerivedTyConOcc, mkNewTyCoOcc, 
+        mkCon2TagOcc, mkTag2ConOcc, mkMaxTagOcc,
        mkClassTyConOcc, mkClassDataConOcc, mkDictOcc, mkIPOcc, 
        mkSpecOcc, mkForeignExportOcc, mkGenOcc1, mkGenOcc2,
        mkDataTOcc, mkDataCOcc, mkDataConWorkerOcc,
        mkSuperDictSelOcc, mkLocalOcc, mkMethodOcc, mkInstTyTcOcc,
-       mkInstTyCoOcc, 
+       mkInstTyCoOcc, mkEqPredCoOcc,
+        mkVectOcc, mkVectTyConOcc, mkVectDataConOcc, mkVectIsoOcc,
+        mkPArrayTyConOcc, mkPArrayDataConOcc,
+        mkPReprTyConOcc,
+        mkPADFunOcc,
 
        -- ** Deconstruction
        occNameFS, occNameString, occNameSpace, 
@@ -45,15 +50,16 @@ module OccName (
 
        -- The OccEnv type
        OccEnv, emptyOccEnv, unitOccEnv, extendOccEnv, mapOccEnv,
-       lookupOccEnv, mkOccEnv, extendOccEnvList, elemOccEnv,
+       lookupOccEnv, mkOccEnv, mkOccEnv_C, extendOccEnvList, elemOccEnv,
        occEnvElts, foldOccEnv, plusOccEnv, plusOccEnv_C, extendOccEnv_C,
+        filterOccEnv, delListFromOccEnv, delFromOccEnv,
 
        -- The OccSet type
        OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet, 
        extendOccSetList,
        unionOccSets, unionManyOccSets, minusOccSet, elemOccSet, occSetElts, 
        foldOccSet, isEmptyOccSet, intersectOccSet, intersectsOccSet,
-
+                  
        -- Tidying up
        TidyOccEnv, emptyTidyOccEnv, tidyOccName, initTidyOccEnv,
 
@@ -63,26 +69,24 @@ module OccName (
        startsVarSym, startsVarId, startsConSym, startsConId
     ) where
 
-#include "HsVersions.h"
-
-import Util            ( thenCmp )
-import Unique          ( Unique, mkUnique, Uniquable(..) )
-import BasicTypes      ( Boxity(..), Arity )
-import StaticFlags     ( opt_PprStyle_Debug )
+import Util
+import Unique
+import BasicTypes
+import StaticFlags
 import UniqFM
 import UniqSet
 import FastString
+import FastTypes
 import Outputable
 import Binary
 
-import GLAEXTS
-
-import Data.Char       ( isUpper, isLower, ord )
+import GHC.Exts
+import Data.Char
 
 -- Unicode TODO: put isSymbol in libcompat
-#if __GLASGOW_HASKELL__ > 604
-import Data.Char       ( isSymbol )
+#if !defined(__GLASGOW_HASKELL__) || __GLASGOW_HASKELL__ > 604
 #else
+isSymbol :: a -> Bool
 isSymbol = const False
 #endif
 
@@ -95,8 +99,8 @@ isSymbol = const False
 %************************************************************************
 
 \begin{code}
-data NameSpace = VarName       -- Variables, including "source" data constructors
-              | DataName       -- "Real" data constructors 
+data NameSpace = VarName       -- Variables, including "real" data constructors
+              | DataName       -- "Source" data constructors 
               | TvName         -- Type variables
               | TcClsName      -- Type constructors and classes; Haskell has them
                                -- in the same name space for now.
@@ -120,6 +124,9 @@ data NameSpace = VarName    -- Variables, including "source" data constructors
 -- The real   datacon has type Int -> Int -> T
 -- GHC chooses a representation based on the strictness etc.
 
+tcName, clsName, tcClsName :: NameSpace
+dataName, srcDataName      :: NameSpace
+tvName, varName            :: NameSpace
 
 -- Though type constructors and classes are in the same name space now,
 -- the NameSpace type is abstract, so we can easily separate them later
@@ -141,22 +148,23 @@ isTcClsName _           = False
 isVarName :: NameSpace -> Bool -- Variables or type variables, but not constructors
 isVarName TvName  = True
 isVarName VarName = True
-isVarName other   = False
+isVarName _       = False
 
 pprNameSpace :: NameSpace -> SDoc
-pprNameSpace DataName  = ptext SLIT("data constructor")
-pprNameSpace VarName   = ptext SLIT("variable")
-pprNameSpace TvName    = ptext SLIT("type variable")
-pprNameSpace TcClsName = ptext SLIT("type constructor or class")
+pprNameSpace DataName  = ptext (sLit "data constructor")
+pprNameSpace VarName   = ptext (sLit "variable")
+pprNameSpace TvName    = ptext (sLit "type variable")
+pprNameSpace TcClsName = ptext (sLit "type constructor or class")
 
 pprNonVarNameSpace :: NameSpace -> SDoc
 pprNonVarNameSpace VarName = empty
 pprNonVarNameSpace ns = pprNameSpace ns
 
+pprNameSpaceBrief :: NameSpace -> SDoc
 pprNameSpaceBrief DataName  = char 'd'
 pprNameSpaceBrief VarName   = char 'v'
-pprNameSpaceBrief TvName    = ptext SLIT("tv")
-pprNameSpaceBrief TcClsName = ptext SLIT("tc")
+pprNameSpaceBrief TvName    = ptext (sLit "tv")
+pprNameSpaceBrief TcClsName = ptext (sLit "tc")
 \end{code}
 
 
@@ -179,8 +187,9 @@ instance Eq OccName where
     (OccName sp1 s1) == (OccName sp2 s2) = s1 == s2 && sp1 == sp2
 
 instance Ord OccName where
-    compare (OccName sp1 s1) (OccName sp2 s2) = (s1  `compare` s2) `thenCmp`
-                                               (sp1 `compare` sp2)
+       -- Compares lexicographically, *not* by Unique of the string
+    compare (OccName sp1 s1) (OccName sp2 s2) 
+       = (s1  `compare` s2) `thenCmp` (sp1 `compare` sp2)
 \end{code}
 
 
@@ -246,7 +255,7 @@ easy to build an OccEnv.
 \begin{code}
 instance Uniquable OccName where
   getUnique (OccName ns fs)
-      = mkUnique char (I# (uniqueOfFS fs))
+      = mkUnique char (iBox (uniqueOfFS fs))
       where    -- See notes above about this getUnique function
         char = case ns of
                VarName   -> 'i'
@@ -254,7 +263,7 @@ instance Uniquable OccName where
                TvName    -> 'v'
                TcClsName -> 't'
 
-type OccEnv a = UniqFM a
+newtype OccEnv a = A (UniqFM a)
 
 emptyOccEnv :: OccEnv a
 unitOccEnv  :: OccName -> a -> OccEnv a
@@ -262,6 +271,7 @@ extendOccEnv :: OccEnv a -> OccName -> a -> OccEnv a
 extendOccEnvList :: OccEnv a -> [(OccName, a)] -> OccEnv a
 lookupOccEnv :: OccEnv a -> OccName -> Maybe a
 mkOccEnv     :: [(OccName,a)] -> OccEnv a
+mkOccEnv_C   :: (a -> a -> a) -> [(OccName,a)] -> OccEnv a
 elemOccEnv   :: OccName -> OccEnv a -> Bool
 foldOccEnv   :: (a -> b -> b) -> b -> OccEnv a -> b
 occEnvElts   :: OccEnv a -> [a]
@@ -269,22 +279,32 @@ extendOccEnv_C :: (a->a->a) -> OccEnv a -> OccName -> a -> OccEnv a
 plusOccEnv     :: OccEnv a -> OccEnv a -> OccEnv a
 plusOccEnv_C   :: (a->a->a) -> OccEnv a -> OccEnv a -> OccEnv a
 mapOccEnv      :: (a->b) -> OccEnv a -> OccEnv b
-
-emptyOccEnv     = emptyUFM
-unitOccEnv      = unitUFM
-extendOccEnv    = addToUFM
-extendOccEnvList = addListToUFM
-lookupOccEnv    = lookupUFM
-mkOccEnv         = listToUFM
-elemOccEnv      = elemUFM
-foldOccEnv      = foldUFM
-occEnvElts      = eltsUFM
-plusOccEnv      = plusUFM
-plusOccEnv_C    = plusUFM_C
-extendOccEnv_C   = addToUFM_C
-mapOccEnv       = mapUFM
-
-type OccSet = UniqFM OccName
+delFromOccEnv     :: OccEnv a -> OccName -> OccEnv a
+delListFromOccEnv :: OccEnv a -> [OccName] -> OccEnv a
+filterOccEnv      :: (elt -> Bool) -> OccEnv elt -> OccEnv elt
+
+emptyOccEnv     = A emptyUFM
+unitOccEnv x y = A $ unitUFM x y 
+extendOccEnv (A x) y z = A $ addToUFM x y z
+extendOccEnvList (A x) l = A $ addListToUFM x l
+lookupOccEnv (A x) y = lookupUFM x y
+mkOccEnv     l    = A $ listToUFM l
+elemOccEnv x (A y)      = elemUFM x y
+foldOccEnv a b (A c)    = foldUFM a b c 
+occEnvElts (A x)        = eltsUFM x
+plusOccEnv (A x) (A y)  = A $ plusUFM x y 
+plusOccEnv_C f (A x) (A y)      = A $ plusUFM_C f x y 
+extendOccEnv_C f (A x) y z   = A $ addToUFM_C f x y z
+mapOccEnv f (A x)       = A $ mapUFM f x
+mkOccEnv_C comb l = A $ addListToUFM_C comb emptyUFM l
+delFromOccEnv (A x) y    = A $ delFromUFM x y
+delListFromOccEnv (A x) y  = A $ delListFromUFM x y
+filterOccEnv x (A y)       = A $ filterUFM x y
+
+instance Outputable a => Outputable (OccEnv a) where
+    ppr (A x) = ppr x
+
+type OccSet = UniqSet OccName
 
 emptyOccSet      :: OccSet
 unitOccSet       :: OccName -> OccSet
@@ -331,20 +351,20 @@ occNameString (OccName _ s) = unpackFS s
 setOccNameSpace :: NameSpace -> OccName -> OccName
 setOccNameSpace sp (OccName _ occ) = OccName sp occ
 
-isVarOcc, isTvOcc, isDataSymOcc, isSymOcc, isTcOcc :: OccName -> Bool
+isVarOcc, isTvOcc, isDataSymOcc, isSymOcc, isTcOcc, isValOcc, isDataOcc :: OccName -> Bool
 
 isVarOcc (OccName VarName _) = True
-isVarOcc other               = False
+isVarOcc _                   = False
 
 isTvOcc (OccName TvName _) = True
-isTvOcc other              = False
+isTvOcc _                  = False
 
 isTcOcc (OccName TcClsName _) = True
-isTcOcc other                 = False
+isTcOcc _                     = False
 
 isValOcc (OccName VarName  _) = True
 isValOcc (OccName DataName _) = True
-isValOcc other               = False
+isValOcc _                    = False
 
 -- Data constructor operator (starts with ':', or '[]')
 -- Pretty inefficient!
@@ -352,20 +372,20 @@ isDataSymOcc (OccName DataName s) = isLexConSym s
 isDataSymOcc (OccName VarName s)  
   | isLexConSym s = pprPanic "isDataSymOcc: check me" (ppr s)
                -- Jan06: I don't think this should happen
-isDataSymOcc other               = False
+isDataSymOcc _                    = False
 
 isDataOcc (OccName DataName _) = True
 isDataOcc (OccName VarName s)  
   | isLexCon s = pprPanic "isDataOcc: check me" (ppr s)
                -- Jan06: I don't think this should happen
-isDataOcc other                       = False
+isDataOcc _                    = False
 
 -- Any operator (data constructor or variable)
 -- Pretty inefficient!
 isSymOcc (OccName DataName s)  = isLexConSym s
 isSymOcc (OccName TcClsName s) = isLexConSym s
 isSymOcc (OccName VarName s)   = isLexSym s
-isSymOcc other                = False
+isSymOcc (OccName TvName s)    = isLexSym s
 
 parenSymOcc :: OccName -> SDoc -> SDoc
 -- Wrap parens around an operator
@@ -401,6 +421,7 @@ Here's our convention for splitting up the interface file name space:
        $w...           workers
        :T...           compiler-generated tycons for dictionaries
        :D...           ...ditto data cons
+        :Co...          ...ditto coercions
        $sf..           specialised version of f
 
        in encoded form these appear as Zdfxxx etc
@@ -410,7 +431,6 @@ Here's our convention for splitting up the interface file name space:
 
 This knowledge is encoded in the following functions.
 
-
 @mk_deriv@ generates an @OccName@ from the prefix and a string.
 NB: The string must already be encoded!
 
@@ -421,13 +441,24 @@ mk_deriv :: NameSpace
         -> OccName
 
 mk_deriv occ_sp sys_prefix str = mkOccName occ_sp (sys_prefix ++ str)
+
+isDerivedOccName :: OccName -> Bool
+isDerivedOccName occ = 
+   case occNameString occ of
+     '$':c:_ | isAlphaNum c -> True
+     ':':c:_ | isAlphaNum c -> True
+     _other                 -> False
 \end{code}
 
 \begin{code}
 mkDataConWrapperOcc, mkWorkerOcc, mkDefaultMethodOcc, mkDerivedTyConOcc,
        mkClassTyConOcc, mkClassDataConOcc, mkDictOcc, mkIPOcc, 
        mkSpecOcc, mkForeignExportOcc, mkGenOcc1, mkGenOcc2,
-       mkDataTOcc, mkDataCOcc, mkDataConWorkerOcc, mkNewTyCoOcc
+       mkDataTOcc, mkDataCOcc, mkDataConWorkerOcc, mkNewTyCoOcc,
+       mkInstTyCoOcc, mkEqPredCoOcc, 
+        mkCon2TagOcc, mkTag2ConOcc, mkMaxTagOcc,
+       mkVectOcc, mkVectTyConOcc, mkVectDataConOcc, mkVectIsoOcc,
+       mkPArrayTyConOcc, mkPArrayDataConOcc, mkPReprTyConOcc, mkPADFunOcc
    :: OccName -> OccName
 
 -- These derived variables have a prefix that no Haskell value could have
@@ -442,7 +473,14 @@ mkDictOcc      = mk_simple_deriv varName  "$d"
 mkIPOcc                    = mk_simple_deriv varName  "$i"
 mkSpecOcc          = mk_simple_deriv varName  "$s"
 mkForeignExportOcc  = mk_simple_deriv varName  "$f"
-mkNewTyCoOcc        = mk_simple_deriv tcName  "Co"
+mkNewTyCoOcc        = mk_simple_deriv tcName  ":Co"
+mkInstTyCoOcc       = mk_simple_deriv tcName  ":CoF"     -- derived from rep ty
+mkEqPredCoOcc      = mk_simple_deriv tcName  "$co"
+
+-- used in derived instances
+mkCon2TagOcc        = mk_simple_deriv varName  "$con2tag_"
+mkTag2ConOcc        = mk_simple_deriv varName  "$tag2con_"
+mkMaxTagOcc         = mk_simple_deriv varName  "$maxtag_"
 
 -- Generic derivable classes
 mkGenOcc1           = mk_simple_deriv varName  "$gfrom"
@@ -454,6 +492,17 @@ mkGenOcc2           = mk_simple_deriv varName  "$gto"
 mkDataTOcc = mk_simple_deriv varName  "$t"
 mkDataCOcc = mk_simple_deriv varName  "$c"
 
+-- Vectorisation
+mkVectOcc          = mk_simple_deriv varName  "$v_"
+mkVectTyConOcc     = mk_simple_deriv tcName   ":V_"
+mkVectDataConOcc   = mk_simple_deriv dataName ":VD_"
+mkVectIsoOcc       = mk_simple_deriv varName  "$VI_"
+mkPArrayTyConOcc   = mk_simple_deriv tcName   ":VP_"
+mkPArrayDataConOcc = mk_simple_deriv dataName ":VPD_"
+mkPReprTyConOcc    = mk_simple_deriv tcName   ":VR_"
+mkPADFunOcc        = mk_simple_deriv varName  "$PA_"
+
+mk_simple_deriv :: NameSpace -> String -> OccName -> OccName
 mk_simple_deriv sp px occ = mk_deriv sp px (occNameString occ)
 
 -- Data constructor workers are made by setting the name space
@@ -478,25 +527,15 @@ mkLocalOcc uniq occ
        -- that need encoding (e.g. 'z'!)
 \end{code}
 
-\begin{code}
-
--- Derive a name for the representation type constructor of a data/newtype
--- instance.
---
-mkInstTyTcOcc :: Unique                -- Unique
-             -> OccName                -- Local name (e.g. "Map")
-             -> OccName                -- Nice unique version (":T23Map")
-mkInstTyTcOcc uniq occ
-   = mk_deriv varName (":T" ++ show uniq) (occNameString occ)
-
--- Derive a name for the coercion of a data/newtype instance.
---
-mkInstTyCoOcc :: Unique                -- Unique
-             -> OccName                -- Local name (e.g. "Map")
-             -> OccName                -- Nice unique version ("Co23Map")
-mkInstTyCoOcc uniq occ
-   = mk_deriv varName ("Co" ++ show uniq) (occNameString occ)
+Derive a name for the representation type constructor of a data/newtype
+instance.
 
+\begin{code}
+mkInstTyTcOcc :: Int                   -- Index
+             -> OccName                -- Family name (e.g. "Map")
+             -> OccName                -- Nice unique version (":R23Map")
+mkInstTyTcOcc index occ
+   = mk_deriv tcName (":R" ++ show index) (occNameString occ)
 \end{code}
 
 \begin{code}
@@ -540,8 +579,8 @@ guys never show up in error messages.  What a hack.
 
 \begin{code}
 mkMethodOcc :: OccName -> OccName
-mkMethodOcc occ@(OccName VarName fs) = occ
-mkMethodOcc occ                             = mk_simple_deriv varName "$m" occ
+mkMethodOcc occ@(OccName VarName _) = occ
+mkMethodOcc occ                     = mk_simple_deriv varName "$m" occ
 \end{code}
 
 
@@ -566,6 +605,7 @@ tack on the '1', if necessary.
 type TidyOccEnv = OccEnv Int   -- The in-scope OccNames
        -- Range gives a plausible starting point for new guesses
 
+emptyTidyOccEnv :: TidyOccEnv
 emptyTidyOccEnv = emptyOccEnv
 
 initTidyOccEnv :: [OccName] -> TidyOccEnv      -- Initialise with names to avoid!
@@ -636,18 +676,18 @@ isLexSym cs = isLexConSym cs || isLexVarSym cs
 -------------
 
 isLexConId cs                          -- Prefix type or data constructors
-  | nullFS cs        = False           --      e.g. "Foo", "[]", "(,)" 
-  | cs == FSLIT("[]") = True
-  | otherwise        = startsConId (headFS cs)
+  | nullFS cs         = False          --      e.g. "Foo", "[]", "(,)" 
+  | cs == (fsLit "[]") = True
+  | otherwise         = startsConId (headFS cs)
 
 isLexVarId cs                          -- Ordinary prefix identifiers
   | nullFS cs        = False           --      e.g. "x", "_x"
   | otherwise         = startsVarId (headFS cs)
 
 isLexConSym cs                         -- Infix type or data constructors
-  | nullFS cs        = False           --      e.g. ":-:", ":", "->"
-  | cs == FSLIT("->") = True
-  | otherwise        = startsConSym (headFS cs)
+  | nullFS cs         = False          --      e.g. ":-:", ":", "->"
+  | cs == (fsLit "->") = True
+  | otherwise         = startsConSym (headFS cs)
 
 isLexVarSym cs                         -- Infix identifiers
   | nullFS cs        = False           --      e.g. "+"
@@ -660,6 +700,7 @@ startsConSym c = c == ':'                           -- Infix data constructors
 startsVarId c  = isLower c || c == '_' -- Ordinary Ids
 startsConId c  = isUpper c || c == '(' -- Ordinary type constructors and data constructors
 
+isSymbolASCII :: Char -> Bool
 isSymbolASCII c = c `elem` "!#$%&*+./<=>?@\\^|~-"
 \end{code}