[project @ 2001-10-19 14:22:11 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / OccName.lhs
index 95acfef..c743343 100644 (file)
@@ -14,13 +14,13 @@ module OccName (
        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, 
+       mkGenOcc1, mkGenOcc2, mkLocalOcc,
        
-       isTvOcc, isDataOcc, isDataSymOcc, isSymOcc, isValOcc,
+       isTvOcc, isTcOcc, isDataOcc, isDataSymOcc, isSymOcc, isValOcc,
 
        occNameFS, occNameString, occNameUserString, occNameSpace, occNameFlavour, 
        setOccNameSpace,
@@ -42,6 +42,7 @@ module OccName (
 
 import Char    ( isDigit, isUpper, isLower, ISALPHANUM, ord, chr, digitToInt )
 import Util    ( thenCmp )
+import Unique  ( Unique )
 import FiniteMap ( FiniteMap, emptyFM, lookupFM, addToFM, elemFM )
 import Outputable
 import GlaExts
@@ -164,12 +165,12 @@ mkSysOccFS :: NameSpace -> EncodedFS -> OccName
 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*
@@ -219,11 +220,14 @@ occNameFlavour (OccName sp _) = nameSpaceString sp
 \end{code}
 
 \begin{code}
-isTvOcc, isDataSymOcc, isSymOcc :: OccName -> Bool
+isTvOcc, isDataSymOcc, isSymOcc, isTcOcc :: OccName -> Bool
 
 isTvOcc (OccName TvName _) = True
 isTvOcc other              = False
 
+isTcOcc (OccName TcClsName _) = True
+isTcOcc other                 = False
+
 isValOcc (OccName VarName  _) = True
 isValOcc (OccName DataName _) = True
 isValOcc other               = False
@@ -258,25 +262,26 @@ Here's our convention for splitting up the interface file name space:
        $dm...          default methods
        $p...           superclass selectors
        $w...           workers
-       $T...           compiler-generated tycons for dictionaries
-       $D...           ...ditto data cons
+       :T...           compiler-generated tycons for dictionaries
+       :D...           ...ditto data cons
        $sf..           specialised version of f
 
        in encoded form these appear as Zdfxxx etc
 
        :...            keywords (export:, letrec: etc.)
+--- I THINK THIS IS WRONG!
 
 This knowledge is encoded in the following functions.
 
 
-@mk_deriv@ generates an @OccName@ from the one-char prefix and a string.
+@mk_deriv@ generates an @OccName@ from the prefix and a string.
 NB: The string must already be encoded!
 
 \begin{code}
 mk_deriv :: NameSpace 
         -> String              -- Distinguishes one sort of derived name from another
         -> EncodedString       -- Must be already encoded!!  We don't want to encode it a 
-                               -- second time because encoding isn't itempotent
+                               -- second time because encoding isn't idempotent
         -> OccName
 
 mk_deriv occ_sp sys_prefix str = mkSysOcc occ_sp (encode sys_prefix ++ str)
@@ -288,15 +293,15 @@ mkDictOcc, mkIPOcc, mkWorkerOcc, mkDefaultMethodOcc,
    :: OccName -> OccName
 
 -- These derived variables have a prefix that no Haskell value could have
-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"     --
-mkDictOcc         = mk_simple_deriv varName  "$d"
-mkIPOcc                   = mk_simple_deriv varName  "$i"
-mkSpecOcc         = mk_simple_deriv varName  "$s"
-mkForeignExportOcc = mk_simple_deriv varName  "$f"
+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"    --
+mkDictOcc          = mk_simple_deriv varName  "$d"
+mkIPOcc                    = mk_simple_deriv varName  "$i"
+mkSpecOcc          = mk_simple_deriv varName  "$s"
+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)
@@ -305,9 +310,17 @@ mk_simple_deriv sp px occ = mk_deriv sp px (occNameString occ)
 \begin{code}
 mkSuperDictSelOcc :: Int       -- Index of superclass, eg 3
                  -> OccName    -- Class, eg "Ord"
-                 -> OccName    -- eg "p3Ord"
+                 -> OccName    -- eg "$p3Ord"
 mkSuperDictSelOcc index cls_occ
   = mk_deriv varName "$p" (show index ++ occNameString cls_occ)
+
+mkLocalOcc :: Unique           -- Unique
+          -> OccName           -- Local name (e.g. "sat")
+          -> OccName           -- Nice unique version ("$L23sat")
+mkLocalOcc uniq occ
+   = mk_deriv varName ("$L" ++ show uniq) (occNameString occ)
+       -- The Unique might print with characters 
+       -- that need encoding (e.g. 'z'!)
 \end{code}
 
 
@@ -426,13 +439,12 @@ The basic encoding scheme is this.
        foo##           foozhzh
        foo##1          foozhzh1
        fooZ            fooZZ   
-       :+              Zczp
-       ()              Z0T
-       (,,,,)          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.)
+       :+              ZCzp
+       ()              Z0T     0-tuple
+       (,,,,)          Z5T     5-tuple  
+       (# #)           Z1H     unboxed 1-tuple (note the space)
+       (#,,,,#)        Z5H     unboxed 5-tuple
+               (NB: There is no Z1T nor Z0H.)
 
 \begin{code}
 -- alreadyEncoded is used in ASSERTs to check for encoded
@@ -459,11 +471,13 @@ encode cs = case maybe_tuple cs of
                go []     = []
                go (c:cs) = encode_ch c ++ go cs
 
+maybe_tuple "(# #)" = Just("Z1H")
 maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of
-                                (n, '#' : ')' : cs) -> Just ('Z' : shows n "H")
+                                (n, '#' : ')' : cs) -> Just ('Z' : shows (n+1) "H")
                                 other               -> Nothing
+maybe_tuple "()" = Just("Z0T")
 maybe_tuple ('(' : cs)       = case count_commas (0::Int) cs of
-                                (n, ')' : cs) -> Just ('Z' : shows n "T")
+                                (n, ')' : cs) -> Just ('Z' : shows (n+1) "T")
                                 other         -> Nothing
 maybe_tuple other           = Nothing
 
@@ -480,7 +494,9 @@ 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
@@ -563,8 +579,10 @@ decode_escape (c : rest)
   | isDigit c = go (digitToInt c) rest
   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 0 ('T' : rest)          = "()" ++ (decode rest)
+    go n ('T' : rest)          = '(' : replicate (n-1) ',' ++ ')' : decode rest
+    go 1 ('H' : rest)          = "(# #)" ++ (decode rest)
+    go n ('H' : rest)          = '(' : '#' : replicate (n-1) ',' ++ '#' : ')' : decode rest
     go n ('U' : rest)           = chr n : decode rest
     go n other = pprPanic "decode_escape" (ppr n <+> text (c:rest))
 
@@ -574,7 +592,7 @@ decode_escape (c : rest) = pprTrace "decode_escape" (char c) (decode rest)
 
 %************************************************************************
 %*                                                                     *
-n\subsection{Lexical categories}
+\subsection{Lexical categories}
 %*                                                                     *
 %************************************************************************