-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Parser combinators statically optimized and staged via typed meta-programming -- -- This is a work-in-progress experimental library to generate parsers, -- leveraging Tagless-Final interpreters and Typed Template Haskell -- staging. -- -- This is an alternative but less powerful/reviewed implementation of -- ParsleyHaskell. See the paper by Jamie Willis, Nicolas Wu, and -- Matthew Pickering, admirably well presented at ICFP-2020: Staged -- Selective Parser Combinators. @package symantic-parser @version 0.0.0.20210102 module Symantic.Parser.Grammar.Fixity data Fixity Fixity1 :: Unifix -> Fixity Fixity2 :: Infix -> Fixity data Unifix Prefix :: Precedence -> Unifix [unifix_precedence] :: Unifix -> Precedence Postfix :: Precedence -> Unifix [unifix_precedence] :: Unifix -> Precedence data Infix Infix :: Maybe Associativity -> Precedence -> Infix [infix_associativity] :: Infix -> Maybe Associativity [infix_precedence] :: Infix -> Precedence infixL :: Precedence -> Infix infixR :: Precedence -> Infix infixB :: Side -> Precedence -> Infix infixN :: Precedence -> Infix infixN0 :: Infix infixN5 :: Infix -- | Given Precedence and Associativity of its parent -- operator, and the operand Side it is in, return whether an -- Infix operator needs to be enclosed by a Pair. isPairNeeded :: (Infix, Side) -> Infix -> Bool -- | If isPairNeeded is True, enclose the given -- IsString by given Pair, otherwise returns the same -- IsString. pairIfNeeded :: Semigroup s => IsString s => Pair -> (Infix, Side) -> Infix -> s -> s type Precedence = Int class PrecedenceOf a precedence :: PrecedenceOf a => a -> Precedence data Associativity -- | Associate to the left: a ¹ b ² c == (a ¹ b) ² c AssocL :: Associativity -- | Associate to the right: a ¹ b ² c == a ¹ (b ² c) AssocR :: Associativity -- | Associate to both sides, but to Side when reading. AssocB :: Side -> Associativity data Side -- | Left SideL :: Side -- | Right SideR :: Side type Pair = (String, String) pairAngle :: Pair pairBrace :: Pair pairBracket :: Pair pairParen :: Pair instance GHC.Show.Show Symantic.Parser.Grammar.Fixity.Unifix instance GHC.Classes.Eq Symantic.Parser.Grammar.Fixity.Unifix instance GHC.Show.Show Symantic.Parser.Grammar.Fixity.Side instance GHC.Classes.Eq Symantic.Parser.Grammar.Fixity.Side instance GHC.Show.Show Symantic.Parser.Grammar.Fixity.Associativity instance GHC.Classes.Eq Symantic.Parser.Grammar.Fixity.Associativity instance GHC.Show.Show Symantic.Parser.Grammar.Fixity.Infix instance GHC.Classes.Eq Symantic.Parser.Grammar.Fixity.Infix instance GHC.Show.Show Symantic.Parser.Grammar.Fixity.Fixity instance GHC.Classes.Eq Symantic.Parser.Grammar.Fixity.Fixity instance Symantic.Parser.Grammar.Fixity.PrecedenceOf Symantic.Parser.Grammar.Fixity.Fixity instance Symantic.Parser.Grammar.Fixity.PrecedenceOf Symantic.Parser.Grammar.Fixity.Infix instance Symantic.Parser.Grammar.Fixity.PrecedenceOf Symantic.Parser.Grammar.Fixity.Unifix module Symantic.Parser.Machine.Input class Show cur => Cursorable cur offset :: Cursorable cur => cur -> Int compareOffset :: Cursorable cur => CodeQ (cur -> cur -> Ordering) lowerOffset :: Cursorable cur => CodeQ (cur -> cur -> Bool) sameOffset :: Cursorable cur => CodeQ (cur -> cur -> Bool) shiftRight :: Cursorable cur => CodeQ (cur -> Int -> cur) shiftRightText :: Text -> Int -> Text shiftLeftText :: Text -> Int -> Text shiftRightByteString :: UnpackedLazyByteString -> Int -> UnpackedLazyByteString shiftLeftByteString :: UnpackedLazyByteString -> Int -> UnpackedLazyByteString offWith :: CodeQ (ts -> OffWith ts) newtype Text16 Text16 :: Text -> Text16 newtype CharList CharList :: String -> CharList data Stream (:>) :: {-# UNPACK #-} !Char -> Stream -> Stream nomore :: Stream data OffWith ts OffWith :: {-# UNPACK #-} !Int -> ts -> OffWith ts data OffWithStreamAnd ts OffWithStreamAnd :: {-# UNPACK #-} !Int -> !Stream -> ts -> OffWithStreamAnd ts data UnpackedLazyByteString UnpackedLazyByteString :: {-# UNPACK #-} !Int -> !Addr# -> ForeignPtrContents -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> ByteString -> UnpackedLazyByteString emptyUnpackedLazyByteString :: Int -> UnpackedLazyByteString class Cursorable (Cursor inp) => Input inp where { type family Cursor inp :: Type; type family InputToken inp :: Type; } cursorOf :: Input inp => CodeQ inp -> CodeQ (# Cursor inp, Cursor inp -> Bool, Cursor inp -> (# InputToken inp, Cursor inp #) #) instance GHC.Show.Show ts => GHC.Show.Show (Symantic.Parser.Machine.Input.OffWith ts) instance Symantic.Parser.Machine.Input.Input GHC.Base.String instance Symantic.Parser.Machine.Input.Input (Data.Array.Base.UArray GHC.Types.Int GHC.Types.Char) instance Symantic.Parser.Machine.Input.Input Data.Text.Internal.Text instance Symantic.Parser.Machine.Input.Input Data.ByteString.Internal.ByteString instance Symantic.Parser.Machine.Input.Input Data.ByteString.Lazy.Internal.ByteString instance Symantic.Parser.Machine.Input.Cursorable Symantic.Parser.Machine.Input.UnpackedLazyByteString instance GHC.Show.Show Symantic.Parser.Machine.Input.UnpackedLazyByteString instance Symantic.Parser.Machine.Input.Cursorable (Symantic.Parser.Machine.Input.OffWith GHC.Base.String) instance Symantic.Parser.Machine.Input.Cursorable GHC.Types.Int instance Symantic.Parser.Machine.Input.Cursorable Data.Text.Internal.Text module Symantic.Univariant.Trans type family Output (repr :: Type -> Type) :: Type -> Type -- | A translation from an interpreter (from) to an -- interpreter (to). class Trans from to trans :: Trans from to => from a -> to a -- | Convenient type class synonym. Note that this is not necessarily a -- bijective translation, a trans being not necessarily -- injective nor surjective. type BiTrans from to = (Trans from to, Trans to from) -- | Convenient type class synonym for using Output type Liftable repr = Trans (Output repr) repr lift :: forall repr a. Liftable repr => Output repr a -> repr a unlift :: forall repr a. Trans repr (Output repr) => repr a -> Output repr a -- | Convenient type class synonym for using Output type Unliftable repr = Trans repr (Output repr) class Trans1 from to trans1 :: Trans1 from to => (from a -> from b) -> to a -> to b trans1 :: (Trans1 from to, BiTrans from to) => (from a -> from b) -> to a -> to b -- | Convenient type class synonym for using Output type Liftable1 repr = Trans1 (Output repr) repr lift1 :: forall repr a b. Liftable1 repr => (Output repr a -> Output repr b) -> repr a -> repr b class Trans2 from to trans2 :: Trans2 from to => (from a -> from b -> from c) -> to a -> to b -> to c trans2 :: (Trans2 from to, BiTrans from to) => (from a -> from b -> from c) -> to a -> to b -> to c -- | Convenient type class synonym for using Output type Liftable2 repr = Trans2 (Output repr) repr lift2 :: forall repr a b c. Liftable2 repr => (Output repr a -> Output repr b -> Output repr c) -> repr a -> repr b -> repr c class Trans3 from to trans3 :: Trans3 from to => (from a -> from b -> from c -> from d) -> to a -> to b -> to c -> to d trans3 :: (Trans3 from to, BiTrans from to) => (from a -> from b -> from c -> from d) -> to a -> to b -> to c -> to d -- | Convenient type class synonym for using Output type Liftable3 repr = Trans3 (Output repr) repr lift3 :: forall repr a b c d. Liftable3 repr => (Output repr a -> Output repr b -> Output repr c -> Output repr d) -> repr a -> repr b -> repr c -> repr d -- | A newtype to disambiguate the Trans instance to any other -- interpreter when there is also one or more Transs to other -- interpreters with a different interpretation than the generic one. newtype Any repr a Any :: repr a -> Any repr a [unAny] :: Any repr a -> repr a instance Symantic.Univariant.Trans.Trans (Symantic.Univariant.Trans.Any repr) repr instance Symantic.Univariant.Trans.Trans1 (Symantic.Univariant.Trans.Any repr) repr instance Symantic.Univariant.Trans.Trans2 (Symantic.Univariant.Trans.Any repr) repr instance Symantic.Univariant.Trans.Trans3 (Symantic.Univariant.Trans.Any repr) repr instance Symantic.Univariant.Trans.Trans repr (Symantic.Univariant.Trans.Any repr) instance Symantic.Univariant.Trans.Trans1 repr (Symantic.Univariant.Trans.Any repr) instance Symantic.Univariant.Trans.Trans2 repr (Symantic.Univariant.Trans.Any repr) instance Symantic.Univariant.Trans.Trans3 repr (Symantic.Univariant.Trans.Any repr) module Symantic.Univariant.Letable -- | This class is not for manual usage like usual symantic operators, here -- def and ref are introduced by observeSharing. class Letable letName repr -- | (def letName x) let-binds (letName) to be -- equal to (x). def :: Letable letName repr => letName -> repr a -> repr a -- | (ref isRec letName) is a reference to -- (letName). (isRec) is True iif. this -- reference is recursive, ie. is reachable within its -- definition. ref :: Letable letName repr => Bool -> letName -> repr a -- | (def letName x) let-binds (letName) to be -- equal to (x). def :: (Letable letName repr, Liftable1 repr) => Letable letName (Output repr) => letName -> repr a -> repr a -- | (ref isRec letName) is a reference to -- (letName). (isRec) is True iif. this -- reference is recursive, ie. is reachable within its -- definition. ref :: (Letable letName repr, Liftable repr) => Letable letName (Output repr) => Bool -> letName -> repr a class MakeLetName letName makeLetName :: MakeLetName letName => SharingName -> IO letName -- | Note that the observable sharing enabled by StableName is not -- perfect as it will not observe all the sharing explicitely done. -- -- Note also that the observed sharing could be different between ghc and -- ghci. data SharingName SharingName :: StableName a -> SharingName -- | (makeSharingName x) is like (makeStableName -- x) but it also forces evaluation of (x) to ensure that -- the StableName is correct first time, which avoids to produce a -- tree bigger than needed. -- -- Note that this function uses unsafePerformIO instead of -- returning in IO, this is apparently required to avoid infinite -- loops due to unstable StableName in compiled code, and -- sometimes also in ghci. -- -- Note that maybe pseq should be used here. makeSharingName :: a -> SharingName -- | Interpreter detecting some (Haskell embedded) let definitions -- used at least once and/or recursively, in order to replace them with -- the def and ref combinators. See Type-safe observable -- sharing in Haskell newtype ObserveSharing letName repr a ObserveSharing :: ReaderT (HashSet SharingName) (State (ObserveSharingState letName)) (CleanDefs letName repr a) -> ObserveSharing letName repr a [unObserveSharing] :: ObserveSharing letName repr a -> ReaderT (HashSet SharingName) (State (ObserveSharingState letName)) (CleanDefs letName repr a) observeSharing :: Eq letName => Hashable letName => ObserveSharing letName repr a -> repr a data ObserveSharingState letName ObserveSharingState :: HashMap SharingName (letName, Int) -> HashSet SharingName -> ObserveSharingState letName [oss_refs] :: ObserveSharingState letName -> HashMap SharingName (letName, Int) -- | TODO: unused so far, will it be useful somewhere at a later stage? [oss_recs] :: ObserveSharingState letName -> HashSet SharingName observeSharingNode :: Eq letName => Hashable letName => Letable letName repr => MakeLetName letName => ObserveSharing letName repr a -> ObserveSharing letName repr a -- | Remove def when non-recursive or unused. newtype CleanDefs letName repr a CleanDefs :: (HashSet letName -> repr a) -> CleanDefs letName repr a [unCleanDefs] :: CleanDefs letName repr a -> HashSet letName -> repr a instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName) => Symantic.Univariant.Trans.Trans (Symantic.Univariant.Letable.CleanDefs letName repr) (Symantic.Univariant.Letable.ObserveSharing letName repr) instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName) => Symantic.Univariant.Trans.Trans1 (Symantic.Univariant.Letable.CleanDefs letName repr) (Symantic.Univariant.Letable.ObserveSharing letName repr) instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName) => Symantic.Univariant.Trans.Trans2 (Symantic.Univariant.Letable.CleanDefs letName repr) (Symantic.Univariant.Letable.ObserveSharing letName repr) instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName) => Symantic.Univariant.Trans.Trans3 (Symantic.Univariant.Letable.CleanDefs letName repr) (Symantic.Univariant.Letable.ObserveSharing letName repr) instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName) => Symantic.Univariant.Letable.Letable letName (Symantic.Univariant.Letable.ObserveSharing letName repr) instance Symantic.Univariant.Trans.Trans repr (Symantic.Univariant.Letable.CleanDefs letName repr) instance Symantic.Univariant.Trans.Trans1 repr (Symantic.Univariant.Letable.CleanDefs letName repr) instance Symantic.Univariant.Trans.Trans2 repr (Symantic.Univariant.Letable.CleanDefs letName repr) instance Symantic.Univariant.Trans.Trans3 repr (Symantic.Univariant.Letable.CleanDefs letName repr) instance (Symantic.Univariant.Letable.Letable letName repr, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName) => Symantic.Univariant.Letable.Letable letName (Symantic.Univariant.Letable.CleanDefs letName repr) instance GHC.Classes.Eq Symantic.Univariant.Letable.SharingName instance Data.Hashable.Class.Hashable Symantic.Univariant.Letable.SharingName -- | Haskell terms which are interesting to pattern-match when optimizing. module Symantic.Parser.Haskell -- | Compile-time value and corresponding code (that can -- produce that value at runtime). data ValueCode a ValueCode :: Value a -> CodeQ a -> ValueCode a [value] :: ValueCode a -> Value a [code] :: ValueCode a -> CodeQ a getValue :: ValueCode a -> a getCode :: ValueCode a -> CodeQ a newtype Value a Value :: a -> Value a [unValue] :: Value a -> a -- | Final encoding of some Haskell functions useful for some optimizations -- in optimizeComb. class Haskellable (repr :: Type -> Type) (.) :: Haskellable repr => repr ((b -> c) -> (a -> b) -> a -> c) ($) :: Haskellable repr => repr ((a -> b) -> a -> b) (.@) :: Haskellable repr => repr (a -> b) -> repr a -> repr b bool :: Haskellable repr => Bool -> repr Bool char :: (Haskellable repr, Lift tok) => tok -> repr tok cons :: Haskellable repr => repr (a -> [a] -> [a]) const :: Haskellable repr => repr (a -> b -> a) eq :: (Haskellable repr, Eq a) => repr a -> repr (a -> Bool) flip :: Haskellable repr => repr ((a -> b -> c) -> b -> a -> c) id :: Haskellable repr => repr (a -> a) nil :: Haskellable repr => repr [a] unit :: Haskellable repr => repr () left :: Haskellable repr => repr (l -> Either l r) right :: Haskellable repr => repr (r -> Either l r) nothing :: Haskellable repr => repr (Maybe a) just :: Haskellable repr => repr (a -> Maybe a) infixl 9 .@ infixr 9 . infixr 0 $ -- | Initial encoding of Haskellable. data Haskell a [Haskell] :: ValueCode a -> Haskell a [:.] :: Haskell ((b -> c) -> (a -> b) -> a -> c) [:$] :: Haskell ((a -> b) -> a -> b) [:@] :: Haskell (a -> b) -> Haskell a -> Haskell b [Cons] :: Haskell (a -> [a] -> [a]) [Const] :: Haskell (a -> b -> a) [Eq] :: Eq a => Haskell a -> Haskell (a -> Bool) [Flip] :: Haskell ((a -> b -> c) -> b -> a -> c) [Id] :: Haskell (a -> a) [Unit] :: Haskell () infixl 9 :@ infixr 0 :$ infixr 9 :. instance GHC.Show.Show (Symantic.Parser.Haskell.Haskell a) instance Symantic.Univariant.Trans.Trans Symantic.Parser.Haskell.Haskell Symantic.Parser.Haskell.Value instance Symantic.Univariant.Trans.Trans Symantic.Parser.Haskell.Haskell Language.Haskell.TH.Lib.Internal.CodeQ instance Symantic.Univariant.Trans.Trans Symantic.Parser.Haskell.Haskell Symantic.Parser.Haskell.ValueCode instance Symantic.Univariant.Trans.Trans Symantic.Parser.Haskell.ValueCode Symantic.Parser.Haskell.Haskell instance Symantic.Parser.Haskell.Haskellable Symantic.Parser.Haskell.Haskell instance Symantic.Parser.Haskell.Haskellable Symantic.Parser.Haskell.ValueCode instance Symantic.Parser.Haskell.Haskellable Symantic.Parser.Haskell.Value instance Symantic.Parser.Haskell.Haskellable Language.Haskell.TH.Lib.Internal.CodeQ module Symantic.Parser.Grammar.Combinators -- | This is like the usual Functor and Applicative type -- classes from the base package, but using (Haskell -- a) instead of just (a) to be able to use and pattern -- match on some usual terms of type (a) (like id) and -- thus apply some optimizations. (repr) , for "representation", -- is the usual tagless-final abstraction over the many semantics that -- this syntax (formed by the methods of type class like this one) will -- be interpreted. class Applicable repr -- | (a2b <$> ra) parses like (ra) but maps -- its returned value with (a2b). (<$>) :: Applicable repr => Haskell (a -> b) -> repr a -> repr b -- | Like <$> but with its arguments flip-ped. (<&>) :: Applicable repr => repr a -> Haskell (a -> b) -> repr b -- | (a <$ rb) parses like (rb) but discards -- its returned value by replacing it with (a). (<$) :: Applicable repr => Haskell a -> repr b -> repr a -- | (ra $> b) parses like (ra) but discards -- its returned value by replacing it with (b). ($>) :: Applicable repr => repr a -> Haskell b -> repr b -- | (pure a) parses the empty string, always succeeding in -- returning (a). pure :: Applicable repr => Haskell a -> repr a -- | (pure a) parses the empty string, always succeeding in -- returning (a). pure :: (Applicable repr, Liftable repr) => Applicable (Output repr) => Haskell a -> repr a -- | (ra2b <*> ra) parses sequentially -- (ra2b) and then (ra), and returns the application of -- the function returned by (ra2b) to the value returned by -- (ra). (<*>) :: Applicable repr => repr (a -> b) -> repr a -> repr b -- | (ra2b <*> ra) parses sequentially -- (ra2b) and then (ra), and returns the application of -- the function returned by (ra2b) to the value returned by -- (ra). (<*>) :: (Applicable repr, Liftable2 repr) => Applicable (Output repr) => repr (a -> b) -> repr a -> repr b -- | (liftA2 a2b2c ra rb) parses sequentially (ra) -- and then (rb), and returns the application of -- (a2b2c) to the values returned by those parsers. liftA2 :: Applicable repr => Haskell (a -> b -> c) -> repr a -> repr b -> repr c -- | (ra <* rb) parses sequentially (ra) and -- then (rb), and returns like (ra), discarding the -- return value of (rb). (<*) :: Applicable repr => repr a -> repr b -> repr a -- | (ra *> rb) parses sequentially (ra) and -- then (rb), and returns like (rb), discarding the -- return value of (ra). (*>) :: Applicable repr => repr a -> repr b -> repr b -- | Like <*> but with its arguments flip-ped. (<**>) :: Applicable repr => repr a -> repr (a -> b) -> repr b infixl 4 $> infixl 4 <&> infixl 4 <**> infixl 4 <$ infixl 4 <* infixl 4 <$> infixl 4 *> infixl 4 <*> class Alternable repr -- | (rl <|> rr) parses (rl) and return its -- return value or, if it fails, parses (rr) from where -- (rl) has left the input stream, and returns its return value. (<|>) :: Alternable repr => repr a -> repr a -> repr a -- | (empty) parses nothing, always failing to return a value. empty :: Alternable repr => repr a -- | (try ra) records the input stream position, then -- parses like (ra) and either returns its value it it succeeds -- or fails if it fails but with a reset of the input stream to the -- recorded position. Generally used on the first alternative: -- (try rl <|> rr). try :: Alternable repr => repr a -> repr a -- | (rl <|> rr) parses (rl) and return its -- return value or, if it fails, parses (rr) from where -- (rl) has left the input stream, and returns its return value. (<|>) :: (Alternable repr, Liftable2 repr) => Alternable (Output repr) => repr a -> repr a -> repr a -- | (empty) parses nothing, always failing to return a value. empty :: (Alternable repr, Liftable repr) => Alternable (Output repr) => repr a -- | (try ra) records the input stream position, then -- parses like (ra) and either returns its value it it succeeds -- or fails if it fails but with a reset of the input stream to the -- recorded position. Generally used on the first alternative: -- (try rl <|> rr). try :: (Alternable repr, Liftable1 repr) => Alternable (Output repr) => repr a -> repr a -- | Like (<|>) but with different returning types -- for the alternatives, and a return value wrapped in an Either -- accordingly. (<+>) :: (Alternable repr, Applicable repr) => Alternable repr => repr a -> repr b -> repr (Either a b) infixl 3 <+> infixl 3 <|> optionally :: Applicable repr => Alternable repr => repr a -> Haskell b -> repr b optional :: Applicable repr => Alternable repr => repr a -> repr () option :: Applicable repr => Alternable repr => Haskell a -> repr a -> repr a choice :: Alternable repr => [repr a] -> repr a maybeP :: Applicable repr => Alternable repr => repr a -> repr (Maybe a) manyTill :: Applicable repr => Alternable repr => repr a -> repr b -> repr [a] class Selectable repr branch :: Selectable repr => repr (Either a b) -> repr (a -> c) -> repr (b -> c) -> repr c branch :: (Selectable repr, Liftable3 repr) => Selectable (Output repr) => repr (Either a b) -> repr (a -> c) -> repr (b -> c) -> repr c class Matchable repr conditional :: (Matchable repr, Eq a) => [Haskell (a -> Bool)] -> [repr b] -> repr a -> repr b -> repr b conditional :: (Matchable repr, Unliftable repr) => Liftable2 repr => Matchable (Output repr) => Eq a => [Haskell (a -> Bool)] -> [repr b] -> repr a -> repr b -> repr b match :: (Matchable repr, Eq a) => [Haskell a] -> repr a -> (Haskell a -> repr b) -> repr b -> repr b class Foldable repr chainPre :: Foldable repr => repr (a -> a) -> repr a -> repr a chainPost :: Foldable repr => repr a -> repr (a -> a) -> repr a chainPre :: (Foldable repr, Applicable repr) => Alternable repr => repr (a -> a) -> repr a -> repr a chainPost :: (Foldable repr, Applicable repr) => Alternable repr => repr a -> repr (a -> a) -> repr a class Satisfiable repr tok satisfy :: Satisfiable repr tok => [ErrorItem tok] -> Haskell (tok -> Bool) -> repr tok satisfy :: (Satisfiable repr tok, Liftable repr) => Satisfiable (Output repr) tok => [ErrorItem tok] -> Haskell (tok -> Bool) -> repr tok data ErrorItem tok ErrorItemToken :: tok -> ErrorItem tok ErrorItemLabel :: String -> ErrorItem tok ErrorItemEnd :: ErrorItem tok class Lookable repr look :: Lookable repr => repr a -> repr a negLook :: Lookable repr => repr a -> repr () look :: (Lookable repr, Liftable1 repr) => Lookable (Output repr) => repr a -> repr a negLook :: (Lookable repr, Liftable1 repr) => Lookable (Output repr) => repr a -> repr () eof :: Lookable repr => repr () eof :: (Lookable repr, Liftable repr) => Lookable (Output repr) => repr () (<:>) :: Applicable repr => repr a -> repr [a] -> repr [a] infixl 4 <:> sequence :: Applicable repr => [repr a] -> repr [a] traverse :: Applicable repr => (a -> repr b) -> [a] -> repr [b] repeat :: Applicable repr => Int -> repr a -> repr [a] between :: Applicable repr => repr o -> repr c -> repr a -> repr a string :: Applicable repr => Satisfiable repr Char => [Char] -> repr [Char] noneOf :: Lift tok => Eq tok => Satisfiable repr tok => [tok] -> repr tok ofChars :: Lift tok => Eq tok => [tok] -> CodeQ tok -> CodeQ Bool more :: Applicable repr => Satisfiable repr Char => Lookable repr => repr () char :: Applicable repr => Satisfiable repr Char => Char -> repr Char anyChar :: Satisfiable repr Char => repr Char token :: Lift tok => Eq tok => Applicable repr => Satisfiable repr tok => tok -> repr tok tokens :: Lift tok => Eq tok => Applicable repr => Alternable repr => Satisfiable repr tok => [tok] -> repr [tok] item :: Satisfiable repr tok => repr tok void :: Applicable repr => repr a -> repr () unit :: Applicable repr => repr () pfoldr :: Applicable repr => Foldable repr => Haskell (a -> b -> b) -> Haskell b -> repr a -> repr b pfoldr1 :: Applicable repr => Foldable repr => Haskell (a -> b -> b) -> Haskell b -> repr a -> repr b pfoldl :: Applicable repr => Foldable repr => Haskell (b -> a -> b) -> Haskell b -> repr a -> repr b pfoldl1 :: Applicable repr => Foldable repr => Haskell (b -> a -> b) -> Haskell b -> repr a -> repr b chainl1' :: Applicable repr => Foldable repr => Haskell (a -> b) -> repr a -> repr (b -> a -> b) -> repr b chainl1 :: Applicable repr => Foldable repr => repr a -> repr (a -> a -> a) -> repr a chainl :: Applicable repr => Alternable repr => Foldable repr => repr a -> repr (a -> a -> a) -> Haskell a -> repr a many :: Applicable repr => Foldable repr => repr a -> repr [a] manyN :: Applicable repr => Foldable repr => Int -> repr a -> repr [a] some :: Applicable repr => Foldable repr => repr a -> repr [a] skipMany :: Applicable repr => Foldable repr => repr a -> repr () skipManyN :: Applicable repr => Foldable repr => Int -> repr a -> repr () skipSome :: Applicable repr => Foldable repr => repr a -> repr () sepBy :: Applicable repr => Alternable repr => Foldable repr => repr a -> repr b -> repr [a] sepBy1 :: Applicable repr => Alternable repr => Foldable repr => repr a -> repr b -> repr [a] endBy :: Applicable repr => Alternable repr => Foldable repr => repr a -> repr b -> repr [a] endBy1 :: Applicable repr => Alternable repr => Foldable repr => repr a -> repr b -> repr [a] sepEndBy :: Applicable repr => Alternable repr => Foldable repr => repr a -> repr b -> repr [a] sepEndBy1 :: Applicable repr => Alternable repr => Foldable repr => repr a -> repr b -> repr [a] instance GHC.Classes.Eq tok => GHC.Classes.Eq (Symantic.Parser.Grammar.Combinators.ErrorItem tok) instance GHC.Classes.Ord tok => GHC.Classes.Ord (Symantic.Parser.Grammar.Combinators.ErrorItem tok) instance GHC.Show.Show tok => GHC.Show.Show (Symantic.Parser.Grammar.Combinators.ErrorItem tok) instance Language.Haskell.TH.Syntax.Lift tok => Language.Haskell.TH.Syntax.Lift (Symantic.Parser.Grammar.Combinators.ErrorItem tok) module Symantic.Parser.Grammar.Write newtype WriteComb a WriteComb :: (WriteCombInh -> Maybe Builder) -> WriteComb a [unWriteComb] :: WriteComb a -> WriteCombInh -> Maybe Builder data WriteCombInh WriteCombInh :: Builder -> (Infix, Side) -> Pair -> WriteCombInh [writeCombInh_indent] :: WriteCombInh -> Builder [writeCombInh_op] :: WriteCombInh -> (Infix, Side) [writeCombInh_pair] :: WriteCombInh -> Pair emptyWriteCombInh :: WriteCombInh writeComb :: WriteComb a -> Text pairWriteCombInh :: Semigroup s => IsString s => WriteCombInh -> Infix -> Maybe s -> Maybe s instance Data.String.IsString (Symantic.Parser.Grammar.Write.WriteComb a) instance GHC.Show.Show letName => Symantic.Univariant.Letable.Letable letName Symantic.Parser.Grammar.Write.WriteComb instance Symantic.Parser.Grammar.Combinators.Applicable Symantic.Parser.Grammar.Write.WriteComb instance Symantic.Parser.Grammar.Combinators.Alternable Symantic.Parser.Grammar.Write.WriteComb instance Symantic.Parser.Grammar.Combinators.Satisfiable Symantic.Parser.Grammar.Write.WriteComb tok instance Symantic.Parser.Grammar.Combinators.Selectable Symantic.Parser.Grammar.Write.WriteComb instance Symantic.Parser.Grammar.Combinators.Matchable Symantic.Parser.Grammar.Write.WriteComb instance Symantic.Parser.Grammar.Combinators.Lookable Symantic.Parser.Grammar.Write.WriteComb instance Symantic.Parser.Grammar.Combinators.Foldable Symantic.Parser.Grammar.Write.WriteComb module Symantic.Parser.Grammar.Optimize -- | Pattern-matchable Combinators of the grammar. (repr) -- is not strictly necessary since it's only a phantom type (no -- constructor use it as a value), but having it: -- --
data Comb (repr :: Type -> Type) a [Pure] :: Haskell a -> Comb repr a [Satisfy] :: Satisfiable repr tok => [ErrorItem tok] -> Haskell (tok -> Bool) -> Comb repr tok [Item] :: Satisfiable repr tok => Comb repr tok [Try] :: Comb repr a -> Comb repr a [Look] :: Comb repr a -> Comb repr a [NegLook] :: Comb repr a -> Comb repr () [Eof] :: Comb repr () [:<*>] :: Comb repr (a -> b) -> Comb repr a -> Comb repr b [:<|>] :: Comb repr a -> Comb repr a -> Comb repr a [Empty] :: Comb repr a [Branch] :: Comb repr (Either a b) -> Comb repr (a -> c) -> Comb repr (b -> c) -> Comb repr c [Match] :: Eq a => [Haskell (a -> Bool)] -> [Comb repr b] -> Comb repr a -> Comb repr b -> Comb repr b [ChainPre] :: Comb repr (a -> a) -> Comb repr a -> Comb repr a [ChainPost] :: Comb repr a -> Comb repr (a -> a) -> Comb repr a [Def] :: Name -> Comb repr a -> Comb repr a [Ref] :: Bool -> Name -> Comb repr a infixl 3 :<|> infixl 4 :<*> pattern (:<$>) :: Haskell (a -> b) -> Comb repr a -> Comb repr b infixl 4 :<$> pattern (:$>) :: Comb repr a -> Haskell b -> Comb repr b infixl 4 :$> pattern (:<$) :: Haskell a -> Comb repr b -> Comb repr a infixl 4 :<$ pattern (:*>) :: Comb repr a -> Comb repr b -> Comb repr b infixl 4 :*> pattern (:<*) :: Comb repr a -> Comb repr b -> Comb repr a infixl 4 :<* newtype OptimizeComb letName repr a OptimizeComb :: Comb repr a -> OptimizeComb letName repr a [unOptimizeComb] :: OptimizeComb letName repr a -> Comb repr a optimizeComb :: Trans (OptimizeComb Name repr) repr => OptimizeComb Name repr a -> repr a optimizeCombNode :: Comb repr a -> Comb repr a instance Symantic.Univariant.Trans.Trans (Symantic.Parser.Grammar.Optimize.Comb repr) repr => Symantic.Univariant.Trans.Trans (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) repr instance Symantic.Univariant.Trans.Trans (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) (Symantic.Parser.Grammar.Optimize.Comb repr) instance Symantic.Univariant.Trans.Trans (Symantic.Parser.Grammar.Optimize.Comb repr) (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) instance Symantic.Univariant.Trans.Trans1 (Symantic.Parser.Grammar.Optimize.Comb repr) (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) instance Symantic.Univariant.Trans.Trans2 (Symantic.Parser.Grammar.Optimize.Comb repr) (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) instance Symantic.Univariant.Trans.Trans3 (Symantic.Parser.Grammar.Optimize.Comb repr) (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) instance Symantic.Univariant.Letable.Letable letName (Symantic.Parser.Grammar.Optimize.Comb repr) => Symantic.Univariant.Letable.Letable letName (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) instance Symantic.Parser.Grammar.Combinators.Applicable (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) instance Symantic.Parser.Grammar.Combinators.Alternable (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) instance Symantic.Parser.Grammar.Combinators.Satisfiable repr tok => Symantic.Parser.Grammar.Combinators.Satisfiable (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) tok instance Symantic.Parser.Grammar.Combinators.Selectable (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) instance Symantic.Parser.Grammar.Combinators.Matchable (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) instance Symantic.Parser.Grammar.Combinators.Lookable (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) instance Symantic.Parser.Grammar.Combinators.Foldable (Symantic.Parser.Grammar.Optimize.OptimizeComb letName repr) instance Symantic.Parser.Grammar.Combinators.Applicable (Symantic.Parser.Grammar.Optimize.Comb repr) instance Symantic.Parser.Grammar.Combinators.Alternable (Symantic.Parser.Grammar.Optimize.Comb repr) instance Symantic.Parser.Grammar.Combinators.Selectable (Symantic.Parser.Grammar.Optimize.Comb repr) instance Symantic.Parser.Grammar.Combinators.Matchable (Symantic.Parser.Grammar.Optimize.Comb repr) instance Symantic.Parser.Grammar.Combinators.Foldable (Symantic.Parser.Grammar.Optimize.Comb repr) instance Symantic.Parser.Grammar.Combinators.Satisfiable repr tok => Symantic.Parser.Grammar.Combinators.Satisfiable (Symantic.Parser.Grammar.Optimize.Comb repr) tok instance Symantic.Parser.Grammar.Combinators.Lookable (Symantic.Parser.Grammar.Optimize.Comb repr) instance Symantic.Univariant.Letable.Letable Language.Haskell.TH.Syntax.Name (Symantic.Parser.Grammar.Optimize.Comb repr) instance (Symantic.Parser.Grammar.Combinators.Applicable repr, Symantic.Parser.Grammar.Combinators.Alternable repr, Symantic.Parser.Grammar.Combinators.Selectable repr, Symantic.Parser.Grammar.Combinators.Foldable repr, Symantic.Parser.Grammar.Combinators.Lookable repr, Symantic.Parser.Grammar.Combinators.Matchable repr, Symantic.Univariant.Letable.Letable Language.Haskell.TH.Syntax.Name repr) => Symantic.Univariant.Trans.Trans (Symantic.Parser.Grammar.Optimize.Comb repr) repr instance Symantic.Univariant.Letable.MakeLetName Language.Haskell.TH.Syntax.Name module Symantic.Parser.Grammar.ObserveSharing -- | Like observeSharing but type-binding (letName) to -- Name to help type inference. observeSharing :: ObserveSharing Name repr a -> repr a -- | Interpreter detecting some (Haskell embedded) let definitions -- used at least once and/or recursively, in order to replace them with -- the def and ref combinators. See Type-safe observable -- sharing in Haskell newtype ObserveSharing letName repr a ObserveSharing :: ReaderT (HashSet SharingName) (State (ObserveSharingState letName)) (CleanDefs letName repr a) -> ObserveSharing letName repr a [unObserveSharing] :: ObserveSharing letName repr a -> ReaderT (HashSet SharingName) (State (ObserveSharingState letName)) (CleanDefs letName repr a) instance Data.Hashable.Class.Hashable Language.Haskell.TH.Syntax.Name instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName, Symantic.Parser.Grammar.Combinators.Satisfiable repr tok) => Symantic.Parser.Grammar.Combinators.Satisfiable (Symantic.Univariant.Letable.ObserveSharing letName repr) tok instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName, Symantic.Parser.Grammar.Combinators.Alternable repr) => Symantic.Parser.Grammar.Combinators.Alternable (Symantic.Univariant.Letable.ObserveSharing letName repr) instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName, Symantic.Parser.Grammar.Combinators.Applicable repr) => Symantic.Parser.Grammar.Combinators.Applicable (Symantic.Univariant.Letable.ObserveSharing letName repr) instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName, Symantic.Parser.Grammar.Combinators.Selectable repr) => Symantic.Parser.Grammar.Combinators.Selectable (Symantic.Univariant.Letable.ObserveSharing letName repr) instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName, Symantic.Parser.Grammar.Combinators.Matchable repr) => Symantic.Parser.Grammar.Combinators.Matchable (Symantic.Univariant.Letable.ObserveSharing letName repr) instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName, Symantic.Parser.Grammar.Combinators.Foldable repr, Symantic.Parser.Grammar.Combinators.Applicable repr, Symantic.Parser.Grammar.Combinators.Alternable repr) => Symantic.Parser.Grammar.Combinators.Foldable (Symantic.Univariant.Letable.ObserveSharing letName repr) instance (Symantic.Univariant.Letable.Letable letName repr, Symantic.Univariant.Letable.MakeLetName letName, GHC.Classes.Eq letName, Data.Hashable.Class.Hashable letName, Symantic.Parser.Grammar.Combinators.Lookable repr) => Symantic.Parser.Grammar.Combinators.Lookable (Symantic.Univariant.Letable.ObserveSharing letName repr) instance Symantic.Parser.Grammar.Combinators.Applicable repr => Symantic.Parser.Grammar.Combinators.Applicable (Symantic.Univariant.Letable.CleanDefs letName repr) instance Symantic.Parser.Grammar.Combinators.Alternable repr => Symantic.Parser.Grammar.Combinators.Alternable (Symantic.Univariant.Letable.CleanDefs letName repr) instance Symantic.Parser.Grammar.Combinators.Satisfiable repr tok => Symantic.Parser.Grammar.Combinators.Satisfiable (Symantic.Univariant.Letable.CleanDefs letName repr) tok instance Symantic.Parser.Grammar.Combinators.Selectable repr => Symantic.Parser.Grammar.Combinators.Selectable (Symantic.Univariant.Letable.CleanDefs letName repr) instance Symantic.Parser.Grammar.Combinators.Matchable repr => Symantic.Parser.Grammar.Combinators.Matchable (Symantic.Univariant.Letable.CleanDefs letName repr) instance Symantic.Parser.Grammar.Combinators.Lookable repr => Symantic.Parser.Grammar.Combinators.Lookable (Symantic.Univariant.Letable.CleanDefs letName repr) instance Symantic.Parser.Grammar.Combinators.Foldable repr => Symantic.Parser.Grammar.Combinators.Foldable (Symantic.Univariant.Letable.CleanDefs letName repr) module Symantic.Parser.Grammar.Dump newtype DumpComb a DumpComb :: Tree String -> DumpComb a [unDumpComb] :: DumpComb a -> Tree String dumpComb :: DumpComb a -> DumpComb a instance GHC.Show.Show (Symantic.Parser.Grammar.Dump.DumpComb a) instance Data.String.IsString (Symantic.Parser.Grammar.Dump.DumpComb a) instance GHC.Show.Show letName => Symantic.Univariant.Letable.Letable letName Symantic.Parser.Grammar.Dump.DumpComb instance Symantic.Parser.Grammar.Combinators.Applicable Symantic.Parser.Grammar.Dump.DumpComb instance Symantic.Parser.Grammar.Combinators.Alternable Symantic.Parser.Grammar.Dump.DumpComb instance Symantic.Parser.Grammar.Combinators.Satisfiable Symantic.Parser.Grammar.Dump.DumpComb tok instance Symantic.Parser.Grammar.Combinators.Selectable Symantic.Parser.Grammar.Dump.DumpComb instance Symantic.Parser.Grammar.Combinators.Matchable Symantic.Parser.Grammar.Dump.DumpComb instance Symantic.Parser.Grammar.Combinators.Lookable Symantic.Parser.Grammar.Dump.DumpComb instance Symantic.Parser.Grammar.Combinators.Foldable Symantic.Parser.Grammar.Dump.DumpComb module Symantic.Parser.Grammar type Grammar repr = (Applicable repr, Alternable repr, Letable Name repr, Selectable repr, Matchable repr, Foldable repr, Lookable repr) -- | A usual pipeline to interpret Combinators: -- observeSharing then optimizeComb then a polymorphic -- (repr). grammar :: Grammar repr => ObserveSharing Name (OptimizeComb Name repr) a -> repr a -- | A usual pipeline to show Combinators: observeSharing -- then optimizeComb then dumpComb then show. showGrammar :: ObserveSharing Name (OptimizeComb Name DumpComb) a -> String -- | This class is not for manual usage like usual symantic operators, here -- def and ref are introduced by observeSharing. class Letable letName repr -- | (def letName x) let-binds (letName) to be -- equal to (x). def :: Letable letName repr => letName -> repr a -> repr a -- | (ref isRec letName) is a reference to -- (letName). (isRec) is True iif. this -- reference is recursive, ie. is reachable within its -- definition. ref :: Letable letName repr => Bool -> letName -> repr a -- | (def letName x) let-binds (letName) to be -- equal to (x). def :: (Letable letName repr, Liftable1 repr) => Letable letName (Output repr) => letName -> repr a -> repr a -- | (ref isRec letName) is a reference to -- (letName). (isRec) is True iif. this -- reference is recursive, ie. is reachable within its -- definition. ref :: (Letable letName repr, Liftable repr) => Letable letName (Output repr) => Bool -> letName -> repr a module Symantic.Parser.Machine.Instructions -- | Instructions for the Machine. data Instr input valueStack (failStack :: Peano) returnValue -- | (Push x k) pushes (x) on the -- valueStack and continues with the next Instruction -- (k). [Push] :: InstrPure v -> Instr inp (v : vs) es ret -> Instr inp vs es ret -- | (Pop k) pushes (x) on the -- valueStack. [Pop] :: Instr inp vs es ret -> Instr inp (v : vs) es ret -- | (LiftI2 f k) pops two values from the -- valueStack, and pushes the result of (f) applied to -- them. [LiftI2] :: InstrPure (x -> y -> z) -> Instr inp (z : vs) es ret -> Instr inp (y : (x : vs)) es ret -- | (Fail) raises an error from the failStack. [Fail] :: [ErrorItem (InputToken inp)] -> Instr inp vs ('Succ es) ret -- | (PopFail k) removes a FailHandler from the -- failStack and continues with the next Instruction -- (k). [PopFail] :: Instr inp vs es ret -> Instr inp vs ('Succ es) ret -- | (CatchFail l r) tries the (l) -- Instruction in a new failure scope such that if (l) -- raises a failure, it is caught, then the input is pushed as it was -- before trying (l) on the valueStack, and the control -- flow goes on with the (r) Instruction. [CatchFail] :: Instr inp vs ('Succ es) ret -> Instr inp (Cursor inp : vs) es ret -> Instr inp vs es ret -- | (LoadInput k) removes the input from the -- valueStack and continues with the next Instruction -- (k) using that input. [LoadInput] :: Instr inp vs es r -> Instr inp (Cursor inp : vs) es r -- | (PushInput k) pushes the input (inp) on the -- valueStack and continues with the next Instruction -- (k). [PushInput] :: Instr inp (Cursor inp : vs) es ret -> Instr inp vs es ret -- | (Case l r). [Case] :: Instr inp (x : vs) es r -> Instr inp (y : vs) es r -> Instr inp (Either x y : vs) es r -- | (Swap k) pops two values on the valueStack, -- pushes the first popped-out, then the second, and continues with the -- next Instruction (k). [Swap] :: Instr inp (x : (y : vs)) es r -> Instr inp (y : (x : vs)) es r -- | (Choices ps bs d). [Choices] :: [InstrPure (v -> Bool)] -> [Instr inp vs es ret] -> Instr inp vs es ret -> Instr inp (v : vs) es ret -- | (Subroutine n v k) binds the LetName -- (n) to the Instr'uctions (v), Calls -- (n) and continues with the next Instruction -- (k). [Subroutine] :: LetName v -> Instr inp '[] ('Succ 'Zero) v -> Instr inp vs ('Succ es) ret -> Instr inp vs ('Succ es) ret -- | (Jump n k) pass the control-flow to the -- Subroutine named (n). [Jump] :: LetName ret -> Instr inp '[] ('Succ es) ret -- | (Call n k) pass the control-flow to the -- Subroutine named (n), and when it Returns, -- continues with the next Instruction (k). [Call] :: LetName v -> Instr inp (v : vs) ('Succ es) ret -> Instr inp vs ('Succ es) ret -- | (Ret) returns the value stored in a singleton -- valueStack. [Ret] :: Instr inp '[ret] es ret -- | (Read expected p k) reads a Char (c) -- from the input, if (p c) is True then -- continues with the next Instruction (k) on, otherwise -- Fail. [Read] :: [ErrorItem (InputToken inp)] -> InstrPure (InputToken inp -> Bool) -> Instr inp (InputToken inp : vs) ('Succ es) ret -> Instr inp vs ('Succ es) ret [DefJoin] :: LetName v -> Instr inp (v : vs) es ret -> Instr inp vs es ret -> Instr inp vs es ret [RefJoin] :: LetName v -> Instr inp (v : vs) es ret data InstrPure a [InstrPureHaskell] :: Haskell a -> InstrPure a [InstrPureSameOffset] :: Cursorable cur => InstrPure (cur -> cur -> Bool) newtype LetName a LetName :: Name -> LetName a [unLetName] :: LetName a -> Name type Executable repr = (Stackable repr, Branchable repr, Failable repr, Inputable repr, Routinable repr, Joinable repr) class Stackable (repr :: Type -> [Type] -> Peano -> Type -> Type) push :: Stackable repr => InstrPure v -> repr inp (v : vs) n ret -> repr inp vs n ret pop :: Stackable repr => repr inp vs n ret -> repr inp (v : vs) n ret liftI2 :: Stackable repr => InstrPure (x -> y -> z) -> repr inp (z : vs) es ret -> repr inp (y : (x : vs)) es ret swap :: Stackable repr => repr inp (x : (y : vs)) n r -> repr inp (y : (x : vs)) n r class Branchable (repr :: Type -> [Type] -> Peano -> Type -> Type) case_ :: Branchable repr => repr inp (x : vs) n r -> repr inp (y : vs) n r -> repr inp (Either x y : vs) n r choices :: Branchable repr => [InstrPure (v -> Bool)] -> [repr inp vs es ret] -> repr inp vs es ret -> repr inp (v : vs) es ret class Failable (repr :: Type -> [Type] -> Peano -> Type -> Type) fail :: Failable repr => [ErrorItem (InputToken inp)] -> repr inp vs ('Succ es) ret popFail :: Failable repr => repr inp vs es ret -> repr inp vs ('Succ es) ret catchFail :: Failable repr => repr inp vs ('Succ es) ret -> repr inp (Cursor inp : vs) es ret -> repr inp vs es ret class Inputable (repr :: Type -> [Type] -> Peano -> Type -> Type) loadInput :: Inputable repr => repr inp vs es r -> repr inp (Cursor inp : vs) es r pushInput :: Inputable repr => repr inp (Cursor inp : vs) es ret -> repr inp vs es ret class Routinable (repr :: Type -> [Type] -> Peano -> Type -> Type) subroutine :: Routinable repr => LetName v -> repr inp '[] ('Succ 'Zero) v -> repr inp vs ('Succ es) ret -> repr inp vs ('Succ es) ret call :: Routinable repr => LetName v -> repr inp (v : vs) ('Succ es) ret -> repr inp vs ('Succ es) ret ret :: Routinable repr => repr inp '[ret] es ret jump :: Routinable repr => LetName ret -> repr inp '[] ('Succ es) ret class Joinable (repr :: Type -> [Type] -> Peano -> Type -> Type) defJoin :: Joinable repr => LetName v -> repr inp (v : vs) es ret -> repr inp vs es ret -> repr inp vs es ret refJoin :: Joinable repr => LetName v -> repr inp (v : vs) es ret class Readable (repr :: Type -> [Type] -> Peano -> Type -> Type) (tok :: Type) read :: (Readable repr tok, tok ~ InputToken inp) => [ErrorItem tok] -> InstrPure (tok -> Bool) -> repr inp (tok : vs) ('Succ es) ret -> repr inp vs ('Succ es) ret -- | Type-level natural numbers, using the Peano recursive encoding. data Peano Zero :: Peano Succ :: Peano -> Peano -- | (Fmap f k). pattern Fmap :: InstrPure (x -> y) -> Instr inp (y : xs) es ret -> Instr inp (x : xs) es ret -- | (App k) pops (x) and (x2y) from the -- valueStack, pushes (x2y x) and continues with the -- next Instruction (k). pattern App :: Instr inp (y : vs) es ret -> Instr inp (x : ((x -> y) : vs)) es ret -- | (If ok ko) pops a Bool from the -- valueStack and continues either with the Instruction -- (ok) if it is True or (ko) otherwise. pattern If :: Instr inp vs es ret -> Instr inp vs es ret -> Instr inp (Bool : vs) es ret -- | Making the control-flow explicit. data Machine inp v Machine :: (forall vs es ret. Instr inp (v : vs) ('Succ es) ret -> Instr inp vs ('Succ es) ret) -> Machine inp v [unMachine] :: Machine inp v -> forall vs es ret. Instr inp (v : vs) ('Succ es) ret -> Instr inp vs ('Succ es) ret runMachine :: forall inp v es repr. Executable repr => Readable repr (InputToken inp) => Machine inp v -> repr inp '[] ('Succ es) v -- | If no input has been consumed by the failing alternative then continue -- with the given continuation. Otherwise, propagate the Failure. failIfConsumed :: Cursorable (Cursor inp) => Instr inp vs ('Succ es) ret -> Instr inp (Cursor inp : vs) ('Succ es) ret -- | (makeJoin k f) factorizes (k) in -- (f), by introducing a DefJoin if necessary, and -- passing the corresponding RefJoin to (f), or -- (k) as is when factorizing is useless. makeJoin :: Instr inp (v : vs) es ret -> (Instr inp (v : vs) es ret -> Instr inp vs es ret) -> Instr inp vs es ret instance GHC.Show.Show (Symantic.Parser.Machine.Instructions.LetName a) instance GHC.Classes.Eq (Symantic.Parser.Machine.Instructions.LetName a) instance Symantic.Parser.Grammar.Combinators.Applicable (Symantic.Parser.Machine.Instructions.Machine inp) instance Symantic.Parser.Machine.Input.Cursorable (Symantic.Parser.Machine.Input.Cursor inp) => Symantic.Parser.Grammar.Combinators.Alternable (Symantic.Parser.Machine.Instructions.Machine inp) instance (tok GHC.Types.~ Symantic.Parser.Machine.Input.InputToken inp) => Symantic.Parser.Grammar.Combinators.Satisfiable (Symantic.Parser.Machine.Instructions.Machine inp) tok instance Symantic.Parser.Grammar.Combinators.Selectable (Symantic.Parser.Machine.Instructions.Machine inp) instance Symantic.Parser.Grammar.Combinators.Matchable (Symantic.Parser.Machine.Instructions.Machine inp) instance (GHC.Classes.Ord (Symantic.Parser.Machine.Input.InputToken inp), Symantic.Parser.Machine.Input.Cursorable (Symantic.Parser.Machine.Input.Cursor inp)) => Symantic.Parser.Grammar.Combinators.Lookable (Symantic.Parser.Machine.Instructions.Machine inp) instance Symantic.Univariant.Letable.Letable Language.Haskell.TH.Syntax.Name (Symantic.Parser.Machine.Instructions.Machine inp) instance Symantic.Parser.Machine.Input.Cursorable (Symantic.Parser.Machine.Input.Cursor inp) => Symantic.Parser.Grammar.Combinators.Foldable (Symantic.Parser.Machine.Instructions.Machine inp) instance (Symantic.Parser.Machine.Instructions.Executable repr, Symantic.Parser.Machine.Instructions.Readable repr (Symantic.Parser.Machine.Input.InputToken inp)) => Symantic.Univariant.Trans.Trans (Symantic.Parser.Machine.Instructions.Instr inp vs es) (repr inp vs es) instance GHC.Show.Show (Symantic.Parser.Machine.Instructions.InstrPure a) instance Symantic.Univariant.Trans.Trans Symantic.Parser.Machine.Instructions.InstrPure Language.Haskell.TH.Lib.Internal.CodeQ module Symantic.Parser.Machine.Generate -- | Generate the CodeQ parsing the input. newtype Gen inp vs es a Gen :: (GenCtx inp vs es a -> CodeQ (Either (ParsingError inp) a)) -> Gen inp vs es a [unGen] :: Gen inp vs es a -> GenCtx inp vs es a -> CodeQ (Either (ParsingError inp) a) data ParsingError inp ParsingErrorStandard :: Offset -> Maybe (InputToken inp) -> Set (ErrorItem (InputToken inp)) -> ParsingError inp [parsingErrorOffset] :: ParsingError inp -> Offset [parsingErrorUnexpected] :: ParsingError inp -> Maybe (InputToken inp) [parsingErrorExpecting] :: ParsingError inp -> Set (ErrorItem (InputToken inp)) type Offset = Int type Cont inp v a = Cursor inp -> [ErrorItem (InputToken inp)] -> v -> Cursor inp -> Either (ParsingError inp) a type SubRoutine inp v a = Cont inp v a -> Cursor inp -> FailHandler inp a -> Either (ParsingError inp) a type FailHandler inp a = Cursor inp -> Cursor inp -> [ErrorItem (InputToken inp)] -> Either (ParsingError inp) a -- | (generate input mach) generates -- TemplateHaskell code parsing given input according to -- given machine. generate :: forall inp ret. Ord (InputToken inp) => Show (InputToken inp) => Lift (InputToken inp) => Input inp => CodeQ inp -> Show (Cursor inp) => Gen inp '[] ('Succ 'Zero) ret -> CodeQ (Either (ParsingError inp) ret) -- | This is a context only present at compile-time. data GenCtx inp vs (es :: Peano) a GenCtx :: ValueStack vs -> FailStack inp es a -> CodeQ (Cont inp a a) -> CodeQ (Cursor inp) -> CodeQ (Cursor inp -> Bool) -> CodeQ (Cursor inp -> (# InputToken inp, Cursor inp #)) -> CodeQ (Cursor inp) -> CodeQ [ErrorItem (InputToken inp)] -> GenCtx inp vs es :: Peano a [valueStack] :: GenCtx inp vs es :: Peano a -> ValueStack vs [failStack] :: GenCtx inp vs es :: Peano a -> FailStack inp es a [retCode] :: GenCtx inp vs es :: Peano a -> CodeQ (Cont inp a a) [input] :: GenCtx inp vs es :: Peano a -> CodeQ (Cursor inp) [moreInput] :: GenCtx inp vs es :: Peano a -> CodeQ (Cursor inp -> Bool) [nextInput] :: GenCtx inp vs es :: Peano a -> CodeQ (Cursor inp -> (# InputToken inp, Cursor inp #)) [farthestInput] :: GenCtx inp vs es :: Peano a -> CodeQ (Cursor inp) [farthestExpecting] :: GenCtx inp vs es :: Peano a -> CodeQ [ErrorItem (InputToken inp)] data ValueStack vs [ValueStackEmpty] :: ValueStack '[] [ValueStackCons] :: {valueStackHead :: CodeQ v, valueStackTail :: ValueStack vs} -> ValueStack (v : vs) data FailStack inp es a [FailStackEmpty] :: FailStack inp 'Zero a [FailStackCons] :: {failStackHead :: CodeQ (FailHandler inp a), failStackTail :: FailStack inp es a} -> FailStack inp ('Succ es) a suspend :: Gen inp (v : vs) es a -> GenCtx inp vs es a -> CodeQ (Cont inp v a) resume :: CodeQ (Cont inp v a) -> Gen inp (v : vs) es a sat :: forall inp vs es a. Ord (InputToken inp) => Lift (InputToken inp) => CodeQ (InputToken inp -> Bool) -> Gen inp (InputToken inp : vs) ('Succ es) a -> Gen inp vs ('Succ es) a -> Gen inp vs ('Succ es) a emitLengthCheck :: Lift (InputToken inp) => Int -> Gen inp vs es a -> Gen inp vs es a -> Gen inp vs es a liftCode :: InstrPure a -> CodeQ a liftCode1 :: InstrPure (a -> b) -> CodeQ a -> CodeQ b liftCode2 :: InstrPure (a -> b -> c) -> CodeQ a -> CodeQ b -> CodeQ c instance GHC.Show.Show (Symantic.Parser.Machine.Input.InputToken inp) => GHC.Show.Show (Symantic.Parser.Machine.Generate.ParsingError inp) instance Symantic.Parser.Machine.Instructions.Stackable Symantic.Parser.Machine.Generate.Gen instance Symantic.Parser.Machine.Instructions.Branchable Symantic.Parser.Machine.Generate.Gen instance Symantic.Parser.Machine.Instructions.Failable Symantic.Parser.Machine.Generate.Gen instance Symantic.Parser.Machine.Instructions.Inputable Symantic.Parser.Machine.Generate.Gen instance Symantic.Parser.Machine.Instructions.Routinable Symantic.Parser.Machine.Generate.Gen instance Symantic.Parser.Machine.Instructions.Joinable Symantic.Parser.Machine.Generate.Gen instance Symantic.Parser.Machine.Instructions.Readable Symantic.Parser.Machine.Generate.Gen GHC.Types.Char module Symantic.Parser.Machine.Dump newtype DumpInstr inp (vs :: [Type]) (es :: Peano) a DumpInstr :: (Forest String -> Forest String) -> DumpInstr inp vs :: [Type] es :: Peano a [unDumpInstr] :: DumpInstr inp vs :: [Type] es :: Peano a -> Forest String -> Forest String dumpInstr :: DumpInstr inp vs es a -> DumpInstr inp vs es a -- | Helper to dump a command. dumpInstrCmd :: String -> Forest String -> Tree String -- | Helper to dump an argument. dumpInstrArg :: String -> Forest String -> Tree String instance GHC.Show.Show (Symantic.Parser.Machine.Dump.DumpInstr inp vs es a) instance Data.String.IsString (Symantic.Parser.Machine.Dump.DumpInstr inp vs es a) instance Symantic.Parser.Machine.Instructions.Stackable Symantic.Parser.Machine.Dump.DumpInstr instance Symantic.Parser.Machine.Instructions.Branchable Symantic.Parser.Machine.Dump.DumpInstr instance Symantic.Parser.Machine.Instructions.Failable Symantic.Parser.Machine.Dump.DumpInstr instance Symantic.Parser.Machine.Instructions.Inputable Symantic.Parser.Machine.Dump.DumpInstr instance Symantic.Parser.Machine.Instructions.Routinable Symantic.Parser.Machine.Dump.DumpInstr instance Symantic.Parser.Machine.Instructions.Joinable Symantic.Parser.Machine.Dump.DumpInstr instance Symantic.Parser.Machine.Instructions.Readable Symantic.Parser.Machine.Dump.DumpInstr inp module Symantic.Parser.Machine type Parser inp = ObserveSharing Name (OptimizeComb Name (Machine inp)) machine :: forall inp repr 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 module Symantic.Parser runParser :: forall inp a. Ord (InputToken inp) => Show (InputToken inp) => Lift (InputToken inp) => Input inp => Readable Gen (InputToken inp) => Parser inp a -> CodeQ (inp -> Either (ParsingError inp) a)