ucd-0.0.0.0: Setup.hs
{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Applicative
import Control.Monad (join)
import Data.Char
import Data.Foldable
import Data.List (dropWhileEnd, intercalate)
import Data.Map (Map)
import qualified Data.Map as Map
import Text.Regex.Applicative (RE)
import qualified Text.Regex.Applicative as RE
import qualified Text.Regex.Applicative.Common as RE
import Util hiding (intercalate)
import Distribution.Simple
import Distribution.Simple.PreProcess
main = defaultMainWithHooks simpleUserHooks
{ hookedPreProcessors = ("ucd-derived-core-properties", \ _ _ _ -> PreProcessor
{ platformIndependent = True
, runPreProcessor = mkSimplePreProcessor $ \ inFile outFile _verbosity ->
readFile inFile >>=
writeFile outFile .
("module Data.Char.Properties.DerivedCore where\n" ++) .
maybe (error "bad format") generate . parseProps
}) : hookedPreProcessors simpleUserHooks
}
data Range a = Range a a
deriving (Foldable, Functor, Traversable)
rangeRE :: RE Char (Range Int)
rangeRE = join Range <$> n <|> Range <$> n <* ".." <*> n where n = RE.hexadecimal
lineRE :: RE Char ([Char], Range Char)
lineRE = flip ((,) . filter (/= '_')) . fmap toEnum <$> rangeRE <* many (RE.psym isSpace) <* "; " <*> many (RE.psym (liftA2 (||) isAlphaNum (== '_')))
generate :: Map [Char] [Range Char] -> [Char]
generate = unlines . ((:) <$> generateTypes . Map.keys <*> generateCode)
generateTypes :: [[Char]] -> [Char]
generateTypes names = intercalate ", " (("is" ++) <$> names) ++ " :: Char -> Bool"
generateCode :: Map [Char] [Range Char] -> [[Char]]
generateCode = toList . Map.mapWithKey (\ name ranges -> asum ["is", name, " x = ", intercalate " || " [asum ["x >= ", show a, " && x <= ", show b] | Range a b <- ranges]])
parseProps :: [Char] -> Maybe (Map [Char] [Range Char])
parseProps = lines & fmap (takeWhile (/= '#') & dropWhileEnd isSpace) & filter (not . null) & traverse (RE.match lineRE) & fmap ((fmap . fmap) pure & Map.fromListWith (flip (++)))