module Symantic.Parser.Machine
 ( module Symantic.Parser.Machine
 , module Symantic.Parser.Machine.Instructions
 , module Symantic.Parser.Machine.Dump
 , module Symantic.Parser.Machine.Generate
 , module Symantic.Parser.Machine.Input
 ) where
import Data.Function ((.))
import Data.Ord (Ord)
import Symantic.Parser.Machine.Input
import Symantic.Parser.Grammar
import Text.Show (Show)
import qualified Language.Haskell.TH.Syntax as TH

import Symantic.Parser.Machine.Instructions
import Symantic.Parser.Machine.Dump
import Symantic.Parser.Machine.Generate

-- * Type 'Parser'
type Parser inp =
  ObserveSharing TH.Name
                 (OptimizeComb TH.Name
                               (Machine inp))

machine :: forall inp repr a.
  Ord (InputToken inp) =>
  Show (InputToken inp) =>
  TH.Lift (InputToken inp) =>
  -- InputToken inp ~ Char =>
  Executable repr =>
  Readable repr (InputToken inp) =>
  Grammar (Machine inp) =>
  Parser inp a ->
  repr inp '[] ('Succ 'Zero) a
machine :: forall inp (repr :: * -> [*] -> Peano -> * -> *) a.
(Ord (InputToken inp), Show (InputToken inp),
 Lift (InputToken inp), Executable repr,
 Readable repr (InputToken inp), Grammar (Machine inp)) =>
Parser inp a -> repr inp '[] ('Succ 'Zero) a
machine = Machine inp a -> repr inp '[] ('Succ 'Zero) a
forall inp v (es :: Peano) (repr :: * -> [*] -> Peano -> * -> *).
(Executable repr, Readable repr (InputToken inp)) =>
Machine inp v -> repr inp '[] ('Succ es) v
runMachine (Machine inp a -> repr inp '[] ('Succ 'Zero) a)
-> (ObserveSharing Name (OptimizeComb Name (Machine inp)) a
    -> Machine inp a)
-> ObserveSharing Name (OptimizeComb Name (Machine inp)) a
-> repr inp '[] ('Succ 'Zero) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OptimizeComb Name (Machine inp) a -> Machine inp a
forall (repr :: * -> *) a.
Trans (OptimizeComb Name repr) repr =>
OptimizeComb Name repr a -> repr a
optimizeComb (OptimizeComb Name (Machine inp) a -> Machine inp a)
-> (ObserveSharing Name (OptimizeComb Name (Machine inp)) a
    -> OptimizeComb Name (Machine inp) a)
-> ObserveSharing Name (OptimizeComb Name (Machine inp)) a
-> Machine inp a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ObserveSharing Name (OptimizeComb Name (Machine inp)) a
-> OptimizeComb Name (Machine inp) a
forall (repr :: * -> *) a. ObserveSharing Name repr a -> repr a
observeSharing