{-# LANGUAGE DerivingStrategies, UnboxedTuples #-}
module Parsley.Internal.Backend.Machine.Types.Input.Offset (
Offset, mkOffset, offset, moveOne, moveN, same,
) where
import Parsley.Internal.Backend.Machine.InputRep (Rep)
import Parsley.Internal.Common.Utils (Code)
data Offset o = Offset {
Offset o -> Code (Rep o)
offset :: Code (Rep o),
Offset o -> Word
unique :: Word,
Offset o -> Amount
moved :: Amount
}
data Amount = Amount Word Word
deriving stock Amount -> Amount -> Bool
(Amount -> Amount -> Bool)
-> (Amount -> Amount -> Bool) -> Eq Amount
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Amount -> Amount -> Bool
$c/= :: Amount -> Amount -> Bool
== :: Amount -> Amount -> Bool
$c== :: Amount -> Amount -> Bool
Eq
same :: Offset o -> Offset o -> Maybe Bool
same :: Offset o -> Offset o -> Maybe Bool
same Offset o
o1 Offset o
o2
| Offset o -> Word
forall o. Offset o -> Word
unique Offset o
o1 Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Offset o -> Word
forall o. Offset o -> Word
unique Offset o
o2 = Bool -> Maybe Bool
forall a. a -> Maybe a
Just (Offset o -> Amount
forall o. Offset o -> Amount
moved Offset o
o1 Amount -> Amount -> Bool
forall a. Eq a => a -> a -> Bool
== Offset o -> Amount
forall o. Offset o -> Amount
moved Offset o
o2)
| Bool
otherwise = Maybe Bool
forall a. Maybe a
Nothing
moveOne :: Offset o -> Code (Rep o) -> Offset o
moveOne :: Offset o -> Code (Rep o) -> Offset o
moveOne = Maybe Word -> Offset o -> Code (Rep o) -> Offset o
forall o. Maybe Word -> Offset o -> Code (Rep o) -> Offset o
moveN (Word -> Maybe Word
forall a. a -> Maybe a
Just Word
1)
moveN :: Maybe Word -> Offset o -> Code (Rep o) -> Offset o
moveN :: Maybe Word -> Offset o -> Code (Rep o) -> Offset o
moveN Maybe Word
n Offset o
off Code (Rep o)
o = Offset o
off { offset :: Code (Rep o)
offset = Code (Rep o)
o, moved :: Amount
moved = Offset o -> Amount
forall o. Offset o -> Amount
moved Offset o
off Amount -> Amount -> Amount
`add` Maybe Word -> Amount
toAmount Maybe Word
n }
where
toAmount :: Maybe Word -> Amount
toAmount :: Maybe Word -> Amount
toAmount Maybe Word
Nothing = Word -> Word -> Amount
Amount Word
1 Word
0
toAmount (Just Word
n) = Word -> Word -> Amount
Amount Word
0 Word
n
mkOffset :: Code (Rep o) -> Word -> Offset o
mkOffset :: Code (Rep o) -> Word -> Offset o
mkOffset Code (Rep o)
offset Word
unique = Code (Rep o) -> Word -> Amount -> Offset o
forall o. Code (Rep o) -> Word -> Amount -> Offset o
Offset Code (Rep o)
offset Word
unique (Word -> Word -> Amount
Amount Word
0 Word
0)
add :: Amount -> Amount -> Amount
add :: Amount -> Amount -> Amount
add a1 :: Amount
a1@(Amount Word
n Word
i) a2 :: Amount
a2@(Amount Word
m Word
j)
| Word
n Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
/= Word
m, Word
n Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
/= Word
0, Word
m Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
/= Word
0 = Word -> Word -> Amount
Amount (Word
n Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
m) Word
0
| Word
n Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
/= Word
0, Word
m Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
/= Word
0 = [Char] -> Amount
forall a. HasCallStack => [Char] -> a
error ([Char]
"adding " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Amount -> [Char]
forall a. Show a => a -> [Char]
show Amount
a1 [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" and " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Amount -> [Char]
forall a. Show a => a -> [Char]
show Amount
a2 [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" makes no sense?")
| Bool
otherwise = Word -> Word -> Amount
Amount (Word -> Word -> Word
forall a. Ord a => a -> a -> a
max Word
n Word
m) (Word
i Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
j)
instance Show (Offset o) where
show :: Offset o -> [Char]
show Offset o
o = Word -> [Char]
forall a. Show a => a -> [Char]
show (Offset o -> Word
forall o. Offset o -> Word
unique Offset o
o) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"+" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Amount -> [Char]
forall a. Show a => a -> [Char]
show (Offset o -> Amount
forall o. Offset o -> Amount
moved Offset o
o)
instance Show Amount where
show :: Amount -> [Char]
show (Amount Word
n Word
m) = Word -> [Char]
forall a. Show a => a -> [Char]
show Word
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"*n+" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Word -> [Char]
forall a. Show a => a -> [Char]
show Word
m