{-# LANGUAGE UndecidableInstances #-}
module Data.Type.Symbol.Parser.Parser.Or ( Or ) where
import Data.Type.Symbol.Parser.Types
import DeFun.Core ( type (@@), type App )
import Data.Type.List ( Reverse )
type Or
:: Parser sl rl
-> Parser sr rr
-> Parser (Either (sl, [Char]) sr) (Either rl rr)
type family Or pl pr where
Or '(plCh, plEnd, sl) '(prCh, prEnd, sr) =
'(OrChSym plCh prCh sr, OrEndSym plEnd prCh prEnd sr, Left '(sl, '[]))
type OrCh
:: ParserChSym sl rl
-> ParserChSym sr rr
-> sr
-> ParserCh (Either (sl, [Char]) sr) (Either rl rr)
type family OrCh plCh prCh sr ch s where
OrCh plCh prCh sr ch (Left '(sl, chs)) =
OrChL prCh sr (ch : chs) (plCh @@ ch @@ sl)
OrCh plCh prCh _ ch (Right sr) =
OrChR (prCh @@ ch @@ sr)
type OrChL
:: ParserChSym sr rr
-> sr
-> [Char]
-> Result sl rl
-> Result (Either (sl, [Char]) sr) (Either rl rr)
type family OrChL prCh sr chs resl where
OrChL _ _ chs (Cont sl) = Cont (Left '(sl, chs))
OrChL _ _ chs (Done rl) = Done (Left rl)
OrChL prCh sr chs (Err _ ) =
OrChLReplay prCh (Reverse chs) (Cont sr)
type OrChLReplay
:: ParserChSym sr rr
-> [Char]
-> Result sr rr
-> Result (Either (sl, [Char]) sr) (Either rl rr)
type family OrChLReplay prCh chs resr where
OrChLReplay prCh (ch : '[]) (Cont sr) = OrChR (prCh @@ ch @@ sr)
OrChLReplay prCh (ch : chs) (Cont sr) =
OrChLReplay prCh chs (prCh @@ ch @@ sr)
OrChLReplay prCh chs (Err er) = Err (EIn "Or(R)" er)
OrChLReplay prCh chs (Done rr) = Done (Right rr)
type family OrChR resr where
OrChR (Cont sr) = Cont (Right sr)
OrChR (Done rr) = Done (Right rr)
OrChR (Err er) = Err (EIn "Or(R)" er)
type OrEnd
:: ParserEndSym sl rl
-> ParserChSym sr rr
-> ParserEndSym sr rr
-> sr
-> ParserEnd (Either (sl, [Char]) sr) (Either rl rr)
type family OrEnd plEnd prCh prEnd sr res where
OrEnd plEnd prCh prEnd sr (Left '(sl, chs)) =
OrEndL prCh prEnd sr chs (plEnd @@ sl)
OrEnd plEnd prCh prEnd _ (Right sr) = OrEndR (prEnd @@ sr)
type OrEndR
:: Either E rr
-> Either E (Either rl rr)
type family OrEndR s where
OrEndR (Left er) = Left (EIn "Or(R)" er)
OrEndR (Right rr) = Right (Right rr)
type OrEndL
:: ParserChSym sr rr
-> ParserEndSym sr rr
-> sr
-> [Char]
-> Either E rl
-> Either E (Either rl rr)
type family OrEndL prCh prEnd sr chs res where
OrEndL prCh prEnd sr chs (Right rl) = Right (Left rl)
OrEndL prCh prEnd sr chs (Left el) =
OrChLReplay' prCh prEnd (Reverse chs) (Cont sr)
type OrChLReplay'
:: ParserChSym sr rr
-> ParserEndSym sr rr
-> [Char]
-> Result sr rr
-> Either E (Either rl rr)
type family OrChLReplay' prCh prEnd chs resr where
OrChLReplay' prCh prEnd (ch : '[]) (Cont sr) =
OrEndR' prEnd (prCh @@ ch @@ sr)
OrChLReplay' prCh prEnd (ch : chs) (Cont sr) =
OrChLReplay' prCh prEnd chs (prCh @@ ch @@ sr)
OrChLReplay' prCh prEnd chs (Err er) = Left (EIn "Or(R)" er)
OrChLReplay' prCh prEnd chs (Done rr) = Right (Right rr)
type family OrEndR' prEnd s where
OrEndR' prEnd (Err er) = Left (EIn "Or(R)" er)
OrEndR' prEnd (Done rr) = Right (Right rr)
OrEndR' prEnd (Cont sr) = OrEndR (prEnd @@ sr)
data OrChSym plCh prCh sr f
type instance App (OrChSym plCh prCh sr) f = OrChSym1 plCh prCh sr f
data OrChSym1 plCh prCh sr ch s
type instance App (OrChSym1 plCh prCh sr ch) s = OrCh plCh prCh sr ch s
type OrEndSym
:: ParserEndSym sl rl
-> ParserChSym sr rr
-> ParserEndSym sr rr
-> sr
-> ParserEndSym (Either (sl, [Char]) sr) (Either rl rr)
data OrEndSym plEnd prCh prEnd sr s
type instance App (OrEndSym plEnd prCh prEnd sr) s = OrEnd plEnd prCh prEnd sr s