module Symantic.Parser
  ( module Symantic.Parser.Grammar
  , module Symantic.Parser.Machine
  , module Symantic.Parser
  ) where

import Control.Monad.ST (ST, RealWorld)
import Data.Function (($))
import Language.Haskell.TH (CodeQ)
import qualified Language.Haskell.TH.Syntax as TH

import Symantic.Parser.Grammar
import Symantic.Parser.Machine

-- * Type 'Parser'
type Parser inp a = Machine Gen inp a

-- ** Type 'Parsed'
type Parsed inp a = ST RealWorld (Result inp a)

runParser :: forall inp a.
  Inputable inp =>
  Machinable (InputToken inp) Gen =>
  Parser inp a ->
  CodeQ (inp -> Parsed inp a)
runParser p = TH.Code $ do
  mach <- TH.runIO $ machine p
  TH.examineCode $ generateCode mach