{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Data.SBV.Char (
elem, notElem
, ord, chr
, toLower, toUpper
, digitToInt, intToDigit
, isControl, isSpace, isLower, isUpper, isAlpha, isAlphaNum, isPrint, isDigit, isOctDigit, isHexDigit, isLetter, isMark, isNumber, isPunctuation, isSymbol, isSeparator
, isAscii, isLatin1, isAsciiLetter, isAsciiUpper, isAsciiLower
) where
import Prelude hiding (elem, notElem)
import qualified Prelude as P
import Data.SBV.Core.Data
import Data.SBV.Core.Model
import qualified Data.Char as C
import Data.SBV.String (isInfixOf, singleton)
elem :: SChar -> SString -> SBool
SChar
c elem :: SChar -> SString -> SBool
`elem` SString
s
| Just String
cs <- SString -> Maybe String
forall a. SymVal a => SBV a -> Maybe a
unliteral SString
s, Just Char
cc <- SChar -> Maybe Char
forall a. SymVal a => SBV a -> Maybe a
unliteral SChar
c
= Bool -> SBool
forall a. SymVal a => a -> SBV a
literal (Char
cc Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`P.elem` String
cs)
| Just String
cs <- SString -> Maybe String
forall a. SymVal a => SBV a -> Maybe a
unliteral SString
s
= (SChar -> SBool) -> [SChar] -> SBool
forall a. (a -> SBool) -> [a] -> SBool
sAny (SChar
c SChar -> SChar -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.==) ([SChar] -> SBool) -> [SChar] -> SBool
forall a b. (a -> b) -> a -> b
$ (Char -> SChar) -> String -> [SChar]
forall a b. (a -> b) -> [a] -> [b]
map Char -> SChar
forall a. SymVal a => a -> SBV a
literal String
cs
| Bool
True
= SChar -> SString
singleton SChar
c SString -> SString -> SBool
`isInfixOf` SString
s
notElem :: SChar -> SString -> SBool
SChar
c notElem :: SChar -> SString -> SBool
`notElem` SString
s = SBool -> SBool
sNot (SChar
c SChar -> SString -> SBool
`elem` SString
s)
ord :: SChar -> SInteger
ord :: SChar -> SInteger
ord SChar
c
| Just Char
cc <- SChar -> Maybe Char
forall a. SymVal a => SBV a -> Maybe a
unliteral SChar
c
= Integer -> SInteger
forall a. SymVal a => a -> SBV a
literal (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
C.ord Char
cc))
| Bool
True
= SVal -> SInteger
forall a. SVal -> SBV a
SBV (SVal -> SInteger) -> SVal -> SInteger
forall a b. (a -> b) -> a -> b
$ Kind -> Either CV (Cached SV) -> SVal
SVal Kind
kTo (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
forall a b. (a -> b) -> a -> b
$ Cached SV -> Either CV (Cached SV)
forall a b. b -> Either a b
Right (Cached SV -> Either CV (Cached SV))
-> Cached SV -> Either CV (Cached SV)
forall a b. (a -> b) -> a -> b
$ (State -> IO SV) -> Cached SV
forall a. (State -> IO a) -> Cached a
cache State -> IO SV
r
where kFrom :: Kind
kFrom = Bool -> Int -> Kind
KBounded Bool
False Int
8
kTo :: Kind
kTo = Kind
KUnbounded
r :: State -> IO SV
r State
st = do SV
csv <- State -> SChar -> IO SV
forall a. State -> SBV a -> IO SV
sbvToSV State
st SChar
c
State -> Kind -> SBVExpr -> IO SV
newExpr State
st Kind
kTo (Op -> [SV] -> SBVExpr
SBVApp (Kind -> Kind -> Op
KindCast Kind
kFrom Kind
kTo) [SV
csv])
chr :: SInteger -> SChar
chr :: SInteger -> SChar
chr SInteger
w
| Just Integer
cw <- SInteger -> Maybe Integer
forall a. SymVal a => SBV a -> Maybe a
unliteral SInteger
w
= Char -> SChar
forall a. SymVal a => a -> SBV a
literal (Int -> Char
C.chr (Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
cw))
| Bool
True
= SVal -> SChar
forall a. SVal -> SBV a
SBV (SVal -> SChar) -> SVal -> SChar
forall a b. (a -> b) -> a -> b
$ Kind -> Either CV (Cached SV) -> SVal
SVal Kind
KChar (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
forall a b. (a -> b) -> a -> b
$ Cached SV -> Either CV (Cached SV)
forall a b. b -> Either a b
Right (Cached SV -> Either CV (Cached SV))
-> Cached SV -> Either CV (Cached SV)
forall a b. (a -> b) -> a -> b
$ (State -> IO SV) -> Cached SV
forall a. (State -> IO a) -> Cached a
cache State -> IO SV
r
where w8 :: SWord8
w8 :: SWord8
w8 = SInteger -> SWord8
forall a b.
(Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
SymVal b) =>
SBV a -> SBV b
sFromIntegral SInteger
w
r :: State -> IO SV
r State
st = do SV Kind
_ NodeId
n <- State -> SWord8 -> IO SV
forall a. State -> SBV a -> IO SV
sbvToSV State
st SWord8
w8
SV -> IO SV
forall (m :: * -> *) a. Monad m => a -> m a
return (SV -> IO SV) -> SV -> IO SV
forall a b. (a -> b) -> a -> b
$ Kind -> NodeId -> SV
SV Kind
KChar NodeId
n
toLower :: SChar -> SChar
toLower :: SChar -> SChar
toLower SChar
c = SBool -> SChar -> SChar -> SChar
forall a. Mergeable a => SBool -> a -> a -> a
ite (SChar -> SBool
isUpper SChar
c) (SInteger -> SChar
chr (SChar -> SInteger
ord SChar
c SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SInteger
32)) SChar
c
toUpper :: SChar -> SChar
toUpper :: SChar -> SChar
toUpper SChar
c = SBool -> SChar -> SChar -> SChar
forall a. Mergeable a => SBool -> a -> a -> a
ite (SChar -> SBool
isLower SChar
c SBool -> SBool -> SBool
.&& SChar
c SChar -> SString -> SBool
`notElem` SString
"\181\223\255") (SInteger -> SChar
chr (SChar -> SInteger
ord SChar
c SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
- SInteger
32)) SChar
c
digitToInt :: SChar -> SInteger
digitToInt :: SChar -> SInteger
digitToInt SChar
c = SBool -> SInteger -> SInteger -> SInteger
forall a. Mergeable a => SBool -> a -> a -> a
ite (SChar
uc SChar -> SString -> SBool
`elem` SString
"0123456789") (SInteger -> SInteger
forall a b.
(Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
SymVal b) =>
SBV a -> SBV b
sFromIntegral (SInteger
o SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
- SChar -> SInteger
ord (Char -> SChar
forall a. SymVal a => a -> SBV a
literal Char
'0')))
(SInteger -> SInteger) -> SInteger -> SInteger
forall a b. (a -> b) -> a -> b
$ SBool -> SInteger -> SInteger -> SInteger
forall a. Mergeable a => SBool -> a -> a -> a
ite (SChar
uc SChar -> SString -> SBool
`elem` SString
"ABCDEF") (SInteger -> SInteger
forall a b.
(Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
SymVal b) =>
SBV a -> SBV b
sFromIntegral (SInteger
o SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
- SChar -> SInteger
ord (Char -> SChar
forall a. SymVal a => a -> SBV a
literal Char
'A') SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SInteger
10))
(SInteger -> SInteger) -> SInteger -> SInteger
forall a b. (a -> b) -> a -> b
$ -SInteger
1
where uc :: SChar
uc = SChar -> SChar
toUpper SChar
c
o :: SInteger
o = SChar -> SInteger
ord SChar
uc
intToDigit :: SInteger -> SChar
intToDigit :: SInteger -> SChar
intToDigit SInteger
i = SBool -> SChar -> SChar -> SChar
forall a. Mergeable a => SBool -> a -> a -> a
ite (SInteger
i SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.>= SInteger
0 SBool -> SBool -> SBool
.&& SInteger
i SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
9) (SInteger -> SChar
chr (SInteger -> SInteger
forall a b.
(Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
SymVal b) =>
SBV a -> SBV b
sFromIntegral SInteger
i SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SChar -> SInteger
ord (Char -> SChar
forall a. SymVal a => a -> SBV a
literal Char
'0')))
(SChar -> SChar) -> SChar -> SChar
forall a b. (a -> b) -> a -> b
$ SBool -> SChar -> SChar -> SChar
forall a. Mergeable a => SBool -> a -> a -> a
ite (SInteger
i SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.>= SInteger
10 SBool -> SBool -> SBool
.&& SInteger
i SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
15) (SInteger -> SChar
chr (SInteger -> SInteger
forall a b.
(Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
SymVal b) =>
SBV a -> SBV b
sFromIntegral SInteger
i SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SChar -> SInteger
ord (Char -> SChar
forall a. SymVal a => a -> SBV a
literal Char
'a') SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
- SInteger
10))
(SChar -> SChar) -> SChar -> SChar
forall a b. (a -> b) -> a -> b
$ Char -> SChar
forall a. SymVal a => a -> SBV a
literal Char
' '
isControl :: SChar -> SBool
isControl :: SChar -> SBool
isControl = (SChar -> SString -> SBool
`elem` SString
controls)
where controls :: SString
controls = SString
"\NUL\SOH\STX\ETX\EOT\ENQ\ACK\a\b\t\n\v\f\r\SO\SI\DLE\DC1\DC2\DC3\DC4\NAK\SYN\ETB\CAN\EM\SUB\ESC\FS\GS\RS\US\DEL\128\129\130\131\132\133\134\135\136\137\138\139\140\141\142\143\144\145\146\147\148\149\150\151\152\153\154\155\156\157\158\159"
isSpace :: SChar -> SBool
isSpace :: SChar -> SBool
isSpace = (SChar -> SString -> SBool
`elem` SString
spaces)
where spaces :: SString
spaces = SString
"\t\n\v\f\r \160"
isLower :: SChar -> SBool
isLower :: SChar -> SBool
isLower = (SChar -> SString -> SBool
`elem` SString
lower)
where lower :: SString
lower = SString
"abcdefghijklmnopqrstuvwxyz\181\223\224\225\226\227\228\229\230\231\232\233\234\235\236\237\238\239\240\241\242\243\244\245\246\248\249\250\251\252\253\254\255"
isUpper :: SChar -> SBool
isUpper :: SChar -> SBool
isUpper = (SChar -> SString -> SBool
`elem` SString
upper)
where upper :: SString
upper = SString
"ABCDEFGHIJKLMNOPQRSTUVWXYZ\192\193\194\195\196\197\198\199\200\201\202\203\204\205\206\207\208\209\210\211\212\213\214\216\217\218\219\220\221\222"
isAlpha :: SChar -> SBool
isAlpha :: SChar -> SBool
isAlpha = (SChar -> SString -> SBool
`elem` SString
alpha)
where alpha :: SString
alpha = SString
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\170\181\186\192\193\194\195\196\197\198\199\200\201\202\203\204\205\206\207\208\209\210\211\212\213\214\216\217\218\219\220\221\222\223\224\225\226\227\228\229\230\231\232\233\234\235\236\237\238\239\240\241\242\243\244\245\246\248\249\250\251\252\253\254\255"
isAlphaNum :: SChar -> SBool
isAlphaNum :: SChar -> SBool
isAlphaNum SChar
c = SChar -> SBool
isAlpha SChar
c SBool -> SBool -> SBool
.|| SChar -> SBool
isNumber SChar
c
isPrint :: SChar -> SBool
isPrint :: SChar -> SBool
isPrint SChar
c = SChar
c SChar -> SChar -> SBool
forall a. EqSymbolic a => a -> a -> SBool
./= Char -> SChar
forall a. SymVal a => a -> SBV a
literal Char
'\173' SBool -> SBool -> SBool
.&& SBool -> SBool
sNot (SChar -> SBool
isControl SChar
c)
isDigit :: SChar -> SBool
isDigit :: SChar -> SBool
isDigit = (SChar -> SString -> SBool
`elem` SString
"0123456789")
isOctDigit :: SChar -> SBool
isOctDigit :: SChar -> SBool
isOctDigit = (SChar -> SString -> SBool
`elem` SString
"01234567")
isHexDigit :: SChar -> SBool
isHexDigit :: SChar -> SBool
isHexDigit = (SChar -> SString -> SBool
`elem` SString
"0123456789abcdefABCDEF")
isLetter :: SChar -> SBool
isLetter :: SChar -> SBool
isLetter = SChar -> SBool
isAlpha
isMark :: SChar -> SBool
isMark :: SChar -> SBool
isMark = SBool -> SChar -> SBool
forall a b. a -> b -> a
const SBool
sFalse
isNumber :: SChar -> SBool
isNumber :: SChar -> SBool
isNumber = (SChar -> SString -> SBool
`elem` SString
"0123456789\178\179\185\188\189\190")
isPunctuation :: SChar -> SBool
isPunctuation :: SChar -> SBool
isPunctuation = (SChar -> SString -> SBool
`elem` SString
"!\"#%&'()*,-./:;?@[\\]_{}\161\167\171\182\183\187\191")
isSymbol :: SChar -> SBool
isSymbol :: SChar -> SBool
isSymbol = (SChar -> SString -> SBool
`elem` SString
"$+<=>^`|~\162\163\164\165\166\168\169\172\174\175\176\177\180\184\215\247")
isSeparator :: SChar -> SBool
isSeparator :: SChar -> SBool
isSeparator = (SChar -> SString -> SBool
`elem` SString
" \160")
isAscii :: SChar -> SBool
isAscii :: SChar -> SBool
isAscii SChar
c = SChar -> SInteger
ord SChar
c SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.< SInteger
128
isLatin1 :: SChar -> SBool
isLatin1 :: SChar -> SBool
isLatin1 = SBool -> SChar -> SBool
forall a b. a -> b -> a
const SBool
sTrue
isAsciiLetter :: SChar -> SBool
isAsciiLetter :: SChar -> SBool
isAsciiLetter SChar
c = SChar -> SBool
isAsciiUpper SChar
c SBool -> SBool -> SBool
.|| SChar -> SBool
isAsciiLower SChar
c
isAsciiUpper :: SChar -> SBool
isAsciiUpper :: SChar -> SBool
isAsciiUpper = (SChar -> SString -> SBool
`elem` String -> SString
forall a. SymVal a => a -> SBV a
literal [Char
'A' .. Char
'Z'])
isAsciiLower :: SChar -> SBool
isAsciiLower :: SChar -> SBool
isAsciiLower = (SChar -> SString -> SBool
`elem` String -> SString
forall a. SymVal a => a -> SBV a
literal [Char
'a' .. Char
'z'])