tlex-core-0.1.0.0: src/Language/Lexer/Tlex/Machine/State.hs
module Language.Lexer.Tlex.Machine.State (
StateNum,
initialStateNum,
StateSet,
emptySet,
singletonSet,
listToSet,
setToList,
nullSet,
insertSet,
intersectSet,
diffSet,
unionSet,
lengthSet,
memberSet,
StateMap,
emptyMap,
insertOrUpdateMap,
insertMap,
lookupMap,
assocsMap,
StateArray,
totalStateMapToArray,
mapArrayWithIx,
indexArray,
arrayAssocs,
StateGraph,
stateArrayToGraph,
liftGraphOp,
indexGraph,
) where
import Language.Lexer.Tlex.Prelude
import qualified Data.Array as Array
import qualified Data.Graph as Graph
import qualified Data.Hashable as Hashable
import qualified Data.IntMap.Strict as IntMap
import qualified Data.IntSet as IntSet
newtype StateNum = StateNum Int
deriving (Eq, Ord, Show, Ix)
deriving (Hashable.Hashable, Enum) via Int
initialStateNum :: StateNum
initialStateNum = StateNum 0
newtype StateSet = StateSet IntSet.IntSet
deriving (Eq, Show)
instance Hashable.Hashable StateSet where
hashWithSalt s (StateSet x) = Hashable.hashWithSalt s do IntSet.toAscList x
emptySet :: StateSet
emptySet = StateSet IntSet.empty
singletonSet :: StateNum -> StateSet
singletonSet (StateNum s) = StateSet do IntSet.singleton s
insertSet :: StateNum -> StateSet -> StateSet
insertSet (StateNum s) (StateSet ss) = StateSet do IntSet.insert s ss
listToSet :: [StateNum] -> StateSet
listToSet ss = StateSet do IntSet.fromList do coerce ss
setToList :: StateSet -> [StateNum]
setToList (StateSet ss) = coerce do IntSet.toList ss
nullSet :: StateSet -> Bool
nullSet (StateSet ss) = IntSet.null ss
intersectSet :: StateSet -> StateSet -> StateSet
intersectSet (StateSet ss1) (StateSet ss2) = StateSet do IntSet.intersection ss1 ss2
diffSet :: StateSet -> StateSet -> StateSet
diffSet (StateSet ss1) (StateSet ss2) = StateSet do IntSet.difference ss1 ss2
unionSet :: StateSet -> StateSet -> StateSet
unionSet (StateSet ss1) (StateSet ss2) = StateSet do IntSet.union ss1 ss2
lengthSet :: StateSet -> Int
lengthSet (StateSet ss) = IntSet.size ss
memberSet :: StateNum -> StateSet -> Bool
memberSet (StateNum s) (StateSet ss) = IntSet.member s ss
newtype StateMap a = StateMap (IntMap.IntMap a)
deriving (Eq, Show, Functor)
emptyMap :: StateMap a
emptyMap = StateMap IntMap.empty
insertMap :: StateNum -> a -> StateMap a -> StateMap a
insertMap (StateNum k) x (StateMap m) = StateMap do IntMap.insert k x m
insertOrUpdateMap :: StateNum -> a -> (a -> a) -> StateMap a -> StateMap a
insertOrUpdateMap (StateNum k) ~dx ~uf (StateMap m) = StateMap case IntMap.lookup k m of
Nothing -> IntMap.insert k dx m
Just x -> IntMap.insert k (uf x) m
lookupMap :: StateNum -> StateMap a -> Maybe a
lookupMap (StateNum sn) (StateMap m) = IntMap.lookup sn m
assocsMap :: StateMap a -> [(StateNum, a)]
assocsMap (StateMap m) = coerce do IntMap.assocs m
newtype StateArray a = StateArray (Array.Array Int a)
deriving (Eq, Show, Functor, Foldable)
totalStateMapToArray :: StateNum -> StateMap a -> StateArray a
totalStateMapToArray (StateNum boundState) (StateMap m) = StateArray
do Array.array (0, pred boundState) do IntMap.toAscList m
mapArrayWithIx :: (StateNum -> a -> a) -> StateArray a -> StateArray a
mapArrayWithIx f (StateArray arr) = StateArray
do Array.listArray
do Array.bounds arr
do [ f (StateNum i) x | (i, x) <- Array.assocs arr ]
indexArray :: StateArray a -> StateNum -> a
indexArray (StateArray arr) (StateNum i) = arr Array.! i
arrayAssocs :: StateArray a -> [(StateNum, a)]
arrayAssocs (StateArray arr) = coerce do Array.assocs arr
newtype StateGraph = StateGraph Graph.Graph
stateArrayToGraph :: StateArray [StateNum] -> StateGraph
stateArrayToGraph (StateArray m) = StateGraph do coerce m
liftGraphOp :: (Graph.Graph -> Graph.Graph) -> StateGraph -> StateGraph
liftGraphOp f x = coerce f x
indexGraph :: StateGraph -> StateNum -> [StateNum]
indexGraph (StateGraph x) (StateNum i) = coerce do x Array.! i