c59ec00c1d253ab1011cd6beb994f31a248f8110
[ghc-base.git] / Data / Char.hs
1 {-# OPTIONS_GHC -fno-implicit-prelude #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module      :  Data.Char
5 -- Copyright   :  (c) The University of Glasgow 2001
6 -- License     :  BSD-style (see the file libraries/base/LICENSE)
7 -- 
8 -- Maintainer  :  libraries@haskell.org
9 -- Stability   :  stable
10 -- Portability :  portable
11 --
12 -- The Char type and associated operations.
13 --
14 -----------------------------------------------------------------------------
15
16 module Data.Char 
17     (
18       Char
19
20     , String
21
22     -- * Character classification
23     -- | Unicode characters are divided into letters, numbers, marks,
24     -- punctuation, symbols, separators (including spaces) and others
25     -- (including control characters).
26     , isAscii, isLatin1, isControl, isSpace
27     , isLower, isUpper,  isAlpha,   isAlphaNum, isPrint
28     , isDigit, isOctDigit, isHexDigit
29     , isAsciiUpper, isAsciiLower
30     , isLetter, isMark, isNumber, isPunctuation, isSymbol, isSeparator
31
32     , GeneralCategory(..), generalCategory
33
34     -- * Case conversion
35     , toUpper, toLower, toTitle  -- :: Char -> Char
36
37     -- * Single digit characters
38     , digitToInt        -- :: Char -> Int
39     , intToDigit        -- :: Int  -> Char
40
41     -- * Numeric representations
42     , ord               -- :: Char -> Int
43     , chr               -- :: Int  -> Char
44
45     -- * String representations
46     , showLitChar       -- :: Char -> ShowS
47     , lexLitChar        -- :: ReadS String
48     , readLitChar       -- :: ReadS Char 
49
50      -- Implementation checked wrt. Haskell 98 lib report, 1/99.
51     ) where
52
53 #ifdef __GLASGOW_HASKELL__
54 import GHC.Base
55 import GHC.Real (fromIntegral)
56 import GHC.Show
57 import GHC.Read (Read, readLitChar, lexLitChar)
58 import GHC.Unicode
59 import GHC.Num
60 import GHC.Enum
61 #endif
62
63 #ifdef __HUGS__
64 import Hugs.Char
65 #endif
66
67 #ifdef __NHC__
68 import Prelude
69 import Prelude(Char,String)
70 import Char
71 import NHC.FFI (CInt)
72 foreign import ccall unsafe "WCsubst.h u_gencat" wgencat :: CInt -> Int
73 #endif
74
75 -- | Convert a single digit 'Char' to the corresponding 'Int'.  
76 -- This function fails unless its argument satisfies 'isHexDigit',
77 -- but recognises both upper and lower-case hexadecimal digits
78 -- (i.e. @\'0\'@..@\'9\'@, @\'a\'@..@\'f\'@, @\'A\'@..@\'F\'@).
79 digitToInt :: Char -> Int
80 digitToInt c
81  | isDigit c            =  ord c - ord '0'
82  | c >= 'a' && c <= 'f' =  ord c - ord 'a' + 10
83  | c >= 'A' && c <= 'F' =  ord c - ord 'A' + 10
84  | otherwise            =  error ("Char.digitToInt: not a digit " ++ show c) -- sigh
85
86 #ifndef __GLASGOW_HASKELL__
87 isAsciiUpper, isAsciiLower :: Char -> Bool
88 isAsciiLower c          =  c >= 'a' && c <= 'z'
89 isAsciiUpper c          =  c >= 'A' && c <= 'Z'
90 #endif
91
92 -- | Unicode General Categories (column 2 of the UnicodeData table)
93 -- in the order they are listed in the Unicode standard.
94
95 data GeneralCategory
96         = UppercaseLetter       -- ^ Lu: Letter, Uppercase
97         | LowercaseLetter       -- ^ Ll: Letter, Lowercase
98         | TitlecaseLetter       -- ^ Lt: Letter, Titlecase
99         | ModifierLetter        -- ^ Lm: Letter, Modifier
100         | OtherLetter           -- ^ Lo: Letter, Other
101         | NonSpacingMark        -- ^ Mn: Mark, Non-Spacing
102         | SpacingCombiningMark  -- ^ Mc: Mark, Spacing Combining
103         | EnclosingMark         -- ^ Me: Mark, Enclosing
104         | DecimalNumber         -- ^ Nd: Number, Decimal
105         | LetterNumber          -- ^ Nl: Number, Letter
106         | OtherNumber           -- ^ No: Number, Other
107         | ConnectorPunctuation  -- ^ Pc: Punctuation, Connector
108         | DashPunctuation       -- ^ Pd: Punctuation, Dash
109         | OpenPunctuation       -- ^ Ps: Punctuation, Open
110         | ClosePunctuation      -- ^ Pe: Punctuation, Close
111         | InitialQuote          -- ^ Pi: Punctuation, Initial quote
112         | FinalQuote            -- ^ Pf: Punctuation, Final quote
113         | OtherPunctuation      -- ^ Po: Punctuation, Other
114         | MathSymbol            -- ^ Sm: Symbol, Math
115         | CurrencySymbol        -- ^ Sc: Symbol, Currency
116         | ModifierSymbol        -- ^ Sk: Symbol, Modifier
117         | OtherSymbol           -- ^ So: Symbol, Other
118         | Space                 -- ^ Zs: Separator, Space
119         | LineSeparator         -- ^ Zl: Separator, Line
120         | ParagraphSeparator    -- ^ Zp: Separator, Paragraph
121         | Control               -- ^ Cc: Other, Control
122         | Format                -- ^ Cf: Other, Format
123         | Surrogate             -- ^ Cs: Other, Surrogate
124         | PrivateUse            -- ^ Co: Other, Private Use
125         | NotAssigned           -- ^ Cn: Other, Not Assigned
126         deriving (Eq, Ord, Enum, Read, Show, Bounded)
127
128 -- | Retrieves the general Unicode category of the character.
129 generalCategory :: Char -> GeneralCategory
130 #if defined(__GLASGOW_HASKELL__) || defined(__NHC__)
131 generalCategory c = toEnum (wgencat (fromIntegral (ord c)))
132 #endif
133 #ifdef __HUGS__
134 generalCategory c = toEnum (primUniGenCat c)
135 #endif
136
137 -- derived character classifiers
138
139 isLetter :: Char -> Bool
140 isLetter c = case generalCategory c of
141         UppercaseLetter         -> True
142         LowercaseLetter         -> True
143         TitlecaseLetter         -> True
144         ModifierLetter          -> True
145         OtherLetter             -> True
146         _                       -> False
147
148 isMark :: Char -> Bool
149 isMark c = case generalCategory c of
150         NonSpacingMark          -> True
151         SpacingCombiningMark    -> True
152         EnclosingMark           -> True
153         _                       -> False
154
155 isNumber :: Char -> Bool
156 isNumber c = case generalCategory c of
157         DecimalNumber           -> True
158         LetterNumber            -> True
159         OtherNumber             -> True
160         _                       -> False
161
162 isPunctuation :: Char -> Bool
163 isPunctuation c = case generalCategory c of
164         ConnectorPunctuation    -> True
165         DashPunctuation         -> True
166         OpenPunctuation         -> True
167         ClosePunctuation        -> True
168         InitialQuote            -> True
169         FinalQuote              -> True
170         OtherPunctuation        -> True
171         _                       -> False
172
173 isSymbol :: Char -> Bool
174 isSymbol c = case generalCategory c of
175         MathSymbol              -> True
176         CurrencySymbol          -> True
177         ModifierSymbol          -> True
178         OtherSymbol             -> True
179         _                       -> False
180
181 isSeparator :: Char -> Bool
182 isSeparator c = case generalCategory c of
183         Space                   -> True
184         LineSeparator           -> True
185         ParagraphSeparator      -> True
186         _                       -> False
187
188 #ifdef __NHC__
189 -- dummy implementation
190 toTitle :: Char -> Char
191 toTitle = toUpper
192 #endif