\begin{code}
module OccName (
-- The NameSpace type; abstact
- NameSpace, tcName, clsName, tcClsName, dataName, varName, ipName,
+ NameSpace, tcName, clsName, tcClsName, dataName, varName,
tvName, nameSpaceString,
-- The OccName type
OccName, -- Abstract, instance of Outputable
pprOccName,
- mkOccFS, mkSysOcc, mkSysOccFS, mkCCallOcc, mkVarOcc, mkKindOccFS,
+ mkOccFS, mkSysOcc, mkSysOccFS, mkFCallOcc, mkVarOcc, mkKindOccFS,
mkSuperDictSelOcc, mkDFunOcc, mkForeignExportOcc,
mkDictOcc, mkIPOcc, mkWorkerOcc, mkMethodOcc, mkDefaultMethodOcc,
mkDerivedTyConOcc, mkClassTyConOcc, mkClassDataConOcc, mkSpecOcc,
mkGenOcc1, mkGenOcc2,
- isSysOcc, isTvOcc, isDataOcc, isDataSymOcc, isSymOcc, isIPOcc, isValOcc,
+ isTvOcc, isDataOcc, isDataSymOcc, isSymOcc, isValOcc,
occNameFS, occNameString, occNameUserString, occNameSpace, occNameFlavour,
setOccNameSpace,
\begin{code}
data NameSpace = VarName -- Variables
- | IPName -- Implicit Parameters
| DataName -- Data constructors
| TvName -- Type variables
| TcClsName -- Type constructors and classes; Haskell has them
dataName = DataName
tvName = TvName
varName = VarName
-ipName = IPName
nameSpaceString :: NameSpace -> String
nameSpaceString DataName = "Data constructor"
nameSpaceString VarName = "Variable"
-nameSpaceString IPName = "Implicit Param"
nameSpaceString TvName = "Type variable"
nameSpaceString TcClsName = "Type constructor or class"
\end{code}
mkSysOccFS occ_sp fs = ASSERT2( alreadyEncodedFS fs, ppr fs )
OccName occ_sp fs
-mkCCallOcc :: EncodedString -> OccName
+mkFCallOcc :: EncodedString -> OccName
-- This version of mkSysOcc doesn't check that the string is already encoded,
-- 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!
-mkCCallOcc str = OccName varName (_PK_ str)
+mkFCallOcc str = OccName varName (_PK_ 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*
-- Pretty inefficient!
isSymOcc (OccName DataName s) = isLexConSym (decodeFS s)
isSymOcc (OccName VarName s) = isLexSym (decodeFS s)
-
-isIPOcc (OccName IPName _) = True
-isIPOcc _ = False
\end{code}
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)
-
-
-isSysOcc :: OccName -> Bool -- True for all these '$' things
-isSysOcc occ = case occNameUserString occ of
- ('$' : _ ) -> True
- other -> False -- We don't care about the ':' ones
- -- isSysOcc is only called for Ids anyway
\end{code}
\begin{code}
fooZ fooZZ
:+ Zczp
() Z0T
- (,,,,) Z4T
-
+ (,,,,) Z4T 5-tuple
+ (#,,,,#) Z4H unboxed 5-tuple
+ (NB: the number is one different to the number of
+ elements. No real reason except that () is a zero-tuple,
+ while (,) is a 2-tuple.)
\begin{code}
-- alreadyEncoded is used in ASSERTs to check for encoded
encode :: UserString -> EncodedString
encode cs = case maybe_tuple cs of
- Just n -> 'Z' : show n ++ "T" -- Tuples go to Z2T etc
+ Just n -> n -- Tuples go to Z2T etc
Nothing -> go cs
where
go [] = []
go (c:cs) = encode_ch c ++ go cs
--- ToDo: Unboxed tuples too, perhaps?
-maybe_tuple ('(' : cs) = check_tuple (0::Int) cs
-maybe_tuple other = Nothing
+maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of
+ (n, '#' : ')' : cs) -> Just ('Z' : shows n "H")
+ other -> Nothing
+maybe_tuple ('(' : cs) = case count_commas (0::Int) cs of
+ (n, ')' : cs) -> Just ('Z' : shows n "T")
+ other -> Nothing
+maybe_tuple other = Nothing
-check_tuple :: Int -> String -> Maybe Int
-check_tuple n (',' : cs) = check_tuple (n+1) cs
-check_tuple n ")" = Just n
-check_tuple n other = Nothing
+count_commas :: Int -> String -> (Int, String)
+count_commas n (',' : cs) = count_commas (n+1) cs
+count_commas n cs = (n,cs)
encodeFS :: UserFS -> EncodedFS
encodeFS fast_str | all unencodedChar str = fast_str
unencodedChar :: Char -> Bool -- True for chars that don't need encoding
unencodedChar 'Z' = False
unencodedChar 'z' = False
-unencodedChar c = ISALPHANUM c
+unencodedChar c = c >= 'a' && c <= 'z'
+ || c >= 'A' && c <= 'Z'
+ || c >= '0' && c <= '9'
encode_ch :: Char -> EncodedString
encode_ch c | unencodedChar c = [c] -- Common case first
where
go n (c : rest) | isDigit c = go (10*n + digitToInt c) rest
go n ('T' : rest) = '(' : replicate n ',' ++ ')' : decode rest
+ go n ('H' : rest) = '(' : '#' : replicate n ',' ++ '#' : ')' : decode rest
go n ('U' : rest) = chr n : decode rest
go n other = pprPanic "decode_escape" (ppr n <+> text (c:rest))