X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FbasicTypes%2FOccName.lhs;h=0faa8706963f8b60c81b19e70f6f04ebf4e8aed5;hb=5b7cf08b9536041724146221aaf8e04236e57cb4;hp=faf7aa8988c94c6dbe4d0c10cf49823a73569fc5;hpb=70b66a28aa5ef80bababb1ca239b2c69e1362147;p=ghc-hetmet.git diff --git a/ghc/compiler/basicTypes/OccName.lhs b/ghc/compiler/basicTypes/OccName.lhs index faf7aa8..0faa870 100644 --- a/ghc/compiler/basicTypes/OccName.lhs +++ b/ghc/compiler/basicTypes/OccName.lhs @@ -1,3 +1,4 @@ +{-% DrIFT (Automatic class derivations for Haskell) v1.1 %-} % % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % @@ -8,21 +9,25 @@ module OccName ( -- The NameSpace type; abstact NameSpace, tcName, clsName, tcClsName, dataName, varName, - tvName, nameSpaceString, + tvName, srcDataName, nameSpaceString, -- The OccName type OccName, -- Abstract, instance of Outputable pprOccName, - mkOccFS, mkSysOcc, mkSysOccFS, mkFCallOcc, mkVarOcc, mkKindOccFS, + mkOccFS, mkSysOcc, mkSysOccFS, mkFCallOcc, mkKindOccFS, + mkVarOcc, mkVarOccEncoded, mkSuperDictSelOcc, mkDFunOcc, mkForeignExportOcc, mkDictOcc, mkIPOcc, mkWorkerOcc, mkMethodOcc, mkDefaultMethodOcc, mkDerivedTyConOcc, mkClassTyConOcc, mkClassDataConOcc, mkSpecOcc, - mkGenOcc1, mkGenOcc2, mkLocalOcc, + mkGenOcc1, mkGenOcc2, mkLocalOcc, + mkDataConWrapperOcc, mkDataConWorkerOcc, isTvOcc, isTcOcc, isDataOcc, isDataSymOcc, isSymOcc, isValOcc, + reportIfUnused, - occNameFS, occNameString, occNameUserString, occNameSpace, occNameFlavour, + occNameFS, occNameString, occNameUserString, occNameSpace, + occNameFlavour, briefOccNameFlavour, setOccNameSpace, -- Tidying up @@ -44,8 +49,11 @@ import Char ( isDigit, isUpper, isLower, isAlphaNum, ord, chr, digitToInt ) import Util ( thenCmp ) import Unique ( Unique ) import FiniteMap ( FiniteMap, emptyFM, lookupFM, addToFM, elemFM ) +import FastString import Outputable -import GlaExts +import Binary + +import GLAEXTS \end{code} We hold both module names and identifier names in a 'Z-encoded' form @@ -60,8 +68,8 @@ code the encoding operation is not performed on each occurrence. These type synonyms help documentation. \begin{code} -type UserFS = FAST_STRING -- As the user typed it -type EncodedFS = FAST_STRING -- Encoded form +type UserFS = FastString -- As the user typed it +type EncodedFS = FastString -- Encoded form type UserString = String -- As the user typed it type EncodedString = String -- Encoded form @@ -71,9 +79,9 @@ pprEncodedFS :: EncodedFS -> SDoc pprEncodedFS fs = getPprStyle $ \ sty -> if userStyle sty - -- ptext (decodeFS fs) would needlessly pack the string again - then text (decode (_UNPK_ fs)) - else ptext fs + -- ftext (decodeFS fs) would needlessly pack the string again + then text (decode (unpackFS fs)) + else ftext fs \end{code} %************************************************************************ @@ -83,12 +91,31 @@ pprEncodedFS fs %************************************************************************ \begin{code} -data NameSpace = VarName -- Variables - | DataName -- Data constructors +data NameSpace = VarName -- Variables, including "source" data constructors + | DataName -- "Real" data constructors | TvName -- Type variables | TcClsName -- Type constructors and classes; Haskell has them -- in the same name space for now. deriving( Eq, Ord ) + {-! derive: Binary !-} + +-- Note [Data Constructors] +-- see also: Note [Data Constructor Naming] in DataCon.lhs +-- +-- "Source" data constructors are the data constructors mentioned +-- in Haskell source code +-- +-- "Real" data constructors are the data constructors of the +-- representation type, which may not be the same as the source +-- type + +-- Example: +-- data T = T !(Int,Int) +-- +-- The source datacon has type (Int,Int) -> T +-- The real datacon has type Int -> Int -> T +-- GHC chooses a representation based on the strictness etc. + -- Though type constructors and classes are in the same name space now, -- the NameSpace type is abstract, so we can easily separate them later @@ -96,10 +123,12 @@ tcName = TcClsName -- Type constructors clsName = TcClsName -- Classes tcClsName = TcClsName -- Not sure which! -dataName = DataName -tvName = TvName -varName = VarName +dataName = DataName +srcDataName = DataName -- Haskell-source data constructors should be + -- in the Data name space +tvName = TvName +varName = VarName nameSpaceString :: NameSpace -> String nameSpaceString DataName = "Data constructor" @@ -119,6 +148,7 @@ nameSpaceString TcClsName = "Type constructor or class" data OccName = OccName NameSpace EncodedFS + {-! derive : Binary !-} \end{code} @@ -159,7 +189,7 @@ already encoded \begin{code} mkSysOcc :: NameSpace -> EncodedString -> OccName mkSysOcc occ_sp str = ASSERT2( alreadyEncoded str, text str ) - OccName occ_sp (_PK_ str) + OccName occ_sp (mkFastString str) mkSysOccFS :: NameSpace -> EncodedFS -> OccName mkSysOccFS occ_sp fs = ASSERT2( alreadyEncodedFS fs, ppr fs ) @@ -170,7 +200,7 @@ mkFCallOcc :: EncodedString -> OccName -- because it will be something like "{__ccall f dyn Int# -> Int#}" -- This encodes a lot into something that then parses like an Id. -- But then alreadyEncoded complains about the braces! -mkFCallOcc str = OccName varName (_PK_ str) +mkFCallOcc str = OccName varName (mkFastString str) -- Kind constructors get a special function. Uniquely, they are not encoded, -- so that they have names like '*'. This means that *even in interface files* @@ -188,6 +218,9 @@ mkOccFS occ_sp fs = mkSysOccFS occ_sp (encodeFS fs) mkVarOcc :: UserFS -> OccName mkVarOcc fs = mkSysOccFS varName (encodeFS fs) + +mkVarOccEncoded :: EncodedFS -> OccName +mkVarOccEncoded fs = mkSysOccFS varName fs \end{code} @@ -203,7 +236,7 @@ occNameFS :: OccName -> EncodedFS occNameFS (OccName _ s) = s occNameString :: OccName -> EncodedString -occNameString (OccName _ s) = _UNPK_ s +occNameString (OccName _ s) = unpackFS s occNameUserString :: OccName -> UserString occNameUserString occ = decode (occNameString occ) @@ -211,12 +244,22 @@ occNameUserString occ = decode (occNameString occ) occNameSpace :: OccName -> NameSpace occNameSpace (OccName sp _) = sp -setOccNameSpace :: OccName -> NameSpace -> OccName -setOccNameSpace (OccName _ occ) sp = OccName sp occ +setOccNameSpace :: NameSpace -> OccName -> OccName +setOccNameSpace sp (OccName _ occ) = OccName sp occ -- occNameFlavour is used only to generate good error messages occNameFlavour :: OccName -> String -occNameFlavour (OccName sp _) = nameSpaceString sp +occNameFlavour (OccName DataName _) = "Data constructor" +occNameFlavour (OccName TvName _) = "Type variable" +occNameFlavour (OccName TcClsName _) = "Type constructor or class" +occNameFlavour (OccName VarName s) = "Variable" + +-- briefOccNameFlavour is used in debug-printing of names +briefOccNameFlavour :: OccName -> String +briefOccNameFlavour (OccName DataName _) = "d" +briefOccNameFlavour (OccName VarName _) = "v" +briefOccNameFlavour (OccName TvName _) = "tv" +briefOccNameFlavour (OccName TcClsName _) = "tc" \end{code} \begin{code} @@ -235,9 +278,11 @@ isValOcc other = False -- Data constructor operator (starts with ':', or '[]') -- Pretty inefficient! isDataSymOcc (OccName DataName s) = isLexConSym (decodeFS s) +isDataSymOcc (OccName VarName s) = isLexConSym (decodeFS s) isDataSymOcc other = False isDataOcc (OccName DataName _) = True +isDataOcc (OccName VarName s) = isLexCon (decodeFS s) isDataOcc other = False -- Any operator (data constructor or variable) @@ -247,6 +292,17 @@ isSymOcc (OccName VarName s) = isLexSym (decodeFS s) \end{code} +\begin{code} +reportIfUnused :: OccName -> Bool + -- Haskell 98 encourages compilers to suppress warnings about + -- unused names in a pattern if they start with "_". +reportIfUnused occ = case occNameUserString occ of + ('_' : _) -> False + zz_other -> True +\end{code} + + + %************************************************************************ %* * \subsection{Making system names} @@ -293,11 +349,13 @@ mkDictOcc, mkIPOcc, mkWorkerOcc, mkDefaultMethodOcc, :: OccName -> OccName -- These derived variables have a prefix that no Haskell value could have +mkDataConWrapperOcc = mk_simple_deriv varName "$W" mkWorkerOcc = mk_simple_deriv varName "$w" mkDefaultMethodOcc = mk_simple_deriv varName "$dm" mkDerivedTyConOcc = mk_simple_deriv tcName ":" -- The : prefix makes sure it classifies mkClassTyConOcc = mk_simple_deriv tcName ":T" -- as a tycon/datacon -mkClassDataConOcc = mk_simple_deriv dataName ":D" -- +mkClassDataConOcc = mk_simple_deriv dataName ":D" -- We go straight to the "real" data con + -- for datacons from classes mkDictOcc = mk_simple_deriv varName "$d" mkIPOcc = mk_simple_deriv varName "$i" mkSpecOcc = mk_simple_deriv varName "$s" @@ -305,6 +363,12 @@ mkForeignExportOcc = mk_simple_deriv varName "$f" mkGenOcc1 = mk_simple_deriv varName "$gfrom" -- Generics mkGenOcc2 = mk_simple_deriv varName "$gto" -- Generics mk_simple_deriv sp px occ = mk_deriv sp px (occNameString occ) + + +-- Data constructor workers are made by setting the name space +-- of the data constructor OccName (which should be a DataName) +-- to DataName +mkDataConWorkerOcc datacon_occ = setOccNameSpace varName datacon_occ \end{code} \begin{code} @@ -375,7 +439,7 @@ because that isn't a single lexeme. So we encode it to 'lle' and *then* tack on the '1', if necessary. \begin{code} -type TidyOccEnv = FiniteMap FAST_STRING Int -- The in-scope OccNames +type TidyOccEnv = FiniteMap FastString Int -- The in-scope OccNames emptyTidyOccEnv = emptyFM initTidyOccEnv :: [OccName] -> TidyOccEnv -- Initialise with names to avoid! @@ -388,7 +452,7 @@ tidyOccName in_scope occ@(OccName occ_sp fs) = (addToFM in_scope fs 1, occ) -- First occurrence | otherwise -- Already occurs - = go in_scope (_UNPK_ fs) + = go in_scope (unpackFS fs) where go in_scope str = case lookupFM in_scope pk_str of @@ -399,7 +463,7 @@ tidyOccName in_scope occ@(OccName occ_sp fs) Nothing -> (addToFM in_scope pk_str 1, mkSysOccFS occ_sp pk_str) -- str is now unique where - pk_str = _PK_ str + pk_str = mkFastString str \end{code} @@ -460,8 +524,8 @@ alreadyEncoded s = all ok s -- reject them here ok ch = isAlphaNum ch -alreadyEncodedFS :: FAST_STRING -> Bool -alreadyEncodedFS fs = alreadyEncoded (_UNPK_ fs) +alreadyEncodedFS :: FastString -> Bool +alreadyEncodedFS fs = alreadyEncoded (unpackFS fs) encode :: UserString -> EncodedString encode cs = case maybe_tuple cs of @@ -487,9 +551,9 @@ count_commas n cs = (n,cs) encodeFS :: UserFS -> EncodedFS encodeFS fast_str | all unencodedChar str = fast_str - | otherwise = _PK_ (encode str) + | otherwise = mkFastString (encode str) where - str = _UNPK_ fast_str + str = unpackFS fast_str unencodedChar :: Char -> Bool -- True for chars that don't need encoding unencodedChar 'Z' = False @@ -535,8 +599,8 @@ encode_ch c = 'z' : shows (ord c) "U" Decode is used for user printing. \begin{code} -decodeFS :: FAST_STRING -> FAST_STRING -decodeFS fs = _PK_ (decode (_UNPK_ fs)) +decodeFS :: FastString -> FastString +decodeFS fs = mkFastString (decode (unpackFS fs)) decode :: EncodedString -> UserString decode [] = [] @@ -601,8 +665,8 @@ These functions test strings to see if they fit the lexical categories defined in the Haskell report. \begin{code} -isLexCon, isLexVar, isLexId, isLexSym :: FAST_STRING -> Bool -isLexConId, isLexConSym, isLexVarId, isLexVarSym :: FAST_STRING -> Bool +isLexCon, isLexVar, isLexId, isLexSym :: FastString -> Bool +isLexConId, isLexConSym, isLexVarId, isLexVarSym :: FastString -> Bool isLexCon cs = isLexConId cs || isLexConSym cs isLexVar cs = isLexVarId cs || isLexVarSym cs @@ -613,22 +677,22 @@ isLexSym cs = isLexConSym cs || isLexVarSym cs ------------- isLexConId cs -- Prefix type or data constructors - | _NULL_ cs = False -- e.g. "Foo", "[]", "(,)" - | cs == SLIT("[]") = True - | otherwise = startsConId (_HEAD_ cs) + | nullFastString cs = False -- e.g. "Foo", "[]", "(,)" + | cs == FSLIT("[]") = True + | otherwise = startsConId (headFS cs) isLexVarId cs -- Ordinary prefix identifiers - | _NULL_ cs = False -- e.g. "x", "_x" - | otherwise = startsVarId (_HEAD_ cs) + | nullFastString cs = False -- e.g. "x", "_x" + | otherwise = startsVarId (headFS cs) isLexConSym cs -- Infix type or data constructors - | _NULL_ cs = False -- e.g. ":-:", ":", "->" - | cs == SLIT("->") = True - | otherwise = startsConSym (_HEAD_ cs) + | nullFastString cs = False -- e.g. ":-:", ":", "->" + | cs == FSLIT("->") = True + | otherwise = startsConSym (headFS cs) isLexVarSym cs -- Infix identifiers - | _NULL_ cs = False -- e.g. "+" - | otherwise = startsVarSym (_HEAD_ cs) + | nullFastString cs = False -- e.g. "+" + | otherwise = startsVarSym (headFS cs) ------------- startsVarSym, startsVarId, startsConSym, startsConId :: Char -> Bool @@ -645,3 +709,34 @@ isUpperISO (C# c#) = c# `geChar#` '\xc0'# && c# `leChar#` '\xde'# && c# `neCh isLowerISO (C# c#) = c# `geChar#` '\xdf'# && c# `leChar#` '\xff'# && c# `neChar#` '\xf7'# --0xdf <= oc && oc <= 0xff && oc /= 0xf7 where oc = ord c \end{code} +\begin{code} +{-* Generated by DrIFT-v1.0 : Look, but Don't Touch. *-} +instance Binary NameSpace where + put_ bh VarName = do + putByte bh 0 + put_ bh DataName = do + putByte bh 1 + put_ bh TvName = do + putByte bh 2 + put_ bh TcClsName = do + putByte bh 3 + get bh = do + h <- getByte bh + case h of + 0 -> do return VarName + 1 -> do return DataName + 2 -> do return TvName + _ -> do return TcClsName + +instance Binary OccName where + put_ bh (OccName aa ab) = do + put_ bh aa + put_ bh ab + get bh = do + aa <- get bh + ab <- get bh + return (OccName aa ab) + +-- Imported from other files :- + +\end{code}