1 {-# LANGUAGE PatternSynonyms #-}
2 {-# LANGUAGE TemplateHaskell #-}
3 {-# LANGUAGE ViewPatterns #-}
4 {-# LANGUAGE UndecidableInstances #-}
5 module Symantic.Parser.Grammar.Optimizations where
7 import Data.Bool (Bool)
8 import Data.Char (Char)
9 import Data.Either (Either(..), either)
10 import Data.Eq (Eq(..))
11 import Data.Maybe (Maybe(..))
13 import Prelude (undefined)
14 import qualified Data.Function as Function
15 import qualified Prelude as Pre
17 import Symantic.Base.Univariant
18 import Symantic.Parser.Grammar.Combinators
19 import Symantic.Parser.Staging hiding (Runtimeable(..), OptRuntime(..))
20 import qualified Symantic.Parser.Staging as S
21 import qualified Language.Haskell.TH.Syntax as TH
24 data OptGram repr a where
25 Pure :: S.OptRuntime S.Runtime a -> OptGram repr a
26 Satisfy :: S.Runtime (Char -> Bool) -> OptGram repr Char
27 Item :: OptGram repr Char
28 Try :: OptGram repr a -> OptGram repr a
29 Look :: OptGram repr a -> OptGram repr a
30 NegLook :: OptGram repr a -> OptGram repr ()
31 (:<*>) :: OptGram repr (a -> b) -> OptGram repr a -> OptGram repr b
32 (:<|>) :: OptGram repr a -> OptGram repr a -> OptGram repr a
33 Empty :: OptGram repr a
34 Branch :: OptGram repr (Either a b) -> OptGram repr (a -> c) -> OptGram repr (b -> c) -> OptGram repr c
35 Match :: Eq a => [S.Runtime (a -> Bool)] -> [OptGram repr b] -> OptGram repr a -> OptGram repr b -> OptGram repr b
36 ChainPre :: OptGram repr (a -> a) -> OptGram repr a -> OptGram repr a
37 ChainPost :: OptGram repr a -> OptGram repr (a -> a) -> OptGram repr a
39 pattern (:<$>) :: S.OptRuntime S.Runtime (a -> b) -> OptGram repr a -> OptGram repr b
40 pattern (:$>) :: OptGram repr a -> S.OptRuntime S.Runtime b -> OptGram repr b
41 pattern (:<$) :: S.OptRuntime S.Runtime a -> OptGram repr b -> OptGram repr a
42 pattern (:*>) :: OptGram repr a -> OptGram repr b -> OptGram repr b
43 pattern (:<*) :: OptGram repr a -> OptGram repr b -> OptGram repr a
44 pattern x :<$> p = Pure x :<*> p
45 pattern p :$> x = p :*> Pure x
46 pattern x :<$ p = Pure x :<* p
47 pattern x :<* p = S.Const :<$> x :<*> p
48 pattern p :*> x = S.Id :<$ p :<*> x
51 infixl 4 :<*>, :<*, :*>
52 infixl 4 :<$>, :<$, :$>
54 instance Applicable (OptGram Runtime) where
55 pure = Pure Function.. S.OptRuntime
57 instance Alternable (OptGram repr) where
61 instance Selectable (OptGram repr) where
63 instance Matchable (OptGram repr) where
65 instance Foldable (OptGram repr) where
68 instance Charable (OptGram repr) where
70 instance Lookable (OptGram repr) where
73 type instance Unlift (OptGram repr) = repr
82 ) => Unliftable (OptGram repr) where
84 Pure a -> pure (unlift a)
85 Satisfy p -> satisfy p
87 Try x -> try (unlift x)
88 Look x -> look (unlift x)
89 NegLook x -> negLook (unlift x)
90 x :<*> y -> unlift x <*> unlift y
91 x :<|> y -> unlift x <|> unlift y
93 Branch lr l r -> branch (unlift lr) (unlift l) (unlift r)
94 Match cs bs a b -> conditional cs (unlift Pre.<$> bs) (unlift a) (unlift b)
97 OptGram repr a -> OptGram repr a
99 -- Applicable Right Absorption Law
100 Empty :<*> _ -> Empty
103 -- Applicable Failure Weakening Law
104 u :<*> Empty -> optGram (u :*> Empty)
105 u :<* Empty -> optGram (u :*> Empty)
106 -- Branch Absorption Law
107 Branch Empty _ _ -> empty
108 -- Branch Weakening Law
109 Branch b Empty Empty -> optGram (b :*> Empty)
111 -- Applicable Identity Law
113 -- Flip const optimisation
114 S.Flip S.:@ S.Const :<$> u -> optGram (u :*> Pure S.Id)
116 f :<$> Pure x -> Pure (f S.:@ x)
117 -- Functor Composition Law
118 -- (a shortcut that could also have been be caught
119 -- by the Composition Law and Homomorphism law)
120 f :<$> (g :<$> p) -> optGram ((S.:.) S.:@ f S.:@ g :<$> p)
122 u :<*> (v :<*> w) -> optGram (optGram (optGram ((S.:.) :<$> u) :<*> v) :<*> w)
124 S.Flip S.:@ S.Const :<$> p :<*> q -> p :*> q
126 S.Const :<$> p :<*> q -> p :<* q
127 -- Reassociation Law 1
128 (u :*> v) :<*> w -> optGram (u :*> (optGram (v :<*> w)))
130 u :<*> Pure x -> optGram (S.Flip S.:@ (S.:$) S.:@ x :<$> u)
131 -- Right Absorption Law
132 (_ :<$> p) :*> q -> p :*> q
133 -- Left Absorption Law
134 p :<* (_ :<$> q) -> p :<* q
135 -- Reassociation Law 2
136 u :<*> (v :<* w) -> optGram (optGram (u :<*> v) :<* w)
137 -- Reassociation Law 3
138 u :<*> (v :$> x) -> optGram (optGram (u :<*> Pure x) :<* v)
147 (u :<|> v) :<|> w -> u :<|> optGram (v :<|> w)
152 (u :$> _) :*> v -> u :*> v
154 u :*> (v :*> w) -> optGram (optGram (u :*> v) :*> w)
158 u :<* (v :$> _) -> optGram (u :<* v)
160 x :<$ u -> optGram (u :$> x)
162 (u :<* v) :<* w -> optGram (u :<* optGram (v :<* w))
168 -- Pure negative-lookahead
169 NegLook Pure{} -> Empty
171 -- Dead negative-lookahead
172 NegLook Empty -> Pure S.unit
173 -- Double Negation Law
174 NegLook (NegLook p) -> optGram (Look (Try p) :*> Pure S.unit)
175 -- Zero Consumption Law
176 NegLook (Try p) -> optGram (NegLook p)
178 Look (Look p) -> Look p
179 -- Right Identity Law
180 NegLook (Look p) -> optGram (NegLook p)
183 Look (NegLook p) -> NegLook p
185 NegLook (Try p :<|> q) -> optGram (optGram (NegLook p) :*> optGram (NegLook q))
186 -- Distributivity Law
187 Look p :<|> Look q -> optGram (Look (optGram (Try p :<|> q)))
189 Look (p :$> x) -> optGram (optGram (Look p) :$> x)
191 Look (f :<$> p) -> optGram (f :<$> optGram (Look p))
193 p :<*> NegLook q -> optGram (optGram (p :<*> Pure S.unit) :<* NegLook q)
195 NegLook (p :$> _) -> optGram (NegLook p)
197 NegLook (_ :<$> p) -> optGram (NegLook p)
199 Try (p :$> x) -> optGram (optGram (Try p) :$> x)
201 Try (f :<$> p) -> optGram (f :<$> optGram (Try p))
203 -- pure Left/Right laws
204 Branch (Pure (unlift -> lr)) l r ->
206 Left e -> optGram (l :<*> Pure (S.OptRuntime (Runtime (Eval e) c)))
207 where c = Code [|| case $$(getCode lr) of Left x -> x ||]
208 Right e -> optGram (r :<*> Pure (S.OptRuntime (Runtime (Eval e) c)))
209 where c = Code [|| case $$(getCode lr) of Right x -> x ||]
210 -- Generalised Identity law
211 Branch b (Pure (unlift -> l)) (Pure (unlift -> r)) ->
212 optGram (S.OptRuntime (Runtime e c) :<$> b)
214 e = Eval (either (getEval l) (getEval r))
215 c = Code [|| either $$(getCode l) $$(getCode r) ||]
217 Branch (x :*> y) p q ->
218 optGram (x :*> optGram (Branch y p q))
219 -- Negated Branch law
221 Branch (Pure (S.OptRuntime (Runtime e c)) :<*> b) Empty l
223 e = Eval (either Right Left)
224 c = Code [||either Right Left||]
226 Branch (Branch b Empty (Pure (unlift -> lr))) Empty br ->
227 optGram (Branch (optGram (Pure (S.OptRuntime (Runtime (Eval e) c)) :<*> b)) Empty br)
230 e (Right r) = case getEval lr r of
233 c = Code [|| \case Left{} -> Left ()
234 Right r -> case $$(getCode lr) r of
236 Right rr -> Right rr ||]
237 -- Distributivity Law
238 f :<$> Branch b l r -> optGram (Branch b (optGram ((S..@) (S..) f :<$> l))
239 (optGram ((S..@) (S..) f :<$> r)))