1 {-# LANGUAGE PatternSynonyms #-}
2 {-# LANGUAGE TemplateHaskell #-}
3 {-# LANGUAGE ViewPatterns #-}
4 module Symantic.Parser.Grammar.Optimizations where
6 import Data.Bool (Bool)
7 import Data.Char (Char)
8 import Data.Either (Either(..), either)
9 import Prelude (undefined)
10 import qualified Data.Function as Function
11 import Data.Eq (Eq(..))
13 import Data.Maybe (Maybe(..))
15 import Symantic.Base.Univariant
16 import Symantic.Parser.Grammar.Combinators
17 import Symantic.Parser.Staging hiding (Runtimeable(..), OptRuntime(..))
18 import qualified Symantic.Parser.Staging as S
19 import qualified Language.Haskell.TH.Syntax as TH
22 data OptGram repr a where
23 Pure :: Pure repr a -> OptGram repr a
24 Satisfy :: Pure repr (Char -> Bool) -> OptGram repr Char
25 Try :: OptGram repr a -> OptGram repr a
26 Look :: OptGram repr a -> OptGram repr a
27 NegLook :: OptGram repr a -> OptGram repr ()
28 (:<*>) :: OptGram repr (a -> b) -> OptGram repr a -> OptGram repr b
29 (:<*) :: OptGram repr a -> OptGram repr b -> OptGram repr a
30 (:*>) :: OptGram repr a -> OptGram repr b -> OptGram repr b
31 (:<|>) :: OptGram repr a -> OptGram repr a -> OptGram repr a
32 Empty :: OptGram repr a
33 Branch :: OptGram repr (Either a b) -> OptGram repr (a -> c) -> OptGram repr (b -> c) -> OptGram repr c
35 pattern (:<$>) :: Pure repr (a -> b) -> OptGram repr a -> OptGram repr b
36 pattern (:$>) :: OptGram repr a -> Pure repr b -> OptGram repr b
37 pattern (:<$) :: Pure repr a -> OptGram repr b -> OptGram repr a
38 pattern x :<$> p = Pure x :<*> p
39 pattern p :$> x = p :*> Pure x
40 pattern x :<$ p = Pure x :<* p
43 infixl 4 :<*>, :<*, :*>
44 infixl 4 :<$>, :<$, :$>
46 instance Applicable (OptGram repr) where
47 type Pure (OptGram repr) = Pure repr
49 (<$>) f = (Pure f :<*>)
53 instance Alternable (OptGram repr) where
57 instance Selectable (OptGram repr) where
59 instance Charable (OptGram repr) where
61 instance Lookable (OptGram repr) where
64 type instance Unlift (OptGram repr) = repr
71 ) => Unliftable (OptGram repr) where
74 Satisfy p -> satisfy p
75 Try x -> try (unlift x)
76 Look x -> look (unlift x)
77 NegLook x -> negLook (unlift x)
78 x :<*> y -> unlift x <*> unlift y
79 x :<* y -> unlift x <* unlift y
80 x :*> y -> unlift x *> unlift y
81 x :<|> y -> unlift x <|> unlift y
83 Branch lr l r -> branch (unlift lr) (unlift l) (unlift r)
86 Pure repr ~ S.OptRuntime Runtime =>
87 OptGram repr a -> OptGram repr a
89 -- Applicable Right Absorption Law
93 -- Applicable Failure Weakening Law
94 u :<*> Empty -> optGram (u :*> Empty)
95 u :<* Empty -> optGram (u :*> Empty)
96 -- Branch Absorption Law
97 Branch Empty _ _ -> empty
98 -- Branch Weakening Law
99 Branch b Empty Empty -> optGram (b :*> Empty)
101 -- Applicable Identity Law
103 -- Flip const optimisation
104 S.Flip S.:@ S.Const :<$> u -> optGram (u :*> Pure S.Id)
106 f :<$> Pure x -> Pure (f S.:@ x)
107 -- Functor Composition Law
108 -- (a shortcut that could also have been be caught
109 -- by the Composition Law and Homomorphism law)
110 f :<$> (g :<$> p) -> optGram ((S.:.) S.:@ f S.:@ g :<$> p)
112 u :<*> (v :<*> w) -> optGram (optGram (optGram ((S.:.) :<$> u) :<*> v) :<*> w)
114 S.Flip S.:@ S.Const :<$> p :<*> q -> p :*> q
116 S.Const :<$> p :<*> q -> p :<* q
117 -- Reassociation Law 1
118 (u :*> v) :<*> w -> optGram (u :*> (optGram (v :<*> w)))
120 u :<*> Pure x -> optGram (S.Flip S.:@ (S.:$) S.:@ x :<$> u)
121 -- Right Absorption Law
122 (_ :<$> p) :*> q -> p :*> q
123 -- Left Absorption Law
124 p :<* (_ :<$> q) -> p :<* q
125 -- Reassociation Law 2
126 u :<*> (v :<* w) -> optGram (optGram (u :<*> v) :<* w)
127 -- Reassociation Law 3
128 u :<*> (v :$> x) -> optGram (optGram (u :<*> Pure x) :<* v)
137 (u :<|> v) :<|> w -> u :<|> optGram (v :<|> w)
142 (u :$> _) :*> v -> u :*> v
144 u :*> (v :*> w) -> optGram (optGram (u :*> v) :*> w)
148 u :<* (v :$> _) -> optGram (u :<* v)
150 x :<$ u -> optGram (u :$> x)
152 (u :<* v) :<* w -> optGram (u :<* optGram (v :<* w))
158 -- Pure negative-lookahead
159 NegLook Pure{} -> Empty
161 -- Dead negative-lookahead
162 NegLook Empty -> Pure S.unit
163 -- Double Negation Law
164 NegLook (NegLook p) -> optGram (Look (Try p) :*> Pure S.unit)
165 -- Zero Consumption Law
166 NegLook (Try p) -> optGram (NegLook p)
168 Look (Look p) -> Look p
169 -- Right Identity Law
170 NegLook (Look p) -> optGram (NegLook p)
173 Look (NegLook p) -> NegLook p
175 NegLook (Try p :<|> q) -> optGram (optGram (NegLook p) :*> optGram (NegLook q))
176 -- Distributivity Law
177 Look p :<|> Look q -> optGram (Look (optGram (Try p :<|> q)))
179 Look (p :$> x) -> optGram (optGram (Look p) :$> x)
181 Look (f :<$> p) -> optGram (f :<$> optGram (Look p))
183 p :<*> NegLook q -> optGram (optGram (p :<*> Pure S.unit) :<* NegLook q)
185 NegLook (p :$> _) -> optGram (NegLook p)
187 NegLook (_ :<$> p) -> optGram (NegLook p)
189 Try (p :$> x) -> optGram (optGram (Try p) :$> x)
191 Try (f :<$> p) -> optGram (f :<$> optGram (Try p))
193 -- pure Left/Right laws
194 Branch (Pure (unlift -> lr)) l r ->
196 Left e -> optGram (l :<*> Pure (S.OptRuntime (Runtime (Eval e) c)))
197 where c = Code [|| case $$(getCode lr) of Left x -> x ||]
198 Right e -> optGram (r :<*> Pure (S.OptRuntime (Runtime (Eval e) c)))
199 where c = Code [|| case $$(getCode lr) of Right x -> x ||]
200 -- Generalised Identity law
201 Branch b (Pure (unlift -> l)) (Pure (unlift -> r)) ->
202 optGram (S.OptRuntime (Runtime e c) :<$> b)
204 e = Eval (either (getEval l) (getEval r))
205 c = Code [|| either $$(getCode l) $$(getCode r) ||]
207 Branch (x :*> y) p q ->
208 optGram (x :*> optGram (Branch y p q))
209 -- Negated Branch law
211 Branch (Pure (S.OptRuntime (Runtime e c)) :<*> b) Empty l
213 e = Eval (either Right Left)
214 c = Code [||either Right Left||]
216 Branch (Branch b Empty (Pure (unlift -> lr))) Empty br ->
217 optGram (Branch (optGram (Pure (S.OptRuntime (Runtime (Eval e) c)) :<*> b)) Empty br)
220 e (Right r) = case getEval lr r of
223 c = Code [|| \case Left{} -> Left ()
224 Right r -> case $$(getCode lr) r of
226 Right rr -> Right rr ||]
227 -- Distributivity Law
228 f :<$> Branch b l r -> optGram (Branch b (optGram ((S..@) (S..) f :<$> l))
229 (optGram ((S..@) (S..) f :<$> r)))