File: Convert.hs

package info (click to toggle)
haskell-derive 2.5.16-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 460 kB
  • sloc: haskell: 3,686; makefile: 5
file content (274 lines) | stat: -rw-r--r-- 9,388 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
{-# LANGUAGE CPP, ScopedTypeVariables, MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances #-}

module Language.Haskell.Convert(Convert, convert) where

import Language.Haskell as HS
import Language.Haskell.TH.Syntax as TH
import Control.Exception
import Data.Typeable
import System.IO.Unsafe
import Data.Maybe


class (Typeable a, Typeable b, Show a, Show b) => Convert a b where
    conv :: a -> b


convert :: forall a b . Convert a b => a -> b
convert a = unsafePerformIO $
        (return $! (conv a :: b)) `Control.Exception.catch` (\(e :: SomeException) -> error $ msg e)
    where
        msg e = "Could not convert " ++ show (typeOf a) ++ " to " ++
                show (typeOf (undefined :: b)) ++ "\n" ++ show a ++
                "\n" ++ show e



appT = foldl AppT

c mr = convert mr

instance Convert a b => Convert [a] [b] where
    conv = map c



instance Convert TH.Dec HS.Decl where
    conv x = case x of
        DataD cxt n vs con ds -> f DataType cxt n vs con ds
        NewtypeD cxt n vs con ds -> f NewType cxt n vs [con] ds
        where
            f t cxt n vs con ds = DataDecl sl t (c cxt) (c n) (c vs) (c con) []

instance Convert TH.Name HS.TyVarBind where
    conv = UnkindedVar . c

instance Convert TH.Name HS.Name where
    conv x = name $ if '.' `elem` x2 then reverse $ takeWhile (/= '.') $ reverse x2 else x2
        where x2 = show x

instance Convert TH.Name HS.QName where
    conv x = if x2 == Ident "[]" then Special ListCon else UnQual x2
        where x2 = c x

instance Convert TH.Con HS.QualConDecl where
    conv (ForallC vs cxt x) = QualConDecl sl (c vs) (c cxt) (c x)
    conv x = QualConDecl sl [] [] (c x)

instance Convert TH.Con HS.ConDecl where
    conv (NormalC n xs) = ConDecl (c n) (c xs)
    conv (RecC n xs) = RecDecl (c n) [([c x], c (y,z)) | (x,y,z) <- xs]
    conv (InfixC x n y) = InfixConDecl (c x) (c n) (c y)

instance Convert TH.StrictType HS.BangType where
    conv (IsStrict, x) = BangedTy $ c x
    conv (NotStrict, x) = UnBangedTy $ c x
#if __GLASGOW_HASKELL__ >= 704
    conv (Unpacked, x) = BangedTy $ c x
#endif

instance Convert TH.Type HS.Type where
    conv (ForallT xs cxt t) = TyForall (Just $ c xs) (c cxt) (c t)
    conv (VarT x) = TyVar $ c x
    conv (ConT x) | ',' `elem` show x = TyTuple Boxed []
                  | otherwise = TyCon $ c x
    conv (AppT (AppT ArrowT x) y) = TyFun (c x) (c y)
    conv (AppT ListT x) = TyList $ c x
    conv (TupleT _) = TyTuple Boxed []
    conv (AppT x y) = case c x of
        TyTuple b xs -> TyTuple b $ xs ++ [c y]
        x -> TyApp x $ c y

instance Convert TH.Type HS.Asst where
    conv (ConT x) = ClassA (UnQual $ c x) []
    conv (AppT x y) = case c x of
        ClassA a b -> ClassA a (b ++ [c y])



instance Convert HS.Decl TH.Dec where
    conv (InstDecl _ cxt nam typ ds) = InstanceD (c cxt) (c $ tyApp (TyCon nam) typ) [c d | InsDecl d <- ds]
    conv (FunBind ms@(HS.Match _ nam _ _ _ _:_)) = FunD (c nam) (c ms)
    conv (PatBind _ p _ bod ds) = ValD (c p) (c bod) (c ds)
    conv (TypeSig _ [nam] typ) = SigD (c nam) (c $ foralls typ)
    conv (DataDecl _ DataType ctx nam typ cs ds) =
      DataD (c ctx) (c nam) (c typ) (c cs) (c (map fst ds))
    conv (DataDecl _ NewType ctx nam typ [con] ds) =
      NewtypeD (c ctx) (c nam) (c typ) (c con) (c (map fst ds))

instance Convert HS.QualConDecl TH.Con where
    conv (QualConDecl _ [] [] con) = c con
    conv (QualConDecl _ vs cx con) = ForallC (c vs) (c cx) (c con)

instance Convert HS.ConDecl TH.Con where
    conv (ConDecl nam typ) = NormalC (c nam) (c typ)
    conv (InfixConDecl l nam r) = InfixC (c l) (c nam) (c r)
    conv (RecDecl nam fs) = RecC (c nam) (concatMap c fs)

instance Convert HS.BangType TH.StrictType where
    conv (BangedTy t) = (IsStrict,c t)
    conv (UnBangedTy t) = (NotStrict,c t)

instance Convert ([HS.Name],HS.BangType) [TH.VarStrictType] where
    conv (names,bt) = [(c name,s,t) | name <- names]
     where (s,t) = c bt

instance Convert HS.Asst TH.Type where
    conv (InfixA x y z) = c $ ClassA y [x,z]
    conv (ClassA x y) = appT (ConT $ c x) (c y)

instance Convert HS.Type TH.Type where
    conv (TyCon (Special ListCon)) = ListT
    conv (TyCon (Special UnitCon)) = TupleT 0
    conv (TyParen x) = c x
    conv (TyForall x y z) = ForallT (c $ fromMaybe [] x) (c y) (c z)
    conv (TyVar x) = VarT $ c x
    conv (TyCon x) = if x ~= "[]" then error "here" else ConT $ c x
    conv (TyFun x y) = AppT (AppT ArrowT (c x)) (c y)
    conv (TyList x) = AppT ListT (c x)
    conv (TyTuple _ x) = appT (TupleT (length x)) (c x)
    conv (TyApp x y) = AppT (c x) (c y)

instance Convert HS.Name TH.Name where
    conv = mkName . filter (`notElem` "()") . prettyPrint

instance Convert HS.Match TH.Clause where
    conv (HS.Match _ _ ps _ bod ds) = Clause (c ps) (c bod) (c ds)

instance Convert HS.Rhs TH.Body where
    conv (UnGuardedRhs x) = NormalB (c x)
    conv (GuardedRhss x) = GuardedB (c x)

instance Convert HS.Exp TH.Exp where
    conv (Con (Special UnitCon)) = TupE []
    conv (Var x) = VarE (c x)
    conv (Con x) = ConE (c x)
    conv (Lit x) = LitE (c x)
    conv (App x y) = AppE (c x) (c y)
    conv (Paren x) = c x
    conv (InfixApp x y z) = InfixE (Just $ c x) (c y) (Just $ c z)
    conv (LeftSection x y) = InfixE (Just $ c x) (c y) Nothing
    conv (RightSection y z) = InfixE Nothing (c y) (Just $ c z)
    conv (Lambda _ x y) = LamE (c x) (c y)
    conv (Tuple _ x) = TupE (c x)
    conv (If x y z) = CondE (c x) (c y) (c z)
    conv (Let x y) = LetE (c x) (c y)
    conv (Case x y) = CaseE (c x) (c y)
    conv (Do x) = DoE (c x)
    conv (EnumFrom x) = ArithSeqE $ FromR (c x)
    conv (EnumFromTo x y) = ArithSeqE $ FromToR (c x) (c y)
    conv (EnumFromThen x y) = ArithSeqE $ FromThenR (c x) (c y)
    conv (EnumFromThenTo x y z) = ArithSeqE $ FromThenToR (c x) (c y) (c z)
    conv (List x) = ListE (c x)
    conv (ExpTypeSig _ x y) = SigE (c x) (c y)
    conv (RecConstr x y) = RecConE (c x) (c y)
    conv (RecUpdate x y) = RecUpdE (c x) (c y) 
    -- Work around bug 3395, convert to do notation instead
    conv (ListComp x y) = CompE $ c $ y ++ [QualStmt $ Qualifier x]

instance Convert HS.GuardedRhs (TH.Guard, TH.Exp) where
    conv = undefined

instance Convert HS.Binds [TH.Dec] where
    conv (BDecls x) = c x

instance Convert HS.Pat TH.Pat where
    conv (PParen x) = c x
    conv (PLit x) = LitP (c x)
    conv (PTuple _ x) = TupP (c x)
    conv (PApp x y) = ConP (c x) (c y)
    conv (PVar x) = VarP (c x)
    conv (PInfixApp x y z) = InfixP (c x) (c y) (c z)
    conv (PIrrPat x) = TildeP (c x)
    conv (PAsPat x y) = AsP (c x) (c y)
    conv (PWildCard) = WildP
    conv (PRec x y) = RecP (c x) (c y)
    conv (PList x) = ListP (c x)
    conv (PatTypeSig _ x y) = SigP (c x) (c y)

instance Convert HS.Literal TH.Lit where
    conv (Char x) = CharL x
    conv (String x) = StringL x
    conv (Int x) = IntegerL x
    conv (Frac x) = RationalL x
    conv (PrimInt x) = IntPrimL x
    conv (PrimWord x) = WordPrimL x
    conv (PrimFloat x) = FloatPrimL x
    conv (PrimDouble x) = DoublePrimL x

instance Convert HS.QName TH.Name where
    conv (UnQual x) = c x
    conv (Qual m x) = c (Ident $ prettyPrint m ++ "." ++ prettyPrint x)
    conv (Special (TupleCon Boxed i)) = Name (mkOccName $ "(" ++ replicate (i-1) ',' ++ ")") NameS

instance Convert HS.PatField TH.FieldPat where
    conv = undefined

instance Convert HS.QOp TH.Exp where
    conv (QVarOp x) = c $ Var x
    conv (QConOp x) = c $ Con x

instance Convert HS.Alt TH.Match where
    conv (Alt _ x y z) = TH.Match (c x) (c y) (c z)

instance Convert HS.Stmt TH.Stmt where
    conv (Generator _ x y) = BindS (c x) (c y)
    conv (LetStmt x) = LetS (c x)
    conv (Qualifier x) = NoBindS (c x)

instance Convert HS.QualStmt TH.Stmt where
    conv (QualStmt x) = c x

instance Convert HS.FieldUpdate TH.FieldExp where
    conv (FieldUpdate x y) = (c x, c y)

instance Convert HS.TyVarBind TH.Name where
    conv (UnkindedVar x) = c x

instance Convert HS.GuardedAlts TH.Body where
    conv (UnGuardedAlt x) = NormalB (c x)
    conv (GuardedAlts x) = GuardedB (c x)

instance Convert HS.GuardedAlt (TH.Guard, TH.Exp) where
    conv (GuardedAlt _ x y) = (PatG (c x), c y)


#if __GLASGOW_HASKELL__ >= 612
instance Convert TH.TyVarBndr HS.TyVarBind where
    conv (PlainTV x) = UnkindedVar $ c x
    conv (KindedTV x y) = KindedVar (c x) $ c y

#if __GLASGOW_HASKELL__ < 706
instance Convert TH.Kind HS.Kind where
    conv StarK = KindStar
    conv (ArrowK x y) = KindFn (c x) $ c y
#else
instance Convert TH.Kind HS.Kind where
    conv StarT = KindStar
    conv (AppT (AppT ArrowT x) y) = KindFn (c x) (c y)
#endif

#if __GLASGOW_HASKELL__ < 709
instance Convert TH.Pred HS.Asst where
    conv (ClassP x y) = ClassA (UnQual $ c x) $ c y
    conv (TH.EqualP x y) = HS.EqualP (c x) $ c y

instance Convert HS.Asst TH.Pred where
    conv (ClassA x y) = ClassP (c x) $ c y
    conv (HS.EqualP x y) = TH.EqualP (c x) $ c y
#endif

instance Convert HS.TyVarBind TH.TyVarBndr where
    conv (UnkindedVar x) = PlainTV $ c x
    conv (KindedVar x y) = KindedTV (c x) $ c y

#if __GLASGOW_HASKELL__ < 706
instance Convert HS.Kind TH.Kind where
    conv KindStar = StarK
    conv (KindFn x y) = ArrowK (c x) $ c y
#else
instance Convert HS.Kind TH.Kind where
    conv KindStar = StarT
    conv (KindFn x y) = AppT (AppT ArrowT (c x)) (c y)
#endif
#endif