1 {-# LANGUAGE TemplateHaskell #-}
2 module Symantic.Parser.Staging where
4 import Data.Bool (Bool)
5 import Data.Char (Char)
7 import Language.Haskell.TH (TExpQ)
8 import qualified Data.Eq as Eq
9 import qualified Data.Function as Function
11 import Symantic.Base.Univariant
14 data Runtime a = Runtime
16 -- ^ The value of the runtime code,
17 -- kept along to be made available to the optimizer.
19 -- ^ An AST of a runtime value.
21 getEval :: Runtime a -> a
22 getEval = unEval Function.. eval
23 getCode :: Runtime a -> TExpQ a
24 getCode = unCode Function.. code
25 type instance Unlift Runtime = Runtime
26 instance Liftable Runtime where
29 instance Unliftable Runtime where
34 newtype Eval a = Eval { unEval :: a }
35 type instance Unlift Eval = Eval
36 instance Liftable Eval where
39 instance Unliftable Eval where
44 newtype Code a = Code { unCode :: TExpQ a }
45 type instance Unlift Code = Code
46 instance Liftable Code where
49 instance Unliftable Code where
53 -- * Class 'Runtimeable'
54 -- | Final encoding of some Runtimeable functions
55 -- useful for some optimizations in 'optGram'.
56 class Runtimeable (repr :: * -> *) where
57 runtime :: Unlift repr a -> repr a
58 (.) :: repr ((b->c) -> (a->b) -> a -> c)
59 ($) :: repr ((a->b) -> a -> b)
60 (.@) :: repr (a->b) -> repr a -> repr b
61 --char :: Char -> repr Char
62 cons :: repr (a -> [a] -> [a])
63 const :: repr (a -> b -> a)
64 eq :: Eq a => repr a -> repr (a -> Bool)
65 flip :: repr ((a -> b -> c) -> b -> a -> c)
70 -- ** Type 'Runtimeable'
71 -- | Initial encoding of 'Runtimeable'
72 data OptRuntime (repr:: * -> *) a where
73 OptRuntime :: repr a -> OptRuntime repr a
74 (:.) :: OptRuntime repr ((b->c) -> (a->b) -> a -> c)
75 (:$) :: OptRuntime repr ((a->b) -> a -> b)
76 (:@) :: OptRuntime repr (a->b) -> OptRuntime repr a -> OptRuntime repr b
77 Const :: OptRuntime repr (a -> b -> a)
78 Flip :: OptRuntime repr ((a -> b -> c) -> b -> a -> c)
79 Id :: OptRuntime repr (a->a)
80 type instance Unlift (OptRuntime repr) = repr
81 instance (Liftable repr, Unliftable repr, Runtimeable repr) => Liftable (OptRuntime repr) where
83 instance (Unliftable repr, Runtimeable repr) => Unliftable (OptRuntime repr) where
85 OptRuntime x -> runtime (unlift x)
88 (:@) f x -> (.@) (unlift f) (unlift x)
96 instance Runtimeable (OptRuntime repr) where
104 instance Runtimeable Runtime where
105 runtime = Function.id
106 (.) = Runtime (.) (.)
107 ($) = Runtime ($) ($)
108 (.@) f x = Runtime ((.@) (eval f) (eval x)) ((.@) (code f) (code x))
109 cons = Runtime cons cons
110 const = Runtime const const
111 eq x = Runtime (eq (eval x)) (eq (code x))
112 flip = Runtime flip flip
114 nil = Runtime nil nil
115 unit = Runtime unit unit
116 instance Runtimeable Eval where
118 (.) = Eval (Function..)
119 ($) = Eval (Function.$)
120 (.@) f x = Eval ((unEval f) (unEval x))
122 const = Eval Function.const
123 eq x = Eval (unEval x Eq.==)
124 flip = Eval Function.flip
125 id = Eval Function.id
128 instance Runtimeable Code where
130 (.) = Code [|| \f g x -> f (g x) ||]
131 ($) = Code [|| \f x -> f x ||]
132 (.@) f x = Code [|| $$(unCode f) $$(unCode x) ||]
133 cons = Code [|| \x xs -> x : xs ||]
134 const = Code [|| \x _ -> x ||]
135 eq x = Code [|| \y -> $$(unCode x) Eq.== y ||]
136 flip = Code [|| \f x y -> f y x ||]
137 id = Code [|| \x -> x ||]
138 nil = Code [|| [] ||]
139 unit = Code [|| () ||]