{-# LANGUAGE DeriveLift #-}
module Burrito.Type.LitChar
( LitChar(..)
, isLiteral
, makeUnencoded
)
where
import qualified Data.Word as Word
import qualified Language.Haskell.TH.Syntax as TH
data LitChar
= Encoded Word.Word8
| Unencoded Char
deriving (Eq, TH.Lift, Show)
makeUnencoded :: Char -> Maybe LitChar
makeUnencoded char = if isLiteral char then Just $ Unencoded char else Nothing
isLiteral :: Char -> Bool
isLiteral x = case x of
' ' -> False
'"' -> False
'\'' -> False
'%' -> False
'<' -> False
'>' -> False
'\\' -> False
'^' -> False
'`' -> False
'{' -> False
'|' -> False
'}' -> False
_ -> between '\x20' '\x7e' x || isUcschar x || isIprivate x
isUcschar :: Char -> Bool
isUcschar x =
between '\xa0' '\xd7ff' x
|| between '\xf900' '\xfdcf' x
|| between '\xfdf0' '\xffef' x
|| between '\x10000' '\x1fffd' x
|| between '\x20000' '\x2fffd' x
|| between '\x30000' '\x3fffd' x
|| between '\x40000' '\x4fffd' x
|| between '\x50000' '\x5fffd' x
|| between '\x60000' '\x6fffd' x
|| between '\x70000' '\x7fffd' x
|| between '\x80000' '\x8fffd' x
|| between '\x90000' '\x9fffd' x
|| between '\xa0000' '\xafffd' x
|| between '\xb0000' '\xbfffd' x
|| between '\xc0000' '\xcfffd' x
|| between '\xd0000' '\xdfffd' x
|| between '\xe1000' '\xefffd' x
isIprivate :: Char -> Bool
isIprivate x =
between '\xe000' '\xf8ff' x
|| between '\xf0000' '\xffffd' x
|| between '\x100000' '\x10fffd' x
between
:: Ord a
=> a
-> a
-> a
-> Bool
between lo hi x = lo <= x && x <= hi