module Iri.CodePointPredicates.Core where

import qualified Data.Vector.Unboxed as A
import Iri.Prelude hiding (Predicate, inRange, (&&&), (|||))

type Predicate =
  Int -> Bool

{-# NOINLINE cached #-}
cached :: Predicate -> Predicate
cached :: Predicate -> Predicate
cached Predicate
predicate =
  case Int -> Predicate -> Vector Bool
forall a. Unbox a => Int -> (Int -> a) -> Vector a
A.generate Int
256 Predicate
predicate of
    Vector Bool
vector -> Vector Bool -> Predicate
forall a. Unbox a => Vector a -> Int -> a
A.unsafeIndex Vector Bool
vector

oneOfChars :: [Char] -> Predicate
oneOfChars :: [Char] -> Predicate
oneOfChars [Char]
string Int
i =
  Int -> [Int] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem Int
i ((Char -> Int) -> [Char] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> Int
ord [Char]
string)

infixr 2 |||

(|||) :: Predicate -> Predicate -> Predicate
||| :: Predicate -> Predicate -> Predicate
(|||) Predicate
left Predicate
right Int
i =
  Predicate
left Int
i Bool -> Bool -> Bool
|| Predicate
right Int
i

infixr 3 &&&

(&&&) :: Predicate -> Predicate -> Predicate
&&& :: Predicate -> Predicate -> Predicate
(&&&) Predicate
left Predicate
right Int
i =
  Predicate
left Int
i Bool -> Bool -> Bool
&& Predicate
right Int
i

inRange :: Int -> Int -> Predicate
inRange :: Int -> Int -> Predicate
inRange Int
min Int
max Int
i =
  Int
i Int -> Predicate
forall a. Ord a => a -> a -> Bool
>= Int
min Bool -> Bool -> Bool
&& Int
i Int -> Predicate
forall a. Ord a => a -> a -> Bool
<= Int
max

inCharRange :: Char -> Char -> Predicate
inCharRange :: Char -> Char -> Predicate
inCharRange Char
min Char
max =
  Int -> Int -> Predicate
inRange (Char -> Int
ord Char
min) (Char -> Int
ord Char
max)

-- | 7-bit
septimal :: Predicate
septimal :: Predicate
septimal Int
i =
  Int
i Int -> Predicate
forall a. Ord a => a -> a -> Bool
< Int
0x80

nonSeptimal :: Predicate
nonSeptimal :: Predicate
nonSeptimal Int
i =
  Int
i Int -> Predicate
forall a. Ord a => a -> a -> Bool
>= Int
0x80

control :: Predicate
control :: Predicate
control Int
i =
  Int
i
    Int -> Predicate
forall a. Ord a => a -> a -> Bool
<= Int
0x1F
    Bool -> Bool -> Bool
|| Int
i
    Int -> Predicate
forall a. Eq a => a -> a -> Bool
== Int
0x7F

asciiAlphanumeric :: Predicate
asciiAlphanumeric :: Predicate
asciiAlphanumeric =
  Char -> Char -> Predicate
inCharRange Char
'a' Char
'z'
    Predicate -> Predicate -> Predicate
||| Char -> Char -> Predicate
inCharRange Char
'A' Char
'Z'
    Predicate -> Predicate -> Predicate
||| Char -> Char -> Predicate
inCharRange Char
'0' Char
'9'