{-# LANGUAGE BinaryLiterals #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} module HaskellWorks.Data.Json.Internal.Backend.Standard.StateMachine ( lookupPhiTable , lookupTransitionTable , phiTable , phiTableSimd , transitionTable , transitionTableSimd , IntState(..) , State(..) ) where import Data.Word import HaskellWorks.Data.Bits.BitWise import qualified Data.Vector as DV import qualified Data.Vector.Storable as DVS import qualified HaskellWorks.Data.Json.Internal.Word8 as W8 {-# ANN module ("HLint: ignore Redundant guard" :: String) #-} newtype IntState = IntState Int deriving (Eq, Ord, Show, Num) data State = InJson | InString | InEscape | InValue deriving (Eq, Enum, Bounded, Show) phiTable :: DV.Vector (DVS.Vector Word8) phiTable = DV.constructN 5 gos where gos :: DV.Vector (DVS.Vector Word8) -> DVS.Vector Word8 gos v = DVS.constructN 256 go where vi = DV.length v go :: DVS.Vector Word8 -> Word8 go u = fromIntegral (snd (stateMachine (fromIntegral ui) (toEnum vi))) where ui = DVS.length u {-# NOINLINE phiTable #-} phiTable2 :: DVS.Vector Word8 phiTable2 = DVS.constructN (4 * fromIntegral iLen) go where iLen = 256 :: Int go :: DVS.Vector Word8 -> Word8 go u = fromIntegral (snd (stateMachine (fromIntegral ui) (toEnum (fromIntegral uj)))) where (uj, ui) = fromIntegral (DVS.length u) `divMod` iLen {-# NOINLINE phiTable2 #-} lookupPhiTable :: IntState -> Word8 -> Word8 lookupPhiTable (IntState s) w = DVS.unsafeIndex phiTable2 (s * 256 + fromIntegral w) {-# INLINE lookupPhiTable #-} phiTableSimd :: DVS.Vector Word32 phiTableSimd = DVS.constructN 256 go where go :: DVS.Vector Word32 -> Word32 go v = (snd (stateMachine vi InJson ) .<. 0) .|. (snd (stateMachine vi InString) .<. 8) .|. (snd (stateMachine vi InEscape) .<. 16) .|. (snd (stateMachine vi InValue ) .<. 24) where vi = fromIntegral (DVS.length v) {-# NOINLINE phiTableSimd #-} transitionTable :: DV.Vector (DVS.Vector Word8) transitionTable = DV.constructN 5 gos where gos :: DV.Vector (DVS.Vector Word8) -> DVS.Vector Word8 gos v = DVS.constructN 256 go where vi = DV.length v go :: DVS.Vector Word8 -> Word8 go u = fromIntegral (fromEnum (fst (stateMachine ui (toEnum vi)))) where ui = fromIntegral (DVS.length u) {-# NOINLINE transitionTable #-} transitionTable2 :: DVS.Vector Word8 transitionTable2 = DVS.constructN (4 * fromIntegral iLen) go where iLen = 256 :: Int go :: DVS.Vector Word8 -> Word8 go u = fromIntegral (fromEnum (fst (stateMachine (fromIntegral ui) (toEnum (fromIntegral uj))))) where (uj, ui) = fromIntegral (DVS.length u) `divMod` iLen {-# NOINLINE transitionTable2 #-} lookupTransitionTable :: IntState -> Word8 -> IntState lookupTransitionTable (IntState s) w = fromIntegral (DVS.unsafeIndex transitionTable2 (s * 256 + fromIntegral w)) {-# INLINE lookupTransitionTable #-} transitionTableSimd :: DVS.Vector Word64 transitionTableSimd = DVS.constructN 256 go where go :: DVS.Vector Word64 -> Word64 go v = fromIntegral (fromEnum (fst (stateMachine vi InJson ))) .|. fromIntegral (fromEnum (fst (stateMachine vi InString))) .|. fromIntegral (fromEnum (fst (stateMachine vi InEscape))) .|. fromIntegral (fromEnum (fst (stateMachine vi InValue ))) where vi = fromIntegral (DVS.length v) {-# NOINLINE transitionTableSimd #-} stateMachine :: Word8 -> State -> (State, Word32) stateMachine c InJson | W8.isOpen c = (InJson , 0b110) stateMachine c InJson | W8.isClose c = (InJson , 0b001) stateMachine c InJson | W8.isDelim c = (InJson , 0b000) stateMachine c InJson | W8.isValueChar c = (InValue , 0b111) stateMachine c InJson | W8.isDoubleQuote c = (InString, 0b111) stateMachine _ InJson | otherwise = (InJson , 0b000) stateMachine c InString | W8.isDoubleQuote c = (InJson , 0b000) stateMachine c InString | W8.isBackSlash c = (InEscape, 0b000) stateMachine _ InString | otherwise = (InString, 0b000) stateMachine _ InEscape | otherwise = (InString, 0b000) stateMachine c InValue | W8.isOpen c = (InJson , 0b110) stateMachine c InValue | W8.isClose c = (InJson , 0b001) stateMachine c InValue | W8.isDelim c = (InJson , 0b000) stateMachine c InValue | W8.isValueChar c = (InValue , 0b000) stateMachine _ InValue | otherwise = (InJson , 0b000) {-# INLINE stateMachine #-}