1 {-# LANGUAGE TemplateHaskell #-}
2 module Symantic.Parser.Staging where
4 import Data.Bool (Bool)
5 import Data.Char (Char)
7 import Data.Functor.Identity (Identity(..))
8 import Language.Haskell.TH (TExpQ)
9 import qualified Data.Eq as Eq
10 import qualified Data.Function as Function
12 import Symantic.Base.Univariant
15 data Runtime a = Runtime
17 -- ^ The value of the runtime code,
18 -- kept along to be made available to the optimizer.
20 -- ^ An AST of a runtime value.
22 getEval :: Runtime a -> a
23 getEval = unEval Function.. eval
24 getCode :: Runtime a -> TExpQ a
25 getCode = unCode Function.. code
26 type instance Unlift Runtime = Runtime
27 instance Liftable Runtime where
30 instance Unliftable Runtime where
35 newtype Eval a = Eval { unEval :: a }
36 type instance Unlift Eval = Eval
37 instance Liftable Eval where
40 instance Unliftable Eval where
45 newtype Code a = Code { unCode :: TExpQ a }
46 type instance Unlift Code = Code
47 instance Liftable Code where
50 instance Unliftable Code where
54 -- * Class 'Runtimeable'
55 -- | Final encoding of some Runtimeable functions
56 -- useful for some optimizations in 'optGram'.
57 class Runtimeable (app :: * -> *) where
58 runtime :: Unlift app a -> app a
59 (.) :: app ((b->c) -> (a->b) -> a -> c)
60 ($) :: app ((a->b) -> a -> b)
61 (.@) :: app (a->b) -> app a -> app b
62 bool :: Bool -> app Bool
63 char :: Char -> app Char
64 cons :: app (a -> [a] -> [a])
65 const :: app (a -> b -> a)
66 eq :: Eq a => app a -> app (a -> Bool)
67 flip :: app ((a -> b -> c) -> b -> a -> c)
71 instance Runtimeable Identity
73 -- ** Type 'Runtimeable'
74 -- | Initial encoding of 'Runtimeable'
75 data OptRuntime (app:: * -> *) a where
76 OptRuntime :: app a -> OptRuntime app a
77 (:.) :: OptRuntime app ((b->c) -> (a->b) -> a -> c)
78 (:$) :: OptRuntime app ((a->b) -> a -> b)
79 (:@) :: OptRuntime app (a->b) -> OptRuntime app a -> OptRuntime app b
80 Const :: OptRuntime app (a -> b -> a)
81 Flip :: OptRuntime app ((a -> b -> c) -> b -> a -> c)
82 Id :: OptRuntime app (a->a)
83 type instance Unlift (OptRuntime app) = app
84 instance (Liftable app, Unliftable app, Runtimeable app) => Liftable (OptRuntime app) where
86 instance (Unliftable app, Runtimeable app) => Unliftable (OptRuntime app) where
88 OptRuntime x -> runtime (unlift x)
91 (:@) f x -> (.@) (unlift f) (unlift x)
99 instance Runtimeable (OptRuntime app) where
107 instance Runtimeable Runtime where
108 runtime = Function.id
109 (.) = Runtime (.) (.)
110 ($) = Runtime ($) ($)
111 (.@) f x = Runtime ((.@) (eval f) (eval x)) ((.@) (code f) (code x))
112 bool b = Runtime (bool b) (bool b)
113 char c = Runtime (char c) (char c)
114 cons = Runtime cons cons
115 const = Runtime const const
116 eq x = Runtime (eq (eval x)) (eq (code x))
117 flip = Runtime flip flip
119 nil = Runtime nil nil
120 unit = Runtime unit unit
121 instance Runtimeable Eval where
123 (.) = Eval (Function..)
124 ($) = Eval (Function.$)
125 (.@) f x = Eval ((unEval f) (unEval x))
129 const = Eval Function.const
130 eq x = Eval (unEval x Eq.==)
131 flip = Eval Function.flip
132 id = Eval Function.id
135 instance Runtimeable Code where
137 (.) = Code [|| \f g x -> f (g x) ||]
138 ($) = Code [|| \f x -> f x ||]
139 (.@) f x = Code [|| $$(unCode f) $$(unCode x) ||]
140 bool b = Code [|| b ||]
141 char c = Code [|| c ||]
142 cons = Code [|| \x xs -> x : xs ||]
143 const = Code [|| \x _ -> x ||]
144 eq x = Code [|| \y -> $$(unCode x) Eq.== y ||]
145 flip = Code [|| \f x y -> f y x ||]
146 id = Code [|| \x -> x ||]
147 nil = Code [|| [] ||]
148 unit = Code [|| () ||]