{-# LANGUAGE ConstraintKinds #-} -- For Grammar
module Symantic.Parser.Grammar
 ( module Symantic.Parser.Grammar
 , module Symantic.Parser.Grammar.Combinators
 , module Symantic.Parser.Grammar.Fixity
 , module Symantic.Parser.Grammar.Optimize
 , module Symantic.Parser.Grammar.ObserveSharing
 , module Symantic.Parser.Grammar.Write
 , module Symantic.Parser.Grammar.Dump
 , Letable(..)
 ) where
import Symantic.Parser.Grammar.Combinators
import Symantic.Parser.Grammar.Dump
import Symantic.Parser.Grammar.Fixity
import Symantic.Parser.Grammar.ObserveSharing
import Symantic.Parser.Grammar.Optimize
import Symantic.Parser.Grammar.Write
import Symantic.Univariant.Letable (Letable(..))

import Data.Function ((.))
import Data.String (String)
import Text.Show (Show(..))
import qualified Language.Haskell.TH.Syntax as TH

-- Class 'Grammar'
type Grammar repr =
  ( Applicable repr
  , Alternable repr
  --, Satisfiable repr
  , Letable TH.Name repr
  , Selectable repr
  , Matchable repr
  , Foldable repr
  , Lookable repr
  )

-- | A usual pipeline to interpret 'Comb'inators:
-- 'observeSharing' then 'optimizeComb' then a polymorphic @(repr)@.
grammar :: Grammar repr => ObserveSharing TH.Name (OptimizeComb TH.Name repr) a -> repr a
grammar :: forall (repr :: * -> *) a.
Grammar repr =>
ObserveSharing Name (OptimizeComb Name repr) a -> repr a
grammar = OptimizeComb Name repr a -> repr a
forall (repr :: * -> *) a.
Trans (OptimizeComb Name repr) repr =>
OptimizeComb Name repr a -> repr a
optimizeComb (OptimizeComb Name repr a -> repr a)
-> (ObserveSharing Name (OptimizeComb Name repr) a
    -> OptimizeComb Name repr a)
-> ObserveSharing Name (OptimizeComb Name repr) a
-> repr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ObserveSharing Name (OptimizeComb Name repr) a
-> OptimizeComb Name repr a
forall (repr :: * -> *) a. ObserveSharing Name repr a -> repr a
observeSharing

-- | A usual pipeline to show 'Comb'inators:
-- 'observeSharing' then 'optimizeComb' then 'dumpComb' then 'show'.
showGrammar :: ObserveSharing TH.Name (OptimizeComb TH.Name DumpComb) a -> String
showGrammar :: forall a.
ObserveSharing Name (OptimizeComb Name DumpComb) a -> String
showGrammar = DumpComb a -> String
forall a. Show a => a -> String
show (DumpComb a -> String)
-> (ObserveSharing Name (OptimizeComb Name DumpComb) a
    -> DumpComb a)
-> ObserveSharing Name (OptimizeComb Name DumpComb) a
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DumpComb a -> DumpComb a
forall a. DumpComb a -> DumpComb a
dumpComb (DumpComb a -> DumpComb a)
-> (ObserveSharing Name (OptimizeComb Name DumpComb) a
    -> DumpComb a)
-> ObserveSharing Name (OptimizeComb Name DumpComb) a
-> DumpComb a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OptimizeComb Name DumpComb a -> DumpComb a
forall (repr :: * -> *) a.
Trans (OptimizeComb Name repr) repr =>
OptimizeComb Name repr a -> repr a
optimizeComb (OptimizeComb Name DumpComb a -> DumpComb a)
-> (ObserveSharing Name (OptimizeComb Name DumpComb) a
    -> OptimizeComb Name DumpComb a)
-> ObserveSharing Name (OptimizeComb Name DumpComb) a
-> DumpComb a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ObserveSharing Name (OptimizeComb Name DumpComb) a
-> OptimizeComb Name DumpComb a
forall (repr :: * -> *) a. ObserveSharing Name repr a -> repr a
observeSharing