{-# LANGUAGE TemplateHaskell #-} module Symantic.Parser.Machine ( module Symantic.Parser.Machine , module Symantic.Parser.Machine.Instructions , module Symantic.Parser.Machine.Dump , module Symantic.Parser.Machine.Eval , module Symantic.Parser.Machine.Input ) where import Symantic.Parser.Machine.Instructions import Symantic.Parser.Machine.Dump import Symantic.Parser.Machine.Eval import Data.Either (Either(..)) import Data.Function ((.)) -- import Data.Char (Char) import Data.Ord (Ord) import Language.Haskell.TH (CodeQ) import Symantic.Parser.Machine.Input import Symantic.Parser.Grammar import Text.Show (Show) import qualified Language.Haskell.TH.Syntax as TH 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 = runMachine . optimizeComb . observeSharing runParser :: forall inp a. Ord (InputToken inp) => Show (InputToken inp) => TH.Lift (InputToken inp) => -- InputToken inp ~ Char => Input inp => Readable Eval (InputToken inp) => Parser inp a -> CodeQ (inp -> Either (ParsingError inp) a) runParser p = [|| \input -> $$(eval [||input||] (machine p)) ||]