never executed always true always false
1 -- Character classification
2
3 module GHC.Parser.CharClass
4 ( is_ident -- Char# -> Bool
5 , is_symbol -- Char# -> Bool
6 , is_any -- Char# -> Bool
7 , is_space -- Char# -> Bool
8 , is_lower -- Char# -> Bool
9 , is_upper -- Char# -> Bool
10 , is_digit -- Char# -> Bool
11 , is_alphanum -- Char# -> Bool
12
13 , is_decdigit, is_hexdigit, is_octdigit, is_bindigit
14 , hexDigit, octDecDigit
15 ) where
16
17 import GHC.Prelude
18
19 import Data.Char ( ord, chr )
20 import Data.Word
21 import GHC.Utils.Panic
22
23 -- Bit masks
24
25 cIdent, cSymbol, cAny, cSpace, cLower, cUpper, cDigit :: Word8
26 cIdent = 1
27 cSymbol = 2
28 cAny = 4
29 cSpace = 8
30 cLower = 16
31 cUpper = 32
32 cDigit = 64
33
34 -- | The predicates below look costly, but aren't, GHC+GCC do a great job
35 -- at the big case below.
36
37 {-# INLINABLE is_ctype #-}
38 is_ctype :: Word8 -> Char -> Bool
39 is_ctype mask c = (charType c .&. mask) /= 0
40
41 is_ident, is_symbol, is_any, is_space, is_lower, is_upper, is_digit,
42 is_alphanum :: Char -> Bool
43 is_ident = is_ctype cIdent
44 is_symbol = is_ctype cSymbol
45 is_any = is_ctype cAny
46 is_space = is_ctype cSpace
47 is_lower = is_ctype cLower
48 is_upper = is_ctype cUpper
49 is_digit = is_ctype cDigit
50 is_alphanum = is_ctype (cLower+cUpper+cDigit)
51
52 -- Utils
53
54 hexDigit :: Char -> Int
55 hexDigit c | is_decdigit c = ord c - ord '0'
56 | otherwise = ord (to_lower c) - ord 'a' + 10
57
58 octDecDigit :: Char -> Int
59 octDecDigit c = ord c - ord '0'
60
61 is_decdigit :: Char -> Bool
62 is_decdigit c
63 = c >= '0' && c <= '9'
64
65 is_hexdigit :: Char -> Bool
66 is_hexdigit c
67 = is_decdigit c
68 || (c >= 'a' && c <= 'f')
69 || (c >= 'A' && c <= 'F')
70
71 is_octdigit :: Char -> Bool
72 is_octdigit c = c >= '0' && c <= '7'
73
74 is_bindigit :: Char -> Bool
75 is_bindigit c = c == '0' || c == '1'
76
77 to_lower :: Char -> Char
78 to_lower c
79 | c >= 'A' && c <= 'Z' = chr (ord c - (ord 'A' - ord 'a'))
80 | otherwise = c
81
82 charType :: Char -> Word8
83 charType c = case c of
84 '\0' -> 0 -- \000
85 '\1' -> 0 -- \001
86 '\2' -> 0 -- \002
87 '\3' -> 0 -- \003
88 '\4' -> 0 -- \004
89 '\5' -> 0 -- \005
90 '\6' -> 0 -- \006
91 '\7' -> 0 -- \007
92 '\8' -> 0 -- \010
93 '\9' -> cSpace -- \t (not allowed in strings, so !cAny)
94 '\10' -> cSpace -- \n (ditto)
95 '\11' -> cSpace -- \v (ditto)
96 '\12' -> cSpace -- \f (ditto)
97 '\13' -> cSpace -- ^M (ditto)
98 '\14' -> 0 -- \016
99 '\15' -> 0 -- \017
100 '\16' -> 0 -- \020
101 '\17' -> 0 -- \021
102 '\18' -> 0 -- \022
103 '\19' -> 0 -- \023
104 '\20' -> 0 -- \024
105 '\21' -> 0 -- \025
106 '\22' -> 0 -- \026
107 '\23' -> 0 -- \027
108 '\24' -> 0 -- \030
109 '\25' -> 0 -- \031
110 '\26' -> 0 -- \032
111 '\27' -> 0 -- \033
112 '\28' -> 0 -- \034
113 '\29' -> 0 -- \035
114 '\30' -> 0 -- \036
115 '\31' -> 0 -- \037
116 '\32' -> cAny .|. cSpace --
117 '\33' -> cAny .|. cSymbol -- !
118 '\34' -> cAny -- "
119 '\35' -> cAny .|. cSymbol -- #
120 '\36' -> cAny .|. cSymbol -- $
121 '\37' -> cAny .|. cSymbol -- %
122 '\38' -> cAny .|. cSymbol -- &
123 '\39' -> cAny .|. cIdent -- '
124 '\40' -> cAny -- (
125 '\41' -> cAny -- )
126 '\42' -> cAny .|. cSymbol -- *
127 '\43' -> cAny .|. cSymbol -- +
128 '\44' -> cAny -- ,
129 '\45' -> cAny .|. cSymbol -- -
130 '\46' -> cAny .|. cSymbol -- .
131 '\47' -> cAny .|. cSymbol -- /
132 '\48' -> cAny .|. cIdent .|. cDigit -- 0
133 '\49' -> cAny .|. cIdent .|. cDigit -- 1
134 '\50' -> cAny .|. cIdent .|. cDigit -- 2
135 '\51' -> cAny .|. cIdent .|. cDigit -- 3
136 '\52' -> cAny .|. cIdent .|. cDigit -- 4
137 '\53' -> cAny .|. cIdent .|. cDigit -- 5
138 '\54' -> cAny .|. cIdent .|. cDigit -- 6
139 '\55' -> cAny .|. cIdent .|. cDigit -- 7
140 '\56' -> cAny .|. cIdent .|. cDigit -- 8
141 '\57' -> cAny .|. cIdent .|. cDigit -- 9
142 '\58' -> cAny .|. cSymbol -- :
143 '\59' -> cAny -- ;
144 '\60' -> cAny .|. cSymbol -- <
145 '\61' -> cAny .|. cSymbol -- =
146 '\62' -> cAny .|. cSymbol -- >
147 '\63' -> cAny .|. cSymbol -- ?
148 '\64' -> cAny .|. cSymbol -- @
149 '\65' -> cAny .|. cIdent .|. cUpper -- A
150 '\66' -> cAny .|. cIdent .|. cUpper -- B
151 '\67' -> cAny .|. cIdent .|. cUpper -- C
152 '\68' -> cAny .|. cIdent .|. cUpper -- D
153 '\69' -> cAny .|. cIdent .|. cUpper -- E
154 '\70' -> cAny .|. cIdent .|. cUpper -- F
155 '\71' -> cAny .|. cIdent .|. cUpper -- G
156 '\72' -> cAny .|. cIdent .|. cUpper -- H
157 '\73' -> cAny .|. cIdent .|. cUpper -- I
158 '\74' -> cAny .|. cIdent .|. cUpper -- J
159 '\75' -> cAny .|. cIdent .|. cUpper -- K
160 '\76' -> cAny .|. cIdent .|. cUpper -- L
161 '\77' -> cAny .|. cIdent .|. cUpper -- M
162 '\78' -> cAny .|. cIdent .|. cUpper -- N
163 '\79' -> cAny .|. cIdent .|. cUpper -- O
164 '\80' -> cAny .|. cIdent .|. cUpper -- P
165 '\81' -> cAny .|. cIdent .|. cUpper -- Q
166 '\82' -> cAny .|. cIdent .|. cUpper -- R
167 '\83' -> cAny .|. cIdent .|. cUpper -- S
168 '\84' -> cAny .|. cIdent .|. cUpper -- T
169 '\85' -> cAny .|. cIdent .|. cUpper -- U
170 '\86' -> cAny .|. cIdent .|. cUpper -- V
171 '\87' -> cAny .|. cIdent .|. cUpper -- W
172 '\88' -> cAny .|. cIdent .|. cUpper -- X
173 '\89' -> cAny .|. cIdent .|. cUpper -- Y
174 '\90' -> cAny .|. cIdent .|. cUpper -- Z
175 '\91' -> cAny -- [
176 '\92' -> cAny .|. cSymbol -- backslash
177 '\93' -> cAny -- ]
178 '\94' -> cAny .|. cSymbol -- ^
179 '\95' -> cAny .|. cIdent .|. cLower -- _
180 '\96' -> cAny -- `
181 '\97' -> cAny .|. cIdent .|. cLower -- a
182 '\98' -> cAny .|. cIdent .|. cLower -- b
183 '\99' -> cAny .|. cIdent .|. cLower -- c
184 '\100' -> cAny .|. cIdent .|. cLower -- d
185 '\101' -> cAny .|. cIdent .|. cLower -- e
186 '\102' -> cAny .|. cIdent .|. cLower -- f
187 '\103' -> cAny .|. cIdent .|. cLower -- g
188 '\104' -> cAny .|. cIdent .|. cLower -- h
189 '\105' -> cAny .|. cIdent .|. cLower -- i
190 '\106' -> cAny .|. cIdent .|. cLower -- j
191 '\107' -> cAny .|. cIdent .|. cLower -- k
192 '\108' -> cAny .|. cIdent .|. cLower -- l
193 '\109' -> cAny .|. cIdent .|. cLower -- m
194 '\110' -> cAny .|. cIdent .|. cLower -- n
195 '\111' -> cAny .|. cIdent .|. cLower -- o
196 '\112' -> cAny .|. cIdent .|. cLower -- p
197 '\113' -> cAny .|. cIdent .|. cLower -- q
198 '\114' -> cAny .|. cIdent .|. cLower -- r
199 '\115' -> cAny .|. cIdent .|. cLower -- s
200 '\116' -> cAny .|. cIdent .|. cLower -- t
201 '\117' -> cAny .|. cIdent .|. cLower -- u
202 '\118' -> cAny .|. cIdent .|. cLower -- v
203 '\119' -> cAny .|. cIdent .|. cLower -- w
204 '\120' -> cAny .|. cIdent .|. cLower -- x
205 '\121' -> cAny .|. cIdent .|. cLower -- y
206 '\122' -> cAny .|. cIdent .|. cLower -- z
207 '\123' -> cAny -- {
208 '\124' -> cAny .|. cSymbol -- |
209 '\125' -> cAny -- }
210 '\126' -> cAny .|. cSymbol -- ~
211 '\127' -> 0 -- \177
212 _ -> panic ("charType: " ++ show c)