on master help sign in
Add support for toLower.

--HG-- extra : convert_revision : e0a040d08252f34d669f728d2484d640b60ae438

commit599c8d1b039c205dbc8268ddbd714532d229d252 authorBryan O'Sullivan <bos@serpentine.com> dateSun 7 Jun 2009, 01:09 (17 years ago) parent7c53770
5 files changed+63−18
Data/Text.hs+9 Data/Text/Fusion/CaseMapping.hs+7 Data/Text/Fusion/Common.hs+22−9 Data/Text/Lazy.hs+9 scripts/SpecialCasing.hs+16−9
Data/Text.hs+9
@@ -57,6 +57,7 @@ module Data.Text
5757
5858 -- * Case conversion
5959 , toUpper
60+ , toLower
6061
6162 -- * Folds
6263 , foldl
@@ -392,6 +393,14 @@ toUpper :: Text -> Text
392393toUpper t = unstream (S.toUpper (stream t))
393394{-# INLINE toUpper #-}
394395
396+-- | /O(n)/ Convert a string to lower case, using simple case
397+-- conversion. The result string may be longer than the input string.
398+-- For instance, the German eszett (U+00DF) maps to the two-letter
399+-- sequence SS.
400+toLower :: Text -> Text
401+toLower t = unstream (S.toLower (stream t))
402+{-# INLINE toLower #-}
403+
395404-- | /O(n)/ The 'transpose' function transposes the rows and columns
396405-- of its 'Text' argument. Note that this function uses 'pack',
397406-- 'unpack', and the list version of transpose, and is thus not very
Data/Text/Fusion/CaseMapping.hs+7
@@ -1,4 +1,6 @@
11{-# LANGUAGE Rank2Types #-}
2+-- AUTOMATICALLY GENERATED - DO NOT EDIT
3+-- Generated by scripts/SpecialCasing.hs
24module Data.Text.Fusion.CaseMapping where
35import Data.Char
46import Data.Text.Fusion.Internal
@@ -210,3 +212,8 @@ upperMapping '\x1fc7' s = Yield '\x0397' (s :!: '\x0342' :!: '\x0399')
210212-- GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
211213upperMapping '\x1ff7' s = Yield '\x03a9' (s :!: '\x0342' :!: '\x0399')
212214upperMapping c s = Yield (toUpper c) (s :!: '\0' :!: '\0')
215+lowerMapping :: forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char
216+{-# INLINE lowerMapping #-}
217+-- LATIN CAPITAL LETTER I WITH DOT ABOVE
218+lowerMapping '\x0130' s = Yield '\x0069' (s :!: '\x0307' :!: '\x0000')
219+lowerMapping c s = Yield (toLower c) (s :!: '\0' :!: '\0')
Data/Text/Fusion/Common.hs+22−9
@@ -1,4 +1,4 @@
1−{-# LANGUAGE BangPatterns #-}
1+{-# LANGUAGE BangPatterns, Rank2Types #-}
22-- |
33-- Module : Data.Text.Fusion.Common
44-- Copyright : (c) Bryan O'Sullivan 2009
@@ -37,6 +37,7 @@ module Data.Text.Fusion.Common
3737
3838 -- ** Case conversion
3939 , toUpper
40+ , toLower
4041
4142 -- * Folds
4243 , foldl
@@ -99,7 +100,7 @@ import Prelude (Bool(..), Char, Either(..), Eq(..), Int, Integral, Maybe(..),
99100import qualified Data.List as L
100101import qualified Prelude as P
101102import Data.Text.Fusion.Internal
102−import Data.Text.Fusion.CaseMapping (upperMapping)
103+import Data.Text.Fusion.CaseMapping (lowerMapping, upperMapping)
103104
104105singleton :: Char -> Stream Char
105106singleton c = Stream next False 1 -- HINT maybe too low
@@ -299,22 +300,34 @@ intersperse c (Stream next0 s0 len) = Stream next (s0 :!: N :!: S1) len -- HINT
299300-- ----------------------------------------------------------------------------
300301-- ** Case conversions (folds)
301302
302−-- | /O(n)/ Convert a string to upper case, using simple case
303−-- conversion. The result string may be longer than the input string.
304−-- For instance, the German eszett (U+00DF) maps to the two-letter
305−-- sequence SS.
306−toUpper :: Stream Char -> Stream Char
307−toUpper (Stream next0 s0 len) = Stream next (s0 :!: '\0' :!: '\0') len
303+caseConvert :: (forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char)
304+ -> Stream Char -> Stream Char
305+caseConvert remap (Stream next0 s0 len) = Stream next (s0 :!: '\0' :!: '\0') len
308306 where
309307 {-# INLINE next #-}
310308 next (s :!: '\0' :!: _) =
311309 case next0 s of
312310 Done -> Done
313311 Skip s' -> Skip (s' :!: '\0' :!: '\0')
314− Yield c s' -> upperMapping c s'
312+ Yield c s' -> remap c s'
315313 next (s :!: a :!: b) = Yield a (s :!: b :!: '\0')
314+
315+-- | /O(n)/ Convert a string to upper case, using simple case
316+-- conversion. The result string may be longer than the input string.
317+-- For instance, the German eszett (U+00DF) maps to the two-letter
318+-- sequence SS.
319+toUpper :: Stream Char -> Stream Char
320+toUpper = caseConvert upperMapping
316321{-# INLINE [0] toUpper #-}
317322
323+-- | /O(n)/ Convert a string to lower case, using simple case
324+-- conversion. The result string may be longer than the input string.
325+-- For instance, the German eszett (U+00DF) maps to the two-letter
326+-- sequence SS.
327+toLower :: Stream Char -> Stream Char
328+toLower = caseConvert lowerMapping
329+{-# INLINE [0] toLower #-}
330+
318331-- ----------------------------------------------------------------------------
319332-- * Reducing Streams (folds)
320333
Data/Text/Lazy.hs+9
@@ -60,6 +60,7 @@ module Data.Text.Lazy
6060
6161 -- ** Case conversion
6262 , toUpper
63+ , toLower
6364
6465 -- * Folds
6566 , foldl
@@ -378,6 +379,14 @@ toUpper :: Text -> Text
378379toUpper t = unstream (S.toUpper (stream t))
379380{-# INLINE toUpper #-}
380381
382+-- | /O(n)/ Convert a string to lower case, using simple case
383+-- conversion. The result string may be longer than the input string.
384+-- For instance, the German eszett (U+00DF) maps to the two-letter
385+-- sequence SS.
386+toLower :: Text -> Text
387+toLower t = unstream (S.toLower (stream t))
388+{-# INLINE toLower #-}
389+
381390-- | /O(n)/ 'foldl', applied to a binary operator, a starting value
382391-- (typically the left-identity of the operator), and a 'Text',
383392-- reduces the 'Text' using the binary operator, from left to right.
scripts/SpecialCasing.hs+16−9
@@ -4,7 +4,7 @@ import Data.Char
44import Numeric
55import System.Environment
66import System.IO
7−import Text.ParserCombinators.Parsec hiding (many, optional, upper, (<|>))
7+import Text.ParserCombinators.Parsec hiding (many, optional, upper, lower, (<|>))
88import Text.ParserCombinators.Parsec.Combinator
99
1010instance Applicative (GenParser s a) where
@@ -41,18 +41,24 @@ entries = many comment *> many (entry <* many comment)
4141parseFile :: FilePath -> IO (Either ParseError [Case])
4242parseFile name = parse entries name <$> readFile name
4343
44−upperFunc ms = typ ++ (map nice . filter p $ ms) ++ [last]
44+mapFunc which access twiddle ms = typ ++ (map nice . filter p $ ms) ++ [last]
4545 where
46− typ = ["upperMapping :: forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char"
47− ,"{-# INLINE upperMapping #-}"]
48− last = "upperMapping c s = Yield (toUpper c) (s :!: '\\0' :!: '\\0')"
49− nice c = "-- " ++ name c ++ "\nupperMapping " ++ showC (code c) ++ " s = Yield " ++ x ++ " (s :!: " ++ y ++ " :!: " ++ z ++ ")"
50− where [x,y,z] = (map showC . take 3) (upper c ++ repeat '\0')
51− p c = [code c] /= upper c && null (conditions c)
46+ typ = [which ++ "Mapping :: forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char"
47+ ,"{-# INLINE " ++ which ++ "Mapping #-}"]
48+ last = which ++ "Mapping c s = Yield (to" ++ ucFirst which ++ " c) (s :!: '\\0' :!: '\\0')"
49+ nice c = "-- " ++ name c ++ "\n" ++
50+ which ++ "Mapping " ++ showC (code c) ++ " s = Yield " ++ x ++ " (s :!: " ++ y ++ " :!: " ++ z ++ ")"
51+ where [x,y,z] = (map showC . take 3) (access c ++ repeat '\0')
52+ p c = [k] /= a && a /= [twiddle k] && null (conditions c)
53+ where a = access c
54+ k = code c
5255 showC c = "'\\x" ++ d ++ "'"
5356 where h = showHex (ord c) ""
5457 d = replicate (4 - length h) '0' ++ h
5558
59+ucFirst (c:cs) = toUpper c : cs
60+ucFirst [] = []
61+
5662main = do
5763 args <- getArgs
5864 let (iname, oname) = case args of
@@ -71,5 +77,6 @@ main = do
7177 ,"import Data.Char"
7278 ,"import Data.Text.Fusion.Internal"
7379 ,""]
74− mapM_ (hPutStrLn h) (upperFunc ms)
80+ mapM_ (hPutStrLn h) (mapFunc "upper" upper toUpper ms)
81+ mapM_ (hPutStrLn h) (mapFunc "lower" lower toLower ms)
7582 hClose h