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 Haskell functions
38 -- useful for some optimizations in 'optimizeComb'.
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)
57 -- ** Type 'Haskellable'
58 -- | Initial encoding of 'Haskellable'.
60 Haskell :: ValueCode a -> Haskell a
61 (:.) :: Haskell ((b->c) -> (a->b) -> a -> c)
62 (:$) :: Haskell ((a->b) -> a -> b)
63 (:@) :: Haskell (a->b) -> Haskell a -> Haskell b
64 Const :: Haskell (a -> b -> a)
65 Flip :: Haskell ((a -> b -> c) -> b -> a -> c)
71 instance Show (Haskell a) where
73 Haskell{} -> showString "Haskell"
74 (:.) -> showString "(.)"
75 (:$) -> showString "($)"
79 Fun.. showString " . "
86 Const -> showString "const"
87 Flip -> showString "flip"
89 Unit -> showString "()"
90 instance Trans Haskell ValueCode where
95 (:@) f x -> (.@) (trans f) (trans x)
100 instance Trans ValueCode Haskell where
102 type instance Output Haskell = ValueCode
104 instance Haskellable Haskell where
107 -- Small optimizations, mainly to reduce dump sizes.
109 (Const :@ x) .@ _y = x
110 ((Flip :@ Const) :@ _x) .@ y = y
116 bool b = Haskell (bool b)
117 char c = Haskell (char c)
118 eq x = Haskell (eq (trans x))
122 right = Haskell right
123 nothing = Haskell nothing
125 instance Haskellable ValueCode where
126 (.) = ValueCode (.) (.)
127 ($) = ValueCode ($) ($)
128 (.@) f x = ValueCode ((.@) (value f) (value x)) ((.@) (code f) (code x))
129 bool b = ValueCode (bool b) (bool b)
130 char c = ValueCode (char c) (char c)
131 cons = ValueCode cons cons
132 const = ValueCode const const
133 eq x = ValueCode (eq (value x)) (eq (code x))
134 flip = ValueCode flip flip
136 nil = ValueCode nil nil
137 unit = ValueCode unit unit
138 left = ValueCode left left
139 right = ValueCode right right
140 nothing = ValueCode nothing nothing
141 just = ValueCode just just
142 instance Haskellable Value where
143 (.) = Value (Function..)
144 ($) = Value (Function.$)
145 (.@) f x = Value (unValue f (unValue x))
149 const = Value Function.const
150 eq x = Value (unValue x Eq.==)
151 flip = Value Function.flip
152 id = Value Function.id
157 nothing = Value Nothing
159 instance Haskellable Code where
160 (.) = Code [|| \f g x -> f (g x) ||]
161 ($) = Code [|| \f x -> f x ||]
162 (.@) f x = Code [|| $$(unCode f) $$(unCode x) ||]
163 bool b = Code [|| b ||]
164 char c = Code [|| c ||]
165 cons = Code [|| \x xs -> x : xs ||]
166 const = Code [|| \x _ -> x ||]
167 eq x = Code [|| \y -> $$(unCode x) Eq.== y ||]
168 flip = Code [|| \f x y -> f y x ||]
169 id = Code [|| \x -> x ||]
170 nil = Code [|| [] ||]
171 unit = Code [|| () ||]
172 left = Code [|| Left ||]
173 right = Code [|| Right ||]
174 nothing = Code [|| Nothing ||]
175 just = Code [|| Just ||]