1 {-# LANGUAGE MagicHash #-}
2 {-# LANGUAGE TemplateHaskell #-}
3 module Symantic.Parser.Staging where
5 import Data.Bool (Bool)
6 import Data.Char (Char)
7 import Data.Either (Either(..))
9 import Data.Maybe (Maybe(..))
10 import Data.Ord (Ord(..))
11 import Language.Haskell.TH (TExpQ)
12 import Text.Show (Show(..), showParen, showString)
13 import qualified Data.Eq as Eq
14 import qualified Data.Function as Fun
15 import qualified Data.Function as Function
17 import Symantic.Univariant.Trans
20 -- | Compile-time 'value' and corresponding 'code' (that can produce that value at runtime).
21 data ValueCode a = ValueCode
25 getValue :: ValueCode a -> a
26 getValue = unValue Function.. value
27 getCode :: ValueCode a -> TExpQ a
28 getCode = unCode Function.. code
31 newtype Value a = Value { unValue :: a }
34 newtype Code a = Code { unCode :: TExpQ a }
36 -- * Class 'Haskellable'
37 -- | Final encoding of some Haskellable functions
38 -- useful for some optimizations in 'optGram'.
39 class Haskellable (repr :: * -> *) where
40 (.) :: repr ((b->c) -> (a->b) -> a -> c)
41 ($) :: repr ((a->b) -> a -> b)
42 (.@) :: repr (a->b) -> repr a -> repr b
43 bool :: Bool -> repr Bool
44 char :: Char -> repr Char
45 cons :: repr (a -> [a] -> [a])
46 const :: repr (a -> b -> a)
47 eq :: Eq a => repr a -> repr (a -> Bool)
48 flip :: repr ((a -> b -> c) -> b -> a -> c)
52 left :: repr (l -> Either l r)
53 right :: repr (r -> Either l r)
54 nothing :: repr (Maybe a)
55 just :: repr (a -> Maybe a)
56 -- instance Haskellable Identity
58 -- ** Type 'Haskellable'
59 -- | Initial encoding of 'Haskellable'
61 Haskell :: ValueCode a -> Haskell a
62 (:.) :: Haskell ((b->c) -> (a->b) -> a -> c)
63 (:$) :: Haskell ((a->b) -> a -> b)
64 (:@) :: Haskell (a->b) -> Haskell a -> Haskell b
65 Const :: Haskell (a -> b -> a)
66 Flip :: Haskell ((a -> b -> c) -> b -> a -> c)
72 instance Show (Haskell a) where
74 Haskell{} -> showString "Haskell"
75 (:.) -> showString "(.)"
76 (:$) -> showString "($)"
79 Fun.$ showString "(@) "
83 Const -> showString "const"
84 Flip -> showString "flip"
86 Unit -> showString "()"
87 instance Trans Haskell ValueCode where
92 (:@) f x -> (.@) (trans f) (trans x)
97 instance Trans ValueCode Haskell where
99 type instance Output Haskell = ValueCode
101 instance Haskellable Haskell where
109 bool b = Haskell (bool b)
110 char c = Haskell (char c)
111 eq x = Haskell (eq (trans x))
115 right = Haskell right
116 nothing = Haskell nothing
118 instance Haskellable ValueCode where
119 (.) = ValueCode (.) (.)
120 ($) = ValueCode ($) ($)
121 (.@) f x = ValueCode ((.@) (value f) (value x)) ((.@) (code f) (code x))
122 bool b = ValueCode (bool b) (bool b)
123 char c = ValueCode (char c) (char c)
124 cons = ValueCode cons cons
125 const = ValueCode const const
126 eq x = ValueCode (eq (value x)) (eq (code x))
127 flip = ValueCode flip flip
129 nil = ValueCode nil nil
130 unit = ValueCode unit unit
131 left = ValueCode left left
132 right = ValueCode right right
133 nothing = ValueCode nothing nothing
134 just = ValueCode just just
135 instance Haskellable Value where
136 (.) = Value (Function..)
137 ($) = Value (Function.$)
138 (.@) f x = Value (unValue f (unValue x))
142 const = Value Function.const
143 eq x = Value (unValue x Eq.==)
144 flip = Value Function.flip
145 id = Value Function.id
150 nothing = Value Nothing
152 instance Haskellable Code where
153 (.) = Code [|| \f g x -> f (g x) ||]
154 ($) = Code [|| \f x -> f x ||]
155 (.@) f x = Code [|| $$(unCode f) $$(unCode x) ||]
156 bool b = Code [|| b ||]
157 char c = Code [|| c ||]
158 cons = Code [|| \x xs -> x : xs ||]
159 const = Code [|| \x _ -> x ||]
160 eq x = Code [|| \y -> $$(unCode x) Eq.== y ||]
161 flip = Code [|| \f x y -> f y x ||]
162 id = Code [|| \x -> x ||]
163 nil = Code [|| [] ||]
164 unit = Code [|| () ||]
165 left = Code [|| Left ||]
166 right = Code [|| Right ||]
167 nothing = Code [|| Nothing ||]
168 just = Code [|| Just ||]