git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: reformat source files with hindent
7651841Andy Arvanitis
src/Language/PureScript/CodeGen/Cpp.hs+433−502
@@ -29,10 +29,10 @@ module Language.PureScript.CodeGen.Cpp
29import Prelude.Compat
29import Prelude.Compat
30
30
31import Data.Char (isLetter)
31import Data.Char (isLetter)
32−import Data.List
33import Data.Function (on)
32import Data.Function (on)
34−import Data.Maybe (catMaybes, fromJust)
33+import Data.List
35import qualified Data.Map as M
34import qualified Data.Map as M
35+import Data.Maybe (catMaybes, fromJust)
36
36
37import Control.Monad (forM, replicateM)
37import Control.Monad (forM, replicateM)
38import Control.Monad.Reader (MonadReader, ask)
38import Control.Monad.Reader (MonadReader, ask)
@@ -61,59 +61,57 @@ import qualified Language.PureScript.Types as T
61-- module.
61-- module.
62--
62--
63---------------------------------------------------------------------------------------------------
63---------------------------------------------------------------------------------------------------
64+moduleToCpp
65+ :: forall m.
64−moduleToCpp :: forall m. (Applicative m, Monad m, MonadReader Options m, MonadSupply m)
66+ (Applicative m, Monad m, MonadReader Options m, MonadSupply m)
65− => E.Environment -> Module Ann -> m [Cpp]
67+ => E.Environment -> Module Ann -> m [Cpp]
66---------------------------------------------------------------------------------------------------
68---------------------------------------------------------------------------------------------------
67moduleToCpp env (Module _ mn imps _ foreigns decls) = do
69moduleToCpp env (Module _ mn imps _ foreigns decls) = do
68− cppImports <-
70+ cppImports <-
69− traverse (pure . runModuleName) .
70− delete (ModuleName [ProperName C.prim]) . (\\ [mn]) $
71+ traverse (pure . runModuleName) . delete (ModuleName [ProperName C.prim]) . (\\ [mn]) $
71− (snd <$> imps)
72+ (snd <$> imps)
72− let cppImports' = "PureScript" : cppImports
73+ let cppImports' = "PureScript" : cppImports
73− cppDecls <- concat <$> mapM (bindToCpp [TopLevel]) decls
74+ cppDecls <- concat <$> mapM (bindToCpp [TopLevel]) decls
74− let cpps = filterInlineFuncs <$> cppDecls
75+ let cpps = filterInlineFuncs <$> cppDecls
75− namesmap = M.toList .
76+ namesmap =
76− M.mapKeysMonotonic (qualifiedToCpp id) . M.map (\(t, _, _) -> arity t) $
77+ M.toList . M.mapKeysMonotonic (qualifiedToCpp id) . M.map (\(t, _, _) -> arity t) $
77− E.names env
78+ E.names env
78− datamap = M.toList .
79+ datamap =
80+ M.toList .
79− M.mapKeysMonotonic (qualifiedToCpp (Ident . runProperName)) .
81+ M.mapKeysMonotonic (qualifiedToCpp (Ident . runProperName)) .
80− M.map (\(_, _, _, fields) -> length fields) $
82+ M.map (\(_, _, _, fields) -> length fields) $
81− E.dataConstructors env
83+ E.dataConstructors env
82− cpps' <- traverse (optimize $ namesmap ++ datamap) cpps
84+ cpps' <- traverse (optimize $ namesmap ++ datamap) cpps
83− foreignWrappers <- curriedForeigns
85+ foreignWrappers <- curriedForeigns
84− let optimized = cpps' ++ foreignWrappers
86+ let optimized = cpps' ++ foreignWrappers
85− let moduleHeader =
87+ let moduleHeader =
86− fileBegin mn "HH" ++
88+ fileBegin mn "HH" ++
87− P.linebreak ++
89+ P.linebreak ++
88− ((\i -> CppInclude i i) <$> cppImports') ++
90+ ((\i -> CppInclude i i) <$> cppImports') ++
89− (if not (null foreigns)
91+ (if not (null foreigns)
90− then [CppInclude [] (runModuleName mn ++ "_ffi")]
92+ then [CppInclude [] (runModuleName mn ++ "_ffi")]
91− else []) ++
93+ else []) ++
92− P.linebreak ++
94+ P.linebreak ++
93− [ CppNamespace (runModuleName mn) $
95+ [ CppNamespace (runModuleName mn) $
94− (CppUseNamespace <$> cppImports') ++
96+ (CppUseNamespace <$> cppImports') ++
95− P.linebreak ++
96− dataCtors ++
97− toHeader optimized ++
98− toHeaderFns optimized
97+ P.linebreak ++ dataCtors ++ toHeader optimized ++ toHeaderFns optimized
99− ] ++
98+ ] ++
100− P.linebreak ++
101− fileEnd mn "HH"
99+ P.linebreak ++ fileEnd mn "HH"
102− let bodyCpps = toBodyDecl optimized ++ toBody optimized
100+ let bodyCpps = toBodyDecl optimized ++ toBody optimized
103− symbols = allSymbols bodyCpps
101+ symbols = allSymbols bodyCpps
104− moduleBody =
102+ moduleBody =
105− CppInclude (runModuleName mn) (runModuleName mn) :
103+ CppInclude (runModuleName mn) (runModuleName mn) :
106− symbolDefs symbols :
104+ symbolDefs symbols :
107− (if null bodyCpps
105+ (if null bodyCpps
108− then []
106+ then []
109− else [ CppNamespace (runModuleName mn) $
107+ else [ CppNamespace (runModuleName mn) $
110− (CppUseNamespace <$> cppImports') ++
108+ (CppUseNamespace <$> cppImports') ++ P.linebreak ++ bodyCpps
111− P.linebreak ++ bodyCpps ]) ++
109+ ]) ++
112− P.linebreak ++
110+ P.linebreak ++
113− (if isMain mn
111+ (if isMain mn
114− then [nativeMain] ++ P.linebreak
112+ then [nativeMain] ++ P.linebreak
115− else [])
113+ else [])
116− return $ moduleHeader ++ CppEndOfHeader : moduleBody
114+ return $ moduleHeader ++ CppEndOfHeader : moduleBody
117 where
115 where
118 -- |
116 -- |
119 -- Generate code in the simplified C++1x intermediate representation for a declaration
117 -- Generate code in the simplified C++1x intermediate representation for a declaration
@@ -122,8 +120,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
122 bindToCpp :: [ValueQual] -> Bind Ann -> m [Cpp]
120 bindToCpp :: [ValueQual] -> Bind Ann -> m [Cpp]
123 -------------------------------------------------------------------------------------------------
121 -------------------------------------------------------------------------------------------------
124 bindToCpp qs (NonRec ann ident val) = return <$> declToCpp qs (ann, ident) val
122 bindToCpp qs (NonRec ann ident val) = return <$> declToCpp qs (ann, ident) val
125− bindToCpp qs (Rec vals) = forM vals (uncurry $ declToCpp (Recursive:qs))
123+ bindToCpp qs (Rec vals) = forM vals (uncurry $ declToCpp (Recursive : qs))
126−
127 -- |
124 -- |
128 -- Desugar a declaration into a variable introduction or named function
125 -- Desugar a declaration into a variable introduction or named function
129 -- declaration.
126 -- declaration.
@@ -134,73 +131,89 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
134 let className = identToCpp ident
131 let className = identToCpp ident
135 (supers, members) = span (C.__superclass_ `isPrefixOf`) (identToCpp <$> (fst $ unAbs e []))
132 (supers, members) = span (C.__superclass_ `isPrefixOf`) (identToCpp <$> (fst $ unAbs e []))
136 in return $ CppStruct className [CppEnum Nothing Nothing (sort supers ++ members)]
133 in return $ CppStruct className [CppEnum Nothing Nothing (sort supers ++ members)]
137−
138 declToCpp vqs (_, ident) (Abs (_, com, ty, _) arg body) = do
134 declToCpp vqs (_, ident) (Abs (_, com, ty, _) arg body) = do
135+ fn <-
139− fn <- if TopLevel `elem` vqs
136+ if TopLevel `elem` vqs
140− then do
137+ then do
141− argNames <- replicateM (arity' - length args' - 1) freshName
138+ remainingArgs <- replicateM (arity' - length args' - 1) freshName
142− let args'' = zip argNames (repeat aty)
139+ let remainingArgs' = zip remainingArgs (repeat aty)
143− if isTypeClassMember
140+ if isTypeClassMember
144− then do -- typeclass member functions are stored curried
141+ then do -- typeclass member functions are stored curried
145− body' <- innerLambdas . optIndexers classes <$> valueToCpp (snd abs')
142+ body' <- innerLambdas . optIndexers classes <$> valueToCpp (snd abs')
143+ return $
146− return $ CppNamespace ""
144+ CppNamespace
147− [ CppFunction
145+ ""
148− (curriedName name)
146+ [ CppFunction (curriedName name) [arg'] rty [Inline] (returnBlock body')
149− [arg']
150− rty
151− [Inline]
152− (returnBlock body')
153− , CppFunction
147+ , CppFunction
154− name
148+ name
155− (arg' : args' ++ args'')
149+ (arg' : args' ++ remainingArgs')
156− rty
150+ rty
151+ (vqs ++
157− (vqs ++ if isAccessor (snd abs') then [Inline] else [])
152+ if isAccessor (snd abs')
153+ then [Inline]
154+ else [])
158− (returnBlock $
155+ (returnBlock $
156+ foldl
159− foldl (\fn a -> CppApp fn [a])
157+ (\fn a -> CppApp fn [a])
160− body'
158+ body'
161− (CppVar . fst <$> (args' ++ args'')))
159+ (CppVar . fst <$> (args' ++ remainingArgs')))
162− ]
163− else do
164− body' <- innerLambdas . optIndexers classes <$> valueToCpp
165− (if null argNames
166− then snd abs'
167− else curriedApp
168− (tail argNames)
169− (App
170− nullAnn
171− (snd abs')
172− (Var nullAnn . Qualified Nothing . Ident $ head argNames)))
173− return $ CppNamespace ""
174− [ CppFunction
175− name
176− (arg' : args' ++ args'')
177− rty
178− (vqs ++ if isAccessor (snd abs') then [Inline] else [])
179− (returnBlock body')
180− , CppFunction
181− (curriedName name)
182− [arg']
183− rty
184− (if arity' == 1 then [Inline] else [])
185− (returnBlock $
186− curriedLambda
187− (fst <$> args' ++ args'')
188− (CppApp (CppVar name)
189− (CppVar . fst <$> (arg' : args' ++ args''))))
190− ]
160+ ]
191 else do
161 else do
162+ body' <-
192− body' <- innerLambdas . optIndexers classes <$> valueToCpp body
163+ innerLambdas . optIndexers classes <$>
164+ valueToCpp
165+ (if null remainingArgs
166+ then snd abs'
167+ else curriedApp
168+ (tail remainingArgs)
169+ (App
170+ nullAnn
171+ (snd abs')
172+ (Var nullAnn . Qualified Nothing . Ident $ head remainingArgs)))
173+ return $
174+ CppNamespace
175+ ""
176+ [ CppFunction
177+ name
178+ (arg' : args' ++ remainingArgs')
179+ rty
180+ (vqs ++
181+ if isAccessor (snd abs')
182+ then [Inline]
183+ else [])
184+ (returnBlock body')
193− return $ CppFunction
185+ , CppFunction
186+ (curriedName name)
187+ [arg']
188+ rty
189+ (if arity' == 1
190+ then [Inline]
191+ else [])
192+ (returnBlock $
193+ curriedLambda
194+ (fst <$> args' ++ remainingArgs')
195+ (CppApp
194− name
196+ (CppVar name)
197+ (CppVar . fst <$> (arg' : args' ++ remainingArgs'))))
198+ ]
199+ else do
200+ body' <- innerLambdas . optIndexers classes <$> valueToCpp body
201+ return $
202+ CppFunction
203+ name
195− [arg']
204+ [arg']
196− rty
205+ rty
206+ (vqs ++
197− (vqs ++ if isIndexer body' then [Inline] else [])
207+ if isIndexer body'
208+ then [Inline]
209+ else [])
198− (returnBlock body')
210+ (returnBlock body')
199 return (CppComment com $ convertIfPrimFn ty' fn)
211 return (CppComment com $ convertIfPrimFn ty' fn)
200 where
212 where
213+ ty'
201− ty' | Just t <- ty = Just t
214+ | Just t <- ty = Just t
202− | Just (t, _, _) <- M.lookup (Qualified (Just mn) ident) (E.names env) = Just t
215+ | Just (t, _, _) <- M.lookup (Qualified (Just mn) ident) (E.names env) = Just t
203− | otherwise = Nothing
216+ | otherwise = Nothing
204 isTypeClassMember = ident `elem` typeClassMembers
217 isTypeClassMember = ident `elem` typeClassMembers
205 arity' = maybe 0 arity ty'
218 arity' = maybe 0 arity ty'
206 name = identToCpp ident
219 name = identToCpp ident
@@ -210,105 +223,90 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
210 args' = (\i -> (identToCpp i, aty)) <$> fst abs'
223 args' = (\i -> (identToCpp i, aty)) <$> fst abs'
211 abs' = unAbs body []
224 abs' = unAbs body []
212 isAccessor :: Expr Ann -> Bool
225 isAccessor :: Expr Ann -> Bool
213− isAccessor Accessor{} = True
226+ isAccessor Accessor {} = True
214 isAccessor _ = False
227 isAccessor _ = False
215 isIndexer :: Cpp -> Bool
228 isIndexer :: Cpp -> Bool
216 isIndexer (CppIndexer (CppSymbol _) (CppVar _)) = True
229 isIndexer (CppIndexer (CppSymbol _) (CppVar _)) = True
217 isIndexer _ = False
230 isIndexer _ = False
231+ classes =
232+ zip
218− classes = zip (CppVar . fst <$> arg' : args')
233+ (CppVar . fst <$> arg' : args')
219− (qualifiedToCpp (Ident . runProperName) . T.constraintClass <$> maybe [] extractConstraints ty')
234+ (qualifiedToCpp (Ident . runProperName) . T.constraintClass <$>
220−
235+ maybe [] extractConstraints ty')
221−
222 declToCpp _ (_, ident) (Constructor _ _ (ProperName _) []) =
236 declToCpp _ (_, ident) (Constructor _ _ (ProperName _) []) =
223 return $
237 return $
224− CppFunction
238+ CppFunction
225− (identToCpp ident)
239+ (identToCpp ident)
226− []
240+ []
227− (Just $ Any [])
241+ (Just $ Any [])
228− [Inline]
242+ [Inline]
229− (returnBlock $
230− CppDataLiteral [CppAccessor (CppVar $ identToCpp ident) (CppVar "data")])
243+ (returnBlock $ CppDataLiteral [CppAccessor (CppVar $ identToCpp ident) (CppVar "data")])
231−
232 declToCpp _ (_, ident) (Constructor _ _ (ProperName _) fields) =
244 declToCpp _ (_, ident) (Constructor _ _ (ProperName _) fields) =
233 return . CppNamespace "" $
245 return . CppNamespace "" $
234 [ CppFunction
246 [ CppFunction
235− name
247+ name
236− (farg <$> fields')
248+ (farg <$> fields')
237− (Just $ Any [])
249+ (Just $ Any [])
238− [Inline]
250+ [Inline]
239− (returnBlock $
251+ (returnBlock $
240− CppDataLiteral $
241− CppAccessor (CppVar name) (CppVar "data") : (CppVar <$> fields'))
252+ CppDataLiteral $ CppAccessor (CppVar name) (CppVar "data") : (CppVar <$> fields'))
242 ] ++
253 ] ++
243 if length fields > 0
254 if length fields > 0
244− then
245− [ CppFunction
255+ then [ CppFunction
246− (curriedName name)
256+ (curriedName name)
247− (farg <$> f)
257+ (farg <$> f)
248− (Just $ Any [])
258+ (Just $ Any [])
249− (if length fields == 1 then [Inline] else [])
259+ (if length fields == 1
260+ then [Inline]
261+ else [])
250− (CppBlock (fieldLambdas fs))
262+ (CppBlock (fieldLambdas fs))
251− ]
263+ ]
252− else
264+ else []
253− []
254 where
265 where
255 name = identToCpp ident
266 name = identToCpp ident
256 fields' = identToCpp <$> fields
267 fields' = identToCpp <$> fields
268+ (f, fs)
257− (f, fs) | (f' : fs') <- fields' = ([f'], fs')
269+ | (f':fs') <- fields' = ([f'], fs')
258− | otherwise = ([], [])
270+ | otherwise = ([], [])
259 farg = \x -> (x, Just $ Any [Const, Ref])
271 farg = \x -> (x, Just $ Any [Const, Ref])
260 fieldLambdas flds
272 fieldLambdas flds
273+ | (f':fs') <- flds =
261− | (f' : fs') <- flds = [ CppReturn . maybeRemCaps $
274+ [ CppReturn . maybeRemCaps $
262− CppLambda
263− [CaptureAll]
264− (farg <$> [f'])
265− (Just $ Any [])
266− (CppBlock $ fieldLambdas fs') ]
275+ CppLambda [CaptureAll] (farg <$> [f']) (Just $ Any []) (CppBlock $ fieldLambdas fs')
276+ ]
267 | otherwise = [CppReturn $ CppApp (CppVar name) (CppVar <$> fields')]
277 | otherwise = [CppReturn $ CppApp (CppVar name) (CppVar <$> fields')]
268−
269 declToCpp qs (_, ident) e
278 declToCpp qs (_, ident) e
270− | Just ty <- exprType e,
279+ | Just ty <- exprType e
271− TopLevel `elem` qs,
280+ , TopLevel `elem` qs
272− arity' <- arity ty,
281+ , arity' <- arity ty
273− arity' > 0 = do
282+ , arity' > 0 = do
274− argNames <- replicateM arity' freshName
283+ argNames <- replicateM arity' freshName
284+ body' <-
275− body' <- valueToCpp $
285+ valueToCpp $
276− curriedApp
286+ curriedApp
277− (tail argNames)
287+ (tail argNames)
278− (App nullAnn e (Var nullAnn . Qualified Nothing . Ident $ head argNames))
288+ (App nullAnn e (Var nullAnn . Qualified Nothing . Ident $ head argNames))
289+ let fn' =
279− let fn' = CppFunction
290+ CppFunction
280− (curriedName name)
291+ (curriedName name)
281− [(head argNames, Just $ Any [Const, Ref])]
292+ [(head argNames, Just $ Any [Const, Ref])]
282− rty
293+ rty
283− []
294+ []
284− (returnBlock $
295+ (returnBlock $
285− curriedLambda
286− (tail argNames)
287− (CppApp (CppVar name)
296+ curriedLambda (tail argNames) (CppApp (CppVar name) (CppVar <$> argNames)))
288− (CppVar <$> argNames)))
297+ return $
289− return $ CppNamespace "" $
298+ CppNamespace "" $
290− [ CppFunction
291− name
292− (zip argNames $ repeat aty)
299+ [CppFunction name (zip argNames $ repeat aty) rty [] (returnBlock body')] ++
293− rty
294− []
295− (returnBlock body')
296− ] ++ if arity' > 0
300+ if arity' > 0
297− then [fn']
301+ then [fn']
298− else []
302+ else []
299 where
303 where
300 name = identToCpp ident
304 name = identToCpp ident
301 aty = Just $ Any [Const, Ref]
305 aty = Just $ Any [Const, Ref]
302 rty = Just $ Any []
306 rty = Just $ Any []
303−
304 declToCpp qs (_, ident) val = do
307 declToCpp qs (_, ident) val = do
305 val' <- valueToCpp val
308 val' <- valueToCpp val
306− return $
307− CppVariableIntroduction
308− (identToCpp ident, Just $ Any [Const])
309+ return $ CppVariableIntroduction (identToCpp ident, Just $ Any [Const]) qs (Just val')
309− qs
310− (Just val')
311−
312 -------------------------------------------------------------------------------------------------
310 -------------------------------------------------------------------------------------------------
313 exprType :: Expr Ann -> Maybe T.Type
311 exprType :: Expr Ann -> Maybe T.Type
314 -------------------------------------------------------------------------------------------------
312 -------------------------------------------------------------------------------------------------
@@ -317,21 +315,20 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
317 exprType (Case (_, _, Just ty, _) _ _) = Just ty
315 exprType (Case (_, _, Just ty, _) _ _) = Just ty
318 exprType (Let (_, _, Just ty, _) _ _) = Just ty
316 exprType (Let (_, _, Just ty, _) _ _) = Just ty
319 exprType _ = Nothing
317 exprType _ = Nothing
320−
321 -------------------------------------------------------------------------------------------------
318 -------------------------------------------------------------------------------------------------
322 fnToLambda :: Cpp -> Cpp
319 fnToLambda :: Cpp -> Cpp
323 -------------------------------------------------------------------------------------------------
320 -------------------------------------------------------------------------------------------------
324 fnToLambda (CppFunction name args _ qs body) =
321 fnToLambda (CppFunction name args _ qs body) =
325 CppVariableIntroduction
322 CppVariableIntroduction
326− (name, Just $ Any [Const])
323+ (name, Just $ Any [Const])
327− (filter (==Static) qs)
324+ (filter (== Static) qs)
328− (Just $ CppLambda cs args (Just $ Any []) body)
325+ (Just $ CppLambda cs args (Just $ Any []) body)
329 where
326 where
327+ cs
330− cs | (not . null) (qs `intersect` [Inline, Static]) = []
328+ | (not . null) (qs `intersect` [Inline, Static]) = []
331− | otherwise = [CaptureAll]
329+ | otherwise = [CaptureAll]
332 fnToLambda (CppComment com cpp) = CppComment com (fnToLambda cpp)
330 fnToLambda (CppComment com cpp) = CppComment com (fnToLambda cpp)
333 fnToLambda _ = error "Not a function!"
331 fnToLambda _ = error "Not a function!"
334−
335 -------------------------------------------------------------------------------------------------
332 -------------------------------------------------------------------------------------------------
336 innerLambdas :: Cpp -> Cpp
333 innerLambdas :: Cpp -> Cpp
337 -------------------------------------------------------------------------------------------------
334 -------------------------------------------------------------------------------------------------
@@ -341,7 +338,6 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
341 go f@(CppFunction {}) = maybeRemCaps $ fnToLambda f
338 go f@(CppFunction {}) = maybeRemCaps $ fnToLambda f
342 go (CppLambda _ args rtyp body) = maybeRemCaps $ CppLambda [CaptureAll] args rtyp body
339 go (CppLambda _ args rtyp body) = maybeRemCaps $ CppLambda [CaptureAll] args rtyp body
343 go cpp = cpp
340 go cpp = cpp
344−
345 -------------------------------------------------------------------------------------------------
341 -------------------------------------------------------------------------------------------------
346 convertRecursiveFns :: [Cpp] -> Cpp -> [Cpp]
342 convertRecursiveFns :: [Cpp] -> Cpp -> [Cpp]
347 -------------------------------------------------------------------------------------------------
343 -------------------------------------------------------------------------------------------------
@@ -350,82 +346,74 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
350 where
346 where
351 cpps' = everywhereOnCpp removeRec <$> cpps
347 cpps' = everywhereOnCpp removeRec <$> cpps
352 allCpps = CppBlock $ otherCpp : cpps'
348 allCpps = CppBlock $ otherCpp : cpps'
353−
354 fns :: [(String, Cpp)]
349 fns :: [(String, Cpp)]
355 fns = toelem <$> concatMap (everythingOnCpp (++) recursive) cpps
350 fns = toelem <$> concatMap (everythingOnCpp (++) recursive) cpps
356−
357 filteredFns :: Cpp -> [(String, Cpp)]
351 filteredFns :: Cpp -> [(String, Cpp)]
358− filteredFns cpp = filter (\(f,_) -> everythingOnCpp (||) (== CppVar f) cpp) fns
352+ filteredFns cpp = filter (\(f, _) -> everythingOnCpp (||) (== CppVar f) cpp) fns
359−
360 recursive :: Cpp -> [Cpp]
353 recursive :: Cpp -> [Cpp]
361− recursive cpp'@(CppFunction _ _ _ qs _) | Recursive `elem` qs = [cpp']
354+ recursive cpp'@(CppFunction _ _ _ qs _)
355+ | Recursive `elem` qs = [cpp']
362− recursive cpp'@(CppVariableIntroduction _ qs _) | Recursive `elem` qs = [cpp']
356+ recursive cpp'@(CppVariableIntroduction _ qs _)
357+ | Recursive `elem` qs = [cpp']
363 recursive _ = []
358 recursive _ = []
364−
365 removeRec :: Cpp -> Cpp
359 removeRec :: Cpp -> Cpp
366− removeRec (CppFunction _ _ _ qs _) | Recursive `elem` qs = CppNoOp
360+ removeRec (CppFunction _ _ _ qs _)
361+ | Recursive `elem` qs = CppNoOp
367− removeRec (CppVariableIntroduction _ qs _) | Recursive `elem` qs = CppNoOp
362+ removeRec (CppVariableIntroduction _ qs _)
363+ | Recursive `elem` qs = CppNoOp
368 removeRec cpp' = cpp'
364 removeRec cpp' = cpp'
369−
370 replaceVar :: [(String, Cpp)] -> Cpp -> Cpp
365 replaceVar :: [(String, Cpp)] -> Cpp -> Cpp
371 replaceVar rs = go
366 replaceVar rs = go
372 where
367 where
368+ go (CppVar var)
373− go (CppVar var) | Just var' <- lookup var rs = var'
369+ | Just var' <- lookup var rs = var'
374 go cpp' = cpp'
370 go cpp' = cpp'
375−
376 dict :: Cpp
371 dict :: Cpp
372+ dict =
377− dict = CppVariableIntroduction
373+ CppVariableIntroduction
378− (topdict, Just $ Any [Const])
374+ (topdict, Just $ Any [Const])
379− []
375+ []
380− (Just $ CppDataLiteral ((\(f,cpp) -> CppComment [LineComment f] cpp) <$> fns))
376+ (Just $ CppDataLiteral ((\(f, cpp) -> CppComment [LineComment f] cpp) <$> fns))
381−
382 accessed :: String -> String -> (String, Cpp)
377 accessed :: String -> String -> (String, Cpp)
383 accessed dictname name =
378 accessed dictname name =
379+ ( name
384− (name, CppApp
380+ , CppApp
385− (CppIndexer
381+ (CppIndexer
386− (CppNumericLiteral .
387− Left .
388− fromIntegral .
389− fromJust $ findIndex ((== name) . fst) fns)
382+ (CppNumericLiteral . Left . fromIntegral . fromJust $ findIndex ((== name) . fst) fns)
390− dict'')
383+ dict'')
391− [dict'])
384+ [dict'])
392 where
385 where
393 dict' = CppVar dictname
386 dict' = CppVar dictname
394 dict'' = CppCast (dataType 1) dict'
387 dict'' = CppCast (dataType 1) dict'
395−
396 accessor :: String -> (String, Cpp) -> Cpp
388 accessor :: String -> (String, Cpp) -> Cpp
397 accessor dictname (name, _) =
389 accessor dictname (name, _) =
398− CppVariableIntroduction
399− (name, Just $ Any [Const])
400− []
401− (Just . snd $ accessed dictname name)
390+ CppVariableIntroduction (name, Just $ Any [Const]) [] (Just . snd $ accessed dictname name)
402−
403 toelem :: Cpp -> (String, Cpp)
391 toelem :: Cpp -> (String, Cpp)
404 toelem (CppFunction name args rtyp _ body'@(CppBlock body)) =
392 toelem (CppFunction name args rtyp _ body'@(CppBlock body)) =
393+ ( name
405− (name, withdict . maybeRemCaps $ CppLambda
394+ , withdict . maybeRemCaps $
395+ CppLambda
406− [CaptureAll]
396+ [CaptureAll]
407− args
397+ args
408− rtyp
398+ rtyp
409− (CppBlock $ (accessor localdict <$> filteredFns body') ++ body))
399+ (CppBlock $ (accessor localdict <$> filteredFns body') ++ body))
410−
411 toelem (CppVariableIntroduction (name, _) _ (Just body')) =
400 toelem (CppVariableIntroduction (name, _) _ (Just body')) =
412 let replacements = accessed localdict . fst <$> filteredFns body'
401 let replacements = accessed localdict . fst <$> filteredFns body'
413 replaced = everywhereOnCpp (replaceVar replacements) body'
402 replaced = everywhereOnCpp (replaceVar replacements) body'
414 in (name, withdict . maybeRemCaps $ CppBlock [CppReturn replaced])
403 in (name, withdict . maybeRemCaps $ CppBlock [CppReturn replaced])
415−
416 toelem _ = error "not a function"
404 toelem _ = error "not a function"
417−
418 withdict :: Cpp -> Cpp
405 withdict :: Cpp -> Cpp
406+ withdict cpp' =
419− withdict cpp' = maybeRemCaps $ CppLambda
407+ maybeRemCaps $
408+ CppLambda
420− [CaptureAll]
409+ [CaptureAll]
421− [(localdict, Just $ Any [Const, Ref])]
410+ [(localdict, Just $ Any [Const, Ref])]
422− (Just $ Any [])
411+ (Just $ Any [])
423− (returnBlock cpp')
412+ (returnBlock cpp')
424 topdict :: String
413 topdict :: String
425 topdict = "_$dict$_"
414 topdict = "_$dict$_"
426 localdict :: String
415 localdict :: String
427 localdict = "$dict$"
416 localdict = "$dict$"
428−
429 convertRecursiveFns cpps _ = cpps
417 convertRecursiveFns cpps _ = cpps
430
418
431 -- |
419 -- |
@@ -434,126 +422,98 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
434 -------------------------------------------------------------------------------------------------
422 -------------------------------------------------------------------------------------------------
435 valueToCpp :: Expr Ann -> m Cpp
423 valueToCpp :: Expr Ann -> m Cpp
436 -------------------------------------------------------------------------------------------------
424 -------------------------------------------------------------------------------------------------
437− valueToCpp (Var (_, _, _, Just IsNewtype) ident) =
425+ valueToCpp (Var (_, _, _, Just IsNewtype) ident) = return $ varToCpp ident
438− return $ varToCpp ident
439−
440− valueToCpp (Var (_, _, _, Just (IsConstructor _ [])) ident) =
426+ valueToCpp (Var (_, _, _, Just (IsConstructor _ [])) ident) = return $ CppApp (varToCpp ident) []
441− return $ CppApp (varToCpp ident) []
442−
443 valueToCpp (Var (_, _, Just ty, _) ident@(Qualified (Just _) _))
427 valueToCpp (Var (_, _, Just ty, _) ident@(Qualified (Just _) _))
444− | arity ty > 0 =
445− return . curriedName' $ varToCpp ident
428+ | arity ty > 0 = return . curriedName' $ varToCpp ident
446−
447− valueToCpp (Var _ ident) =
429+ valueToCpp (Var _ ident) = return $ varToCpp ident
448− return $ varToCpp ident
449−
450− valueToCpp (Literal _ (NumericLiteral n)) =
430+ valueToCpp (Literal _ (NumericLiteral n)) = return (CppNumericLiteral n)
451− return (CppNumericLiteral n)
452−
453− valueToCpp (Literal _ (StringLiteral s)) =
431+ valueToCpp (Literal _ (StringLiteral s)) = return (CppStringLiteral s)
454− return (CppStringLiteral s)
455−
456− valueToCpp (Literal _ (CharLiteral c)) =
432+ valueToCpp (Literal _ (CharLiteral c)) = return (CppCharLiteral c)
457− return (CppCharLiteral c)
458−
459− valueToCpp (Literal _ (BooleanLiteral b)) =
433+ valueToCpp (Literal _ (BooleanLiteral b)) = return (CppBooleanLiteral b)
460− return (CppBooleanLiteral b)
461−
462− valueToCpp (Literal _ (ArrayLiteral xs)) =
434+ valueToCpp (Literal _ (ArrayLiteral xs)) = CppArrayLiteral <$> mapM valueToCpp xs
463− CppArrayLiteral <$> mapM valueToCpp xs
464−
465 valueToCpp (Literal _ (ObjectLiteral ps)) =
435 valueToCpp (Literal _ (ObjectLiteral ps)) =
466 CppMapLiteral Record <$>
436 CppMapLiteral Record <$>
467− mapM (sndM valueToCpp) ((\(k,v) -> (CppSymbol k, v)) <$> sortBy (compare `on` fst) ps)
437+ mapM (sndM valueToCpp) ((\(k, v) -> (CppSymbol k, v)) <$> sortBy (compare `on` fst) ps)
468−
469− valueToCpp (Accessor _ prop val) =
470− CppIndexer <$> pure (CppSymbol prop) <*> valueToCpp val
438+ valueToCpp (Accessor _ prop val) = CppIndexer <$> pure (CppSymbol prop) <*> valueToCpp val
471−
472 -- TODO: use a more efficient way of copying/updating the map?
439 -- TODO: use a more efficient way of copying/updating the map?
473 valueToCpp (ObjectUpdate (_, _, Just ty, _) obj ps) = do
440 valueToCpp (ObjectUpdate (_, _, Just ty, _) obj ps) = do
474 obj' <- valueToCpp obj
441 obj' <- valueToCpp obj
475 updatedFields <- mapM (sndM valueToCpp) ps
442 updatedFields <- mapM (sndM valueToCpp) ps
476 let origKeys = (allKeys ty) \\ (fst <$> updatedFields)
443 let origKeys = (allKeys ty) \\ (fst <$> updatedFields)
477 origFields = (\key -> (key, CppIndexer (CppSymbol key) obj')) <$> origKeys
444 origFields = (\key -> (key, CppIndexer (CppSymbol key) obj')) <$> origKeys
445+ return $
478− return $ CppMapLiteral Record $
446+ CppMapLiteral Record $
479− (\(k,v) -> (CppSymbol k, v)) <$> sortBy (compare `on` fst) (origFields ++ updatedFields)
447+ (\(k, v) -> (CppSymbol k, v)) <$> sortBy (compare `on` fst) (origFields ++ updatedFields)
480 where
448 where
481 allKeys :: T.Type -> [String]
449 allKeys :: T.Type -> [String]
482 allKeys (T.TypeApp (T.TypeConstructor _) r@(T.RCons {})) = fst <$> (fst $ T.rowToList r)
450 allKeys (T.TypeApp (T.TypeConstructor _) r@(T.RCons {})) = fst <$> (fst $ T.rowToList r)
483 allKeys (T.ForAll _ t _) = allKeys t
451 allKeys (T.ForAll _ t _) = allKeys t
484 allKeys _ = error $ show "Not a recognized row type"
452 allKeys _ = error $ show "Not a recognized row type"
485−
486 valueToCpp (ObjectUpdate _ _ _) = error $ "Bad Type in object update!"
453 valueToCpp (ObjectUpdate _ _ _) = error $ "Bad Type in object update!"
487−
488 valueToCpp (Abs (_, _, ty, _) arg body) = do
454 valueToCpp (Abs (_, _, ty, _) arg body) = do
489 cpp <- valueToCpp body
455 cpp <- valueToCpp body
490 let cpp' = innerLambdas cpp
456 let cpp' = innerLambdas cpp
491 return $
457 return $
492 CppLambda
458 CppLambda
493− []
459+ []
494− [(identToCpp arg, Just $ Any [Const, Ref])]
460+ [(identToCpp arg, Just $ Any [Const, Ref])]
495− (Just $ Any [])
461+ (Just $ Any [])
496− (returnBlock $ optIndexers classes cpp')
462+ (returnBlock $ optIndexers classes cpp')
497 where
463 where
498− arg' = identToCpp arg
464+ arg' = identToCpp arg
499− args' = identToCpp <$> (fst $ unAbs body [])
465+ args' = identToCpp <$> (fst $ unAbs body [])
466+ classes =
467+ zip
500− classes = zip (CppVar <$> arg' : args')
468+ (CppVar <$> arg' : args')
501− (qualifiedToCpp (Ident . runProperName) . T.constraintClass <$> maybe [] extractConstraints ty)
469+ (qualifiedToCpp (Ident . runProperName) . T.constraintClass <$>
502−
470+ maybe [] extractConstraints ty)
503− valueToCpp e@App{} = do
471+ valueToCpp e@App {} = do
504 let (f, args) = unApp e []
472 let (f, args) = unApp e []
505 args' <- mapM valueToCpp args
473 args' <- mapM valueToCpp args
506 case f of
474 case f of
507 Var (_, _, _, Just IsNewtype) _ -> return (head args')
475 Var (_, _, _, Just IsNewtype) _ -> return (head args')
508 Var (_, _, _, Just IsTypeClassConstructor) (Qualified mn' (Ident classname)) ->
476 Var (_, _, _, Just IsTypeClassConstructor) (Qualified mn' (Ident classname)) ->
509− let Just (_, constraints, fns) = findClass (Qualified mn' (ProperName classname)) in
477+ let Just (_, constraints, fns) = findClass (Qualified mn' (ProperName classname))
510− return . CppMapLiteral Instance $
478+ in return . CppMapLiteral Instance $
511− zip
512− (CppSymbol <$> (sort $ superClassDictionaryNames constraints) ++ (fst <$> fns))
479+ zip (CppSymbol <$> (sort $ superClassDictionaryNames constraints) ++ (fst <$> fns)) args'
513− args'
514 Var _ (Qualified (Just _) _) -> applied f args' curriedName'
480 Var _ (Qualified (Just _) _) -> applied f args' curriedName'
515 _ -> applied f args' id
481 _ -> applied f args' id
516 where
482 where
517 applied f args g = flip (foldl (\fn a -> CppApp (g fn) [a])) args <$> valueToCpp f
483 applied f args g = flip (foldl (\fn a -> CppApp (g fn) [a])) args <$> valueToCpp f
518−
519 valueToCpp (Case (maybeSpan, _, ty, _) values binders) = do
484 valueToCpp (Case (maybeSpan, _, ty, _) values binders) = do
520 vals <- mapM valueToCpp values
485 vals <- mapM valueToCpp values
521 bindersToCpp maybeSpan ty binders vals
486 bindersToCpp maybeSpan ty binders vals
522−
523 valueToCpp (Let _ ds val) = do
487 valueToCpp (Let _ ds val) = do
524 ds' <- concat <$> mapM (bindToCpp []) ds
488 ds' <- concat <$> mapM (bindToCpp []) ds
525 ret <- valueToCpp val
489 ret <- valueToCpp val
526 opts <- ask
490 opts <- ask
527 let ds'' = tco opts <$> ds'
491 let ds'' = tco opts <$> ds'
492+ let rs =
528− let rs = if hasRecursion ds''
493+ if hasRecursion ds''
529− then convertRecursiveFns ds'' ret
494+ then convertRecursiveFns ds'' ret
530− else ds''
495+ else ds''
531 let cpps = innerLambdas <$> rs
496 let cpps = innerLambdas <$> rs
532− return $ CppApp
533− (CppLambda [] [] Nothing (CppBlock (cpps ++ [CppReturn ret])))
497+ return $ CppApp (CppLambda [] [] Nothing (CppBlock (cpps ++ [CppReturn ret]))) []
534− []
535 where
498 where
536 hasRecursion :: [Cpp] -> Bool
499 hasRecursion :: [Cpp] -> Bool
537 hasRecursion cpps' = any (everythingOnCpp (||) hasRecursiveRef) cpps'
500 hasRecursion cpps' = any (everythingOnCpp (||) hasRecursiveRef) cpps'
538 where
501 where
539 valnames :: [String]
502 valnames :: [String]
540− valnames = concatMap (everythingOnCpp (++) valname) cpps'
503+ valnames = concatMap (everythingOnCpp (++) valname) cpps'
541−
542 valname :: Cpp -> [String]
504 valname :: Cpp -> [String]
543 valname (CppFunction name _ _ _ _) = [name]
505 valname (CppFunction name _ _ _ _) = [name]
544 valname (CppVariableIntroduction (name, _) _ _) = [name]
506 valname (CppVariableIntroduction (name, _) _ _) = [name]
545 valname _ = []
507 valname _ = []
546−
547 hasRecursiveRef :: Cpp -> Bool
508 hasRecursiveRef :: Cpp -> Bool
548 hasRecursiveRef (CppFunction _ _ _ _ body) = everythingOnCpp (||) ref body
509 hasRecursiveRef (CppFunction _ _ _ _ body) = everythingOnCpp (||) ref body
549 hasRecursiveRef (CppVariableIntroduction _ _ (Just value)) = everythingOnCpp (||) ref value
510 hasRecursiveRef (CppVariableIntroduction _ _ (Just value)) = everythingOnCpp (||) ref value
550 hasRecursiveRef _ = False
511 hasRecursiveRef _ = False
551−
552 ref :: Cpp -> Bool
512 ref :: Cpp -> Bool
513+ ref (CppVar name)
553− ref (CppVar name) | name `elem` valnames = True
514+ | name `elem` valnames = True
554 ref _ = False
515 ref _ = False
555−
556− valueToCpp Constructor{} = return CppNoOp
516+ valueToCpp Constructor {} = return CppNoOp
557
517
558 -- |
518 -- |
559 -- Generate code in the simplified C++1x intermediate representation for a reference to a
519 -- Generate code in the simplified C++1x intermediate representation for a reference to a
@@ -575,42 +535,41 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
575 bindersToCpp maybeSpan _ binders vals = do
535 bindersToCpp maybeSpan _ binders vals = do
576 valNames <- replicateM (length vals) freshName
536 valNames <- replicateM (length vals) freshName
577 let assignments = zipWith mkVarDecl valNames (map Just vals)
537 let assignments = zipWith mkVarDecl valNames (map Just vals)
538+ cpps <-
578− cpps <- forM binders $ \(CaseAlternative bs result) -> do
539+ forM binders $ \(CaseAlternative bs result) -> do
579− ret <- guardsToCpp result
540+ ret <- guardsToCpp result
580− go valNames ret bs
541+ go valNames ret bs
581 return $
542 return $
582 CppApp
543 CppApp
583 (CppLambda
544 (CppLambda
584− []
545+ []
585− []
546+ []
586− (Just $ Any [])
547+ (Just $ Any [])
587− (CppBlock (assignments ++ concat cpps ++ [failedPatternError valNames])))
548+ (CppBlock (assignments ++ concat cpps ++ [failedPatternError valNames])))
588 []
549 []
589 where
550 where
590− mkVarDecl :: String -> Maybe Cpp -> Cpp
551+ mkVarDecl :: String -> Maybe Cpp -> Cpp
591− mkVarDecl name = CppVariableIntroduction (name, Nothing) []
552+ mkVarDecl name = CppVariableIntroduction (name, Nothing) []
592− go :: [String] -> [Cpp] -> [Binder Ann] -> m [Cpp]
553+ go :: [String] -> [Cpp] -> [Binder Ann] -> m [Cpp]
593− go _ done [] = return done
554+ go _ done [] = return done
594− go (v:vs) done' (b:bs) = do
555+ go (v:vs) done' (b:bs) = do
595− done'' <- go vs done' bs
556+ done'' <- go vs done' bs
596− binderToCpp v done'' b
557+ binderToCpp v done'' b
597− go _ _ _ = error "Invalid arguments to bindersToCpp"
558+ go _ _ _ = error "Invalid arguments to bindersToCpp"
598−
599− failedPatternError :: [String] -> Cpp
559+ failedPatternError :: [String] -> Cpp
600− failedPatternError _ =
560+ failedPatternError _ =
601− CppThrow $ CppApp (CppVar "runtime_error") [CppStringLiteral errorMessage]
561+ CppThrow $ CppApp (CppVar "runtime_error") [CppStringLiteral errorMessage]
602−
603− errorMessage :: String
562+ errorMessage :: String
563+ errorMessage =
604− errorMessage = "Failed pattern match" ++
564+ "Failed pattern match" ++
605− maybe "" (((" at " ++ runModuleName mn ++ " ") ++) . displayStartEndPos) maybeSpan ++
565+ maybe "" (((" at " ++ runModuleName mn ++ " ") ++) . displayStartEndPos) maybeSpan ++ ": "
606− ": "
607−
608− guardsToCpp :: Either [(Guard Ann, Expr Ann)] (Expr Ann) -> m [Cpp]
566+ guardsToCpp :: Either [(Guard Ann, Expr Ann)] (Expr Ann) -> m [Cpp]
609− guardsToCpp (Left gs) = forM gs $ \(cond, val) -> do
567+ guardsToCpp (Left gs) =
568+ forM gs $ \(cond, val) -> do
610 cond' <- valueToCpp cond
569 cond' <- valueToCpp cond
611− done <- valueToCpp val
570+ done <- valueToCpp val
612 return $ CppIfElse cond' (returnBlock done) Nothing
571 return $ CppIfElse cond' (returnBlock done) Nothing
613− guardsToCpp (Right v) = return . CppReturn <$> valueToCpp v
572+ guardsToCpp (Right v) = return . CppReturn <$> valueToCpp v
614
573
615 -- |
574 -- |
616 -- Generate code in the simplified C++1x intermediate representation for a pattern match
575 -- Generate code in the simplified C++1x intermediate representation for a pattern match
@@ -619,112 +578,85 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
619 -------------------------------------------------------------------------------------------------
578 -------------------------------------------------------------------------------------------------
620 binderToCpp :: String -> [Cpp] -> Binder Ann -> m [Cpp]
579 binderToCpp :: String -> [Cpp] -> Binder Ann -> m [Cpp]
621 -------------------------------------------------------------------------------------------------
580 -------------------------------------------------------------------------------------------------
622− binderToCpp _ done (NullBinder{}) = return done
581+ binderToCpp _ done (NullBinder {}) = return done
623−
624− binderToCpp varName done (LiteralBinder _ l) =
582+ binderToCpp varName done (LiteralBinder _ l) = literalToBinderCpp varName done l
625− literalToBinderCpp varName done l
626−
627 binderToCpp varName done (VarBinder _ ident) =
583 binderToCpp varName done (VarBinder _ ident) =
628 return $
584 return $
629− CppVariableIntroduction
630− (identToCpp ident, Just $ Any [Const])
585+ CppVariableIntroduction (identToCpp ident, Just $ Any [Const]) [] (Just $ CppVar varName) : done
631− []
632− (Just $ CppVar varName)
633− : done
634−
635 binderToCpp varName done (ConstructorBinder (_, _, _, Just IsNewtype) _ _ [b]) =
586 binderToCpp varName done (ConstructorBinder (_, _, _, Just IsNewtype) _ _ [b]) =
636 binderToCpp varName done b
587 binderToCpp varName done b
637−
638− binderToCpp varName done (ConstructorBinder (_, _, _, Just (IsConstructor ctorType fields))
588+ binderToCpp varName done (ConstructorBinder (_, _, _, Just (IsConstructor ctorType fields)) _ (Qualified mn' (ProperName ctor)) bs) = do
639− _
640− (Qualified mn' (ProperName ctor))
641− bs) = do
642 cpps <- go (zip fields bs) done
589 cpps <- go (zip fields bs) done
643 return $
590 return $
644 case ctorType of
591 case ctorType of
645 ProductType -> cpps
592 ProductType -> cpps
646 SumType ->
593 SumType ->
647− [ CppIfElse
594+ [ CppIfElse
648− (CppBinary
595+ (CppBinary
649− EqualTo
596+ EqualTo
650− (CppIndexer
651− (CppVar ctorKey)
652− (CppCast (dataType 1) $ CppVar varName))
597+ (CppIndexer (CppVar ctorKey) (CppCast (dataType 1) $ CppVar varName))
653− ctorCpp)
598+ ctorCpp)
654− (CppBlock cpps)
599+ (CppBlock cpps)
655− Nothing]
600+ Nothing
601+ ]
656 where
602 where
657 go :: [(Ident, Binder Ann)] -> [Cpp] -> m [Cpp]
603 go :: [(Ident, Binder Ann)] -> [Cpp] -> m [Cpp]
658 go [] done' = return done'
604 go [] done' = return done'
659− go ((field, binder) : remain) done' = do
605+ go ((field, binder):remain) done' = do
660 argVar <- freshName
606 argVar <- freshName
661 done'' <- go remain done'
607 done'' <- go remain done'
662 cpps <- binderToCpp argVar done'' binder
608 cpps <- binderToCpp argVar done'' binder
663 return $
609 return $
664 CppVariableIntroduction
610 CppVariableIntroduction
665− (argVar, Nothing)
611+ (argVar, Nothing)
666− []
612+ []
613+ (Just $
667− (Just $ CppIndexer
614+ CppIndexer
668− (fieldToIndex' field)
615+ (fieldToIndex' field)
669− (CppCast (dataType $ fieldToIndex field + 1) $ CppVar varName))
616+ (CppCast (dataType $ fieldToIndex field + 1) $ CppVar varName)) :
670− : cpps
617+ cpps
671 fieldToIndex :: Ident -> Int
618 fieldToIndex :: Ident -> Int
672− fieldToIndex = (+1) . read . dropWhile isLetter . runIdent
619+ fieldToIndex = (+ 1) . read . dropWhile isLetter . runIdent
673 fieldToIndex' :: Ident -> Cpp
620 fieldToIndex' :: Ident -> Cpp
674 fieldToIndex' = CppNumericLiteral . Left . toInteger . fieldToIndex
621 fieldToIndex' = CppNumericLiteral . Left . toInteger . fieldToIndex
675 ctor' :: Cpp
622 ctor' :: Cpp
676 ctor' = CppAccessor (CppVar . identToCpp $ Ident ctor) (CppVar "data")
623 ctor' = CppAccessor (CppVar . identToCpp $ Ident ctor) (CppVar "data")
677 ctorCpp :: Cpp
624 ctorCpp :: Cpp
625+ ctorCpp
626+ | Just mn'' <- mn'
678− ctorCpp | Just mn'' <- mn', mn'' /= mn = CppAccessor ctor' (CppVar $ moduleNameToCpp mn'')
627+ , mn'' /= mn = CppAccessor ctor' (CppVar $ moduleNameToCpp mn'')
679− | otherwise = ctor'
628+ | otherwise = ctor'
680−
681− binderToCpp _ _ b@(ConstructorBinder{}) =
629+ binderToCpp _ _ b@(ConstructorBinder {}) =
682 error $ "Invalid ConstructorBinder in binderToCpp: " ++ show b
630 error $ "Invalid ConstructorBinder in binderToCpp: " ++ show b
683−
684 binderToCpp varName done (NamedBinder _ ident binder) = do
631 binderToCpp varName done (NamedBinder _ ident binder) = do
685 cpp <- binderToCpp varName done binder
632 cpp <- binderToCpp varName done binder
686 return $
633 return $
687− CppVariableIntroduction
688− (identToCpp ident, Just $ Any [Const])
634+ CppVariableIntroduction (identToCpp ident, Just $ Any [Const]) [] (Just $ CppVar varName) :
689− []
690− (Just $ CppVar varName)
691− : cpp
635+ cpp
692−
693 -------------------------------------------------------------------------------------------------
636 -------------------------------------------------------------------------------------------------
694 literalToBinderCpp :: String -> [Cpp] -> Literal (Binder Ann) -> m [Cpp]
637 literalToBinderCpp :: String -> [Cpp] -> Literal (Binder Ann) -> m [Cpp]
695 -------------------------------------------------------------------------------------------------
638 -------------------------------------------------------------------------------------------------
696 literalToBinderCpp varName done (NumericLiteral num) =
639 literalToBinderCpp varName done (NumericLiteral num) =
640+ return
697− return [ CppIfElse
641+ [ CppIfElse
698− (CppBinary EqualTo (CppVar varName) (CppNumericLiteral num))
642+ (CppBinary EqualTo (CppVar varName) (CppNumericLiteral num))
699− (CppBlock done)
643+ (CppBlock done)
700− Nothing ]
644+ Nothing
701−
645+ ]
702 literalToBinderCpp varName done (CharLiteral c) =
646 literalToBinderCpp varName done (CharLiteral c) =
703− return [ CppIfElse
647+ return
704− (CppBinary EqualTo (CppVar varName) (CppCharLiteral c))
648+ [CppIfElse (CppBinary EqualTo (CppVar varName) (CppCharLiteral c)) (CppBlock done) Nothing]
705− (CppBlock done)
706− Nothing ]
707−
708 literalToBinderCpp varName done (StringLiteral str) =
649 literalToBinderCpp varName done (StringLiteral str) =
650+ return
709− return [ CppIfElse
651+ [ CppIfElse
710− (CppBinary EqualTo (CppVar varName) (CppStringLiteral str))
652+ (CppBinary EqualTo (CppVar varName) (CppStringLiteral str))
711− (CppBlock done)
653+ (CppBlock done)
712− Nothing ]
654+ Nothing
713−
655+ ]
714 literalToBinderCpp varName done (BooleanLiteral True) =
656 literalToBinderCpp varName done (BooleanLiteral True) =
715− return [ CppIfElse
657+ return [CppIfElse (CppVar varName) (CppBlock done) Nothing]
716− (CppVar varName)
717− (CppBlock done)
718− Nothing ]
719−
720 literalToBinderCpp varName done (BooleanLiteral False) =
658 literalToBinderCpp varName done (BooleanLiteral False) =
721− return [ CppIfElse
659+ return [CppIfElse (CppUnary Not (CppVar varName)) (CppBlock done) Nothing]
722− (CppUnary
723− Not
724− (CppVar varName))
725− (CppBlock done)
726− Nothing ]
727−
728 literalToBinderCpp varName done (ObjectLiteral bs) = go done bs
660 literalToBinderCpp varName done (ObjectLiteral bs) = go done bs
729 where
661 where
730 go :: [Cpp] -> [(String, Binder Ann)] -> m [Cpp]
662 go :: [Cpp] -> [(String, Binder Ann)] -> m [Cpp]
@@ -735,27 +667,22 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
735 cpp <- binderToCpp propVar done'' binder
667 cpp <- binderToCpp propVar done'' binder
736 return $
668 return $
737 CppVariableIntroduction
669 CppVariableIntroduction
738− (propVar, Nothing)
670+ (propVar, Nothing)
739− []
671+ []
740− (Just $ CppIndexer
672+ (Just $ CppIndexer (CppSymbol prop) (CppVar varName)) :
741− (CppSymbol prop)
742− (CppVar varName))
743− : cpp
673+ cpp
744−
745 literalToBinderCpp varName done (ArrayLiteral bs) = do
674 literalToBinderCpp varName done (ArrayLiteral bs) = do
746 cpp <- go done 0 bs
675 cpp <- go done 0 bs
747 let cond =
676 let cond =
748 case length bs of
677 case length bs of
749− 0 -> CppBinary
750− Dot
751− (CppCast arrayType $ CppVar varName)
678+ 0 -> CppBinary Dot (CppCast arrayType $ CppVar varName) (CppApp (CppVar "empty") [])
752− (CppApp (CppVar "empty") [])
679+ n ->
753− n -> let var = CppCast arrayType $ CppVar varName
680+ let var = CppCast arrayType $ CppVar varName
754− in CppBinary
681+ in CppBinary
755− EqualTo
682+ EqualTo
756− (CppBinary Dot var (CppApp (CppVar "size") []))
683+ (CppBinary Dot var (CppApp (CppVar "size") []))
757− (CppNumericLiteral (Left (fromIntegral n)))
684+ (CppNumericLiteral (Left (fromIntegral n)))
758− return [ CppIfElse cond (CppBlock cpp) Nothing ]
685+ return [CppIfElse cond (CppBlock cpp) Nothing]
759 where
686 where
760 go :: [Cpp] -> Integer -> [Binder Ann] -> m [Cpp]
687 go :: [Cpp] -> Integer -> [Binder Ann] -> m [Cpp]
761 go done' _ [] = return done'
688 go done' _ [] = return done'
@@ -765,25 +692,20 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
765 cpp <- binderToCpp elVar done'' binder
692 cpp <- binderToCpp elVar done'' binder
766 return $
693 return $
767 CppVariableIntroduction
694 CppVariableIntroduction
768− (elVar, Nothing)
695+ (elVar, Nothing)
769− []
696+ []
770− (Just $ CppIndexer
771− (CppNumericLiteral (Left index))
697+ (Just $ CppIndexer (CppNumericLiteral (Left index)) (CppVar varName)) :
772− (CppVar varName))
773− : cpp
698+ cpp
774−
775 -------------------------------------------------------------------------------------------------
699 -------------------------------------------------------------------------------------------------
776 unApp :: Expr Ann -> [Expr Ann] -> (Expr Ann, [Expr Ann])
700 unApp :: Expr Ann -> [Expr Ann] -> (Expr Ann, [Expr Ann])
777 -------------------------------------------------------------------------------------------------
701 -------------------------------------------------------------------------------------------------
778 unApp (App _ val arg) args = unApp val (arg : args)
702 unApp (App _ val arg) args = unApp val (arg : args)
779 unApp other args = (other, args)
703 unApp other args = (other, args)
780−
781 -------------------------------------------------------------------------------------------------
704 -------------------------------------------------------------------------------------------------
782 unAbs :: Expr Ann -> [Ident] -> ([Ident], Expr Ann)
705 unAbs :: Expr Ann -> [Ident] -> ([Ident], Expr Ann)
783 -------------------------------------------------------------------------------------------------
706 -------------------------------------------------------------------------------------------------
784 unAbs (Abs _ arg val) args = unAbs val (args ++ [arg])
707 unAbs (Abs _ arg val) args = unAbs val (args ++ [arg])
785 unAbs other args = (args, other)
708 unAbs other args = (args, other)
786−
787 -------------------------------------------------------------------------------------------------
709 -------------------------------------------------------------------------------------------------
788 qualifiedToCpp :: (a -> Ident) -> Qualified a -> Cpp
710 qualifiedToCpp :: (a -> Ident) -> Qualified a -> Cpp
789 -------------------------------------------------------------------------------------------------
711 -------------------------------------------------------------------------------------------------
@@ -797,63 +719,68 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
797 -- Find a class in scope by name, retrieving its list of constraints, function names and types.
719 -- Find a class in scope by name, retrieving its list of constraints, function names and types.
798 --
720 --
799 -------------------------------------------------------------------------------------------------
721 -------------------------------------------------------------------------------------------------
800− findClass :: Qualified (ProperName 'ClassName) -> Maybe ([String], [T.Constraint], [(String, T.Type)])
722+ findClass :: Qualified (ProperName 'ClassName)
723+ -> Maybe ([String], [T.Constraint], [(String, T.Type)])
801 -------------------------------------------------------------------------------------------------
724 -------------------------------------------------------------------------------------------------
802 findClass name
725 findClass name
803− | Just tcd <- M.lookup name (E.typeClasses env),
726+ | Just tcd <- M.lookup name (E.typeClasses env)
804− fns' <- (\(i,t) -> (runIdent i, t)) <$> E.typeClassMembers tcd
727+ , fns' <- (\(i, t) -> (runIdent i, t)) <$> E.typeClassMembers tcd =
728+ Just
805− = Just (fst <$> E.typeClassArguments tcd,
729+ ( fst <$> E.typeClassArguments tcd
806− E.typeClassSuperclasses tcd,
730+ , E.typeClassSuperclasses tcd
807− (sortBy (compare `on` normalizedName . fst) fns'))
731+ , (sortBy (compare `on` normalizedName . fst) fns'))
808 findClass _ = Nothing
732 findClass _ = Nothing
809−
810 -------------------------------------------------------------------------------------------------
733 -------------------------------------------------------------------------------------------------
811 typeClassMembers :: [Ident]
734 typeClassMembers :: [Ident]
812 -------------------------------------------------------------------------------------------------
735 -------------------------------------------------------------------------------------------------
736+ typeClassMembers =
737+ fst <$>
813− typeClassMembers = fst <$> (concat . M.elems $ M.map E.typeClassMembers (M.filterWithKey thisModule (E.typeClasses env)))
738+ (concat . M.elems $ M.map E.typeClassMembers (M.filterWithKey thisModule (E.typeClasses env)))
814 where
739 where
815 thisModule (Qualified (Just mn') _) _ = mn' == mn
740 thisModule (Qualified (Just mn') _) _ = mn' == mn
816 thisModule _ _ = False
741 thisModule _ _ = False
817−
818 -------------------------------------------------------------------------------------------------
742 -------------------------------------------------------------------------------------------------
819 dataCtors :: [Cpp]
743 dataCtors :: [Cpp]
820 -------------------------------------------------------------------------------------------------
744 -------------------------------------------------------------------------------------------------
745+ dataCtors =
821− dataCtors = [CppNamespace "data"
746+ [ CppNamespace
747+ "data"
822− [CppEnum Nothing (Just intType) . ("_" :) .
748+ [ CppEnum Nothing (Just intType) . ("_" :) . catMaybes . map modCtor . M.keys $
823− catMaybes . map modCtor . M.keys $ E.dataConstructors env]]
749+ E.dataConstructors env
750+ ]
751+ ]
824 where
752 where
825 modCtor :: Qualified (ProperName a) -> Maybe String
753 modCtor :: Qualified (ProperName a) -> Maybe String
826− modCtor (Qualified (Just mn') (ProperName name)) | mn' == mn = Just $ identToCpp (Ident name)
754+ modCtor (Qualified (Just mn') (ProperName name))
755+ | mn' == mn = Just $ identToCpp (Ident name)
827 modCtor _ = Nothing
756 modCtor _ = Nothing
828−
829 -------------------------------------------------------------------------------------------------
757 -------------------------------------------------------------------------------------------------
830 curriedForeigns :: m [Cpp]
758 curriedForeigns :: m [Cpp]
831 -------------------------------------------------------------------------------------------------
759 -------------------------------------------------------------------------------------------------
832 curriedForeigns = concat <$> mapM go allForeigns
760 curriedForeigns = concat <$> mapM go allForeigns
833 where
761 where
834 go (ident, ty)
762 go (ident, ty)
835− | arity' <- arity ty,
763+ | arity' <- arity ty
836− arity' > 0 = do
764+ , arity' > 0 = do
837− let name = identToCpp ident
765+ let name = identToCpp ident
838− argNames <- replicateM arity' freshName
766+ argNames <- replicateM arity' freshName
839− return $
767+ return $
840− [ CppFunction
768+ [ CppFunction
841− (curriedName name)
769+ (curriedName name)
842− [(head argNames, Just $ Any [Const, Ref])]
770+ [(head argNames, Just $ Any [Const, Ref])]
843− (Just $ Any [])
771+ (Just $ Any [])
772+ (if arity' == 1
844− (if arity' == 1 then [Inline] else [])
773+ then [Inline]
774+ else [])
845− (returnBlock $
775+ (returnBlock $
846− curriedLambda
847− (tail argNames)
848− (CppApp (CppVar name)
776+ curriedLambda (tail argNames) (CppApp (CppVar name) (CppVar <$> argNames)))
849− (CppVar <$> argNames)))
850− ]
777+ ]
851 go _ = return []
778 go _ = return []
852−
853 allForeigns :: [(Ident, T.Type)]
779 allForeigns :: [(Ident, T.Type)]
780+ allForeigns =
854− allForeigns = map (\((Qualified _ ident), (ty, _, _)) -> (ident, ty)) .
781+ map (\((Qualified _ ident), (ty, _, _)) -> (ident, ty)) .
855− filter (\((Qualified mn' _), (_, kind, _)) -> mn' == Just mn && kind == E.External) .
782+ filter (\((Qualified mn' _), (_, kind, _)) -> mn' == Just mn && kind == E.External) . M.toList $
856− M.toList $ E.names env
783+ E.names env
857
784
858---------------------------------------------------------------------------------------------------
785---------------------------------------------------------------------------------------------------
859returnBlock :: Cpp -> Cpp
786returnBlock :: Cpp -> Cpp
@@ -863,21 +790,18 @@ returnBlock cpp = CppBlock [CppReturn cpp]
863---------------------------------------------------------------------------------------------------
790---------------------------------------------------------------------------------------------------
864curriedLambda :: [String] -> Cpp -> Cpp
791curriedLambda :: [String] -> Cpp -> Cpp
865---------------------------------------------------------------------------------------------------
792---------------------------------------------------------------------------------------------------
866−curriedLambda args ret = foldr (\arg ret' -> CppLambda
793+curriedLambda args ret =
867− [CaptureAll]
794+ foldr
795+ (\arg ret' ->
868− [(arg, Just $ Any [Const, Ref])]
796+ CppLambda [CaptureAll] [(arg, Just $ Any [Const, Ref])] (Just $ Any []) (returnBlock ret'))
869− (Just $ Any [])
797+ ret
870− (returnBlock ret')
871− ) ret args
798+ args
872
799
873---------------------------------------------------------------------------------------------------
800---------------------------------------------------------------------------------------------------
874curriedApp :: [String] -> Expr Ann -> Expr Ann
801curriedApp :: [String] -> Expr Ann -> Expr Ann
875---------------------------------------------------------------------------------------------------
802---------------------------------------------------------------------------------------------------
876−curriedApp args vals = foldl (\val arg -> App
803+curriedApp args vals =
877− nullAnn
878− val
879− (Var nullAnn . Qualified Nothing $ Ident arg))
804+ foldl (\val arg -> App nullAnn val (Var nullAnn . Qualified Nothing $ Ident arg)) vals args
880− vals args
881
805
882---------------------------------------------------------------------------------------------------
806---------------------------------------------------------------------------------------------------
883arity :: T.Type -> Int
807arity :: T.Type -> Int
@@ -885,7 +809,8 @@ arity :: T.Type -> Int
885arity = go 0
809arity = go 0
886 where
810 where
887 go arity' (T.ForAll _ t _) = go arity' t
811 go arity' (T.ForAll _ t _) = go arity' t
888− go arity' (T.TypeApp (T.TypeApp fn _) t) | fn == E.tyFunction = go (arity' + 1) t
812+ go arity' (T.TypeApp (T.TypeApp fn _) t)
813+ | fn == E.tyFunction = go (arity' + 1) t
889 go arity' (T.ConstrainedType ts t) = go (arity' + length ts) t
814 go arity' (T.ConstrainedType ts t) = go (arity' + length ts) t
890 go arity' _ = arity'
815 go arity' _ = arity'
891
816
@@ -895,29 +820,29 @@ extractConstraints :: T.Type -> [T.Constraint]
895extractConstraints = go []
820extractConstraints = go []
896 where
821 where
897 go cs (T.ForAll _ t _) = go cs t
822 go cs (T.ForAll _ t _) = go cs t
898− go cs (T.TypeApp (T.TypeApp fn _) t) | fn == E.tyFunction = go cs t
823+ go cs (T.TypeApp (T.TypeApp fn _) t)
824+ | fn == E.tyFunction = go cs t
899 go cs (T.ConstrainedType ts t) = go (cs ++ ts) t
825 go cs (T.ConstrainedType ts t) = go (cs ++ ts) t
900 go cs _ = cs
826 go cs _ = cs
901
827
902---------------------------------------------------------------------------------------------------
828---------------------------------------------------------------------------------------------------
903−optIndexers :: [(Cpp,Cpp)] -> Cpp -> Cpp
829+optIndexers :: [(Cpp, Cpp)] -> Cpp -> Cpp
904---------------------------------------------------------------------------------------------------
830---------------------------------------------------------------------------------------------------
905optIndexers classes = everywhereOnCpp dictIndexerToEnum
831optIndexers classes = everywhereOnCpp dictIndexerToEnum
906 where
832 where
907 dictIndexerToEnum :: Cpp -> Cpp
833 dictIndexerToEnum :: Cpp -> Cpp
908 dictIndexerToEnum (CppIndexer (CppSymbol prop) dict)
834 dictIndexerToEnum (CppIndexer (CppSymbol prop) dict)
909 | Just cls <- lookup dict classes =
835 | Just cls <- lookup dict classes =
910− CppBinary Dot
836+ CppBinary
911− (CppIndexer
837+ Dot
912− (CppAccessor (CppVar . identToCpp $ Ident prop) cls)
838+ (CppIndexer (CppAccessor (CppVar . identToCpp $ Ident prop) cls) (CppCast (mapType 0) dict))
913− (CppCast (mapType 0) dict))
914 (CppVar "second")
839 (CppVar "second")
915 dictIndexerToEnum cpp = cpp
840 dictIndexerToEnum cpp = cpp
916
841
917---------------------------------------------------------------------------------------------------
842---------------------------------------------------------------------------------------------------
918curriedName :: String -> String
843curriedName :: String -> String
919---------------------------------------------------------------------------------------------------
844---------------------------------------------------------------------------------------------------
920−curriedName name@('$' : _) = name
845+curriedName name@('$':_) = name
921curriedName name = '$' : name
846curriedName name = '$' : name
922
847
923---------------------------------------------------------------------------------------------------
848---------------------------------------------------------------------------------------------------
@@ -932,14 +857,20 @@ primFn :: T.Type -> ([CppType], Maybe CppType)
932---------------------------------------------------------------------------------------------------
857---------------------------------------------------------------------------------------------------
933primFn = go []
858primFn = go []
934 where
859 where
935− go ps (T.TypeApp (T.TypeApp fn a) b) | fn == E.tyFunction,
860+ go ps (T.TypeApp (T.TypeApp fn a) b)
861+ | fn == E.tyFunction
936− Just a' <- numType a = go (ps ++ [a']) b
862+ , Just a' <- numType a = go (ps ++ [a']) b
863+ go ps t
937− go ps t | Just t' <- numType t = (ps , Just t')
864+ | Just t' <- numType t = (ps, Just t')
938 go _ _ = ([], Nothing)
865 go _ _ = ([], Nothing)
939− numType t@(T.TypeConstructor {}) | t == E.tyInt = Just intType
866+ numType t@(T.TypeConstructor {})
867+ | t == E.tyInt = Just intType
940− numType t@(T.TypeConstructor {}) | t == E.tyNumber = Just doubleType
868+ numType t@(T.TypeConstructor {})
869+ | t == E.tyNumber = Just doubleType
941− numType t@(T.TypeConstructor {}) | t == E.tyBoolean = Just boolType
870+ numType t@(T.TypeConstructor {})
871+ | t == E.tyBoolean = Just boolType
942− numType t@(T.TypeConstructor {}) | t == E.tyChar = Just charType
872+ numType t@(T.TypeConstructor {})
873+ | t == E.tyChar = Just charType
943 numType _ = Nothing
874 numType _ = Nothing
944
875
945---------------------------------------------------------------------------------------------------
876---------------------------------------------------------------------------------------------------
@@ -978,11 +909,11 @@ filterInlineFuncs = everywhereOnCpp convert
978 convert :: Cpp -> Cpp
909 convert :: Cpp -> Cpp
979 convert (CppBlock []) = CppBlock []
910 convert (CppBlock []) = CppBlock []
980 convert (CppFunction n ps r qs cpp)
911 convert (CppFunction n ps r qs cpp)
981− | Inline `elem` qs,
912+ | Inline `elem` qs
982− everythingOnCpp (||) shouldRemove cpp = CppFunction n ps r (delete Inline qs) cpp
913+ , everythingOnCpp (||) shouldRemove cpp = CppFunction n ps r (delete Inline qs) cpp
983 where
914 where
984 shouldRemove :: Cpp -> Bool
915 shouldRemove :: Cpp -> Bool
985− shouldRemove CppSymbol{} = True
916+ shouldRemove CppSymbol {} = True
986− shouldRemove CppLambda{} = True
917+ shouldRemove CppLambda {} = True
987 shouldRemove _ = False
918 shouldRemove _ = False
988 convert cpp = cpp
919 convert cpp = cpp
src/Language/PureScript/CodeGen/Cpp/File.hs+62−73
@@ -12,7 +12,6 @@
12-- File generation utility functions
12-- File generation utility functions
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15−
16{-# LANGUAGE PatternGuards #-}
15{-# LANGUAGE PatternGuards #-}
17
16
18module Language.PureScript.CodeGen.Cpp.File where
17module Language.PureScript.CodeGen.Cpp.File where
@@ -36,37 +35,33 @@ toHeader = catMaybes . map go
36 go (CppNamespace name cpps)
35 go (CppNamespace name cpps)
37 | cpps'@(_:_) <- toHeader cpps = Just (CppNamespace name cpps')
36 | cpps'@(_:_) <- toHeader cpps = Just (CppNamespace name cpps')
38 | otherwise = Nothing
37 | otherwise = Nothing
39− go cpp@(CppUseNamespace{}) = Just cpp
38+ go cpp@(CppUseNamespace {}) = Just cpp
40 go (CppFunction _ _ _ qs _)
39 go (CppFunction _ _ _ qs _)
41 | Inline `elem` qs = Nothing
40 | Inline `elem` qs = Nothing
42− go (CppFunction _ [(_, atyp)] _ _ (CppBlock [CppReturn (CppApp _ [_])])) | atyp == Just (Auto [])
41+ go (CppFunction _ [(_, atyp)] _ _ (CppBlock [CppReturn (CppApp _ [_])]))
43− = Nothing
42+ | atyp == Just (Auto []) = Nothing
44 go (CppFunction name args rtyp qs _) =
43 go (CppFunction name args rtyp qs _) =
45− let args' = (\(_,t) -> ("", t)) <$> args in
44+ let args' = (\(_, t) -> ("", t)) <$> args
46− Just (CppFunction name args' rtyp qs CppNoOp)
45+ in Just (CppFunction name args' rtyp qs CppNoOp)
47− go (CppVariableIntroduction _ _ (Just CppNumericLiteral {})) =
46+ go (CppVariableIntroduction _ _ (Just CppNumericLiteral {})) = Nothing
48− Nothing
49− go (CppVariableIntroduction _ _ (Just CppStringLiteral {})) =
47+ go (CppVariableIntroduction _ _ (Just CppStringLiteral {})) = Nothing
50− Nothing
51− go (CppVariableIntroduction _ _ (Just CppBooleanLiteral {})) =
48+ go (CppVariableIntroduction _ _ (Just CppBooleanLiteral {})) = Nothing
52− Nothing
53− go (CppVariableIntroduction _ _ (Just (CppUnary _ (CppNumericLiteral {})))) =
49+ go (CppVariableIntroduction _ _ (Just (CppUnary _ (CppNumericLiteral {})))) = Nothing
54− Nothing
55 go (CppVariableIntroduction (name, _) _ (Just (CppLambda _ [] rty _))) =
50 go (CppVariableIntroduction (name, _) _ (Just (CppLambda _ [] rty _))) =
56 Just $ CppFunction name [] rty [] CppNoOp
51 Just $ CppFunction name [] rty [] CppNoOp
57−
58 -- Generate thunks for top-level values
52 -- Generate thunks for top-level values
59 go (CppVariableIntroduction (name, _) _ (Just cpp)) =
53 go (CppVariableIntroduction (name, _) _ (Just cpp)) =
60 case cpp of
54 case cpp of
61 CppMapLiteral Instance _ ->
55 CppMapLiteral Instance _ ->
62 Just $ CppFunction name [("", Just thunkMarkerType)] (Just $ Any [Const, Ref]) [] CppNoOp
56 Just $ CppFunction name [("", Just thunkMarkerType)] (Just $ Any [Const, Ref]) [] CppNoOp
63− _ ->
64− Just $ CppVariableIntroduction (name, Just $ Any [Const]) [Extern] Nothing
57+ _ -> Just $ CppVariableIntroduction (name, Just $ Any [Const]) [Extern] Nothing
65− go cpp@(CppStruct {}) =
58+ go cpp@(CppStruct {}) = Just cpp
66− Just cpp
67 go (CppComment comms cpp')
59 go (CppComment comms cpp')
60+ | Just cpp <- go cpp' =
61+ Just $
62+ case cpp of
68− | Just cpp <- go cpp' = Just $ case cpp of CppFunction {} -> cpp
63+ CppFunction {} -> cpp
69− _ -> CppComment comms cpp
64+ _ -> CppComment comms cpp
70 go _ = Nothing
65 go _ = Nothing
71
66
72---------------------------------------------------------------------------------------------------
67---------------------------------------------------------------------------------------------------
@@ -81,17 +76,13 @@ toHeaderFns = catMaybes . map go
81 go cpp@(CppFunction _ _ _ qs _)
76 go cpp@(CppFunction _ _ _ qs _)
82 | Inline `elem` qs = Just cpp
77 | Inline `elem` qs = Just cpp
83 go (CppFunction name [(_, atyp)] _ _ (CppBlock [CppReturn (CppApp cpp [_])]))
78 go (CppFunction name [(_, atyp)] _ _ (CppBlock [CppReturn (CppApp cpp [_])]))
84− | Just Auto {} <- atyp
85− = Just (CppVariableIntroduction (name, Nothing) [] (Just cpp))
79+ | Just Auto {} <- atyp = Just (CppVariableIntroduction (name, Nothing) [] (Just cpp))
86− go cpp@(CppVariableIntroduction _ _ (Just CppNumericLiteral {})) =
80+ go cpp@(CppVariableIntroduction _ _ (Just CppNumericLiteral {})) = Just cpp
87− Just cpp
88− go cpp@(CppVariableIntroduction _ _ (Just CppStringLiteral {})) =
81+ go cpp@(CppVariableIntroduction _ _ (Just CppStringLiteral {})) = Just cpp
89− Just cpp
90− go cpp@(CppVariableIntroduction _ _ (Just CppBooleanLiteral {})) =
82+ go cpp@(CppVariableIntroduction _ _ (Just CppBooleanLiteral {})) = Just cpp
91− Just cpp
92− go cpp@(CppVariableIntroduction _ _ (Just (CppUnary _ (CppNumericLiteral {})))) =
83+ go cpp@(CppVariableIntroduction _ _ (Just (CppUnary _ (CppNumericLiteral {})))) = Just cpp
93− Just cpp
84+ go (CppComment comms cpp')
94− go (CppComment comms cpp') | Just cpp <- go cpp' = Just (CppComment comms cpp)
85+ | Just cpp <- go cpp' = Just (CppComment comms cpp)
95 go _ = Nothing
86 go _ = Nothing
96
87
97---------------------------------------------------------------------------------------------------
88---------------------------------------------------------------------------------------------------
@@ -100,7 +91,8 @@ toBodyDecl :: [Cpp] -> [Cpp]
100toBodyDecl = catMaybes . map go
91toBodyDecl = catMaybes . map go
101 where
92 where
102 go :: Cpp -> Maybe Cpp
93 go :: Cpp -> Maybe Cpp
94+ go (CppComment comms cpp')
103− go (CppComment comms cpp') | Just commented <- go cpp' = Just (CppComment comms commented)
95+ | Just commented <- go cpp' = Just (CppComment comms commented)
104 go _ = Nothing
96 go _ = Nothing
105
97
106---------------------------------------------------------------------------------------------------
98---------------------------------------------------------------------------------------------------
@@ -112,28 +104,22 @@ toBody = catMaybes . map go
112 go (CppNamespace name cpps)
104 go (CppNamespace name cpps)
113 | cpps'@(_:_) <- toBody cpps = Just (CppNamespace name cpps')
105 | cpps'@(_:_) <- toBody cpps = Just (CppNamespace name cpps')
114 | otherwise = Nothing
106 | otherwise = Nothing
115− go cpp@(CppUseNamespace{}) = Just cpp
107+ go cpp@(CppUseNamespace {}) = Just cpp
116 go (CppFunction _ _ _ qs _)
108 go (CppFunction _ _ _ qs _)
117 | Inline `elem` qs = Nothing
109 | Inline `elem` qs = Nothing
118 go cpp@(CppFunction {}) = Just cpp
110 go cpp@(CppFunction {}) = Just cpp
119− go (CppVariableIntroduction _ _ (Just CppNumericLiteral {})) =
111+ go (CppVariableIntroduction _ _ (Just CppNumericLiteral {})) = Nothing
120− Nothing
121− go (CppVariableIntroduction _ _ (Just CppStringLiteral {})) =
112+ go (CppVariableIntroduction _ _ (Just CppStringLiteral {})) = Nothing
122− Nothing
123− go (CppVariableIntroduction _ _ (Just CppBooleanLiteral {})) =
113+ go (CppVariableIntroduction _ _ (Just CppBooleanLiteral {})) = Nothing
124− Nothing
125− go (CppVariableIntroduction _ _ (Just (CppUnary _ (CppNumericLiteral {})))) =
114+ go (CppVariableIntroduction _ _ (Just (CppUnary _ (CppNumericLiteral {})))) = Nothing
126− Nothing
127 go (CppVariableIntroduction (name, _) _ (Just (CppLambda _ [] rty body))) =
115 go (CppVariableIntroduction (name, _) _ (Just (CppLambda _ [] rty body))) =
128 Just $ CppFunction name [] rty [] body
116 Just $ CppFunction name [] rty [] body
129−
130 -- Generate thunks for top-level values
117 -- Generate thunks for top-level values
131 go (CppVariableIntroduction (name, _) _ (Just cpp)) =
118 go (CppVariableIntroduction (name, _) _ (Just cpp)) =
132 case cpp of
119 case cpp of
133 CppMapLiteral Instance _ ->
120 CppMapLiteral Instance _ ->
134 Just $ CppFunction name [("", Just thunkMarkerType)] (Just $ Any [Const, Ref]) [] block
121 Just $ CppFunction name [("", Just thunkMarkerType)] (Just $ Any [Const, Ref]) [] block
135− _ ->
136− Just $ CppVariableIntroduction (name, Just $ Any [Const]) [] (Just lambda)
122+ _ -> Just $ CppVariableIntroduction (name, Just $ Any [Const]) [] (Just lambda)
137 where
123 where
138 val = CppVariableIntroduction ("$value$", Just $ Any [Const]) [Static] (Just $ addCaptures cpp)
124 val = CppVariableIntroduction ("$value$", Just $ Any [Const]) [Static] (Just $ addCaptures cpp)
139 block = CppBlock [val, CppReturn (CppVar "$value$")]
125 block = CppBlock [val, CppReturn (CppVar "$value$")]
@@ -142,39 +128,41 @@ toBody = catMaybes . map go
142 addCaptures (CppMapLiteral t objs) = CppMapLiteral t (objlam <$> objs)
128 addCaptures (CppMapLiteral t objs) = CppMapLiteral t (objlam <$> objs)
143 where
129 where
144 objlam :: (Cpp, Cpp) -> (Cpp, Cpp)
130 objlam :: (Cpp, Cpp) -> (Cpp, Cpp)
131+ objlam (name', (CppLambda _ args rty body)) =
145− objlam (name', (CppLambda _ args rty body)) = (name' , CppLambda [] args rty $ addCaptures body)
132+ (name', CppLambda [] args rty $ addCaptures body)
146 objlam obj = obj
133 objlam obj = obj
147− addCaptures (CppApp (CppLambda _ [] rty body) []) = CppApp (CppLambda [] [] rty (addCaptures body)) []
134+ addCaptures (CppApp (CppLambda _ [] rty body) []) =
135+ CppApp (CppLambda [] [] rty (addCaptures body)) []
148 addCaptures cpps' = everywhereOnCpp addCapture cpps'
136 addCaptures cpps' = everywhereOnCpp addCapture cpps'
149 where
137 where
150 addCapture :: Cpp -> Cpp
138 addCapture :: Cpp -> Cpp
151 addCapture (CppLambda _ args rty body) = maybeRemCaps $ CppLambda [CaptureAll] args rty body
139 addCapture (CppLambda _ args rty body) = maybeRemCaps $ CppLambda [CaptureAll] args rty body
152 addCapture cpp' = cpp'
140 addCapture cpp' = cpp'
141+ go (CppComment comms cpp')
153− go (CppComment comms cpp') | Just commented <- go cpp' = Just (CppComment comms commented)
142+ | Just commented <- go cpp' = Just (CppComment comms commented)
154 go _ = Nothing
143 go _ = Nothing
155
144
156-------------------------------------------------------------------------------------------------
145-------------------------------------------------------------------------------------------------
157maybeRemCaps :: Cpp -> Cpp
146maybeRemCaps :: Cpp -> Cpp
158-------------------------------------------------------------------------------------------------
147-------------------------------------------------------------------------------------------------
159−maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn CppNumericLiteral{}]))
148+maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn CppNumericLiteral {}])) =
160− = CppLambda [] args rtyp body
149+ CppLambda [] args rtyp body
161−maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn CppStringLiteral{}]))
150+maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn CppStringLiteral {}])) =
162− = CppLambda [] args rtyp body
151+ CppLambda [] args rtyp body
163−maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn CppCharLiteral{}]))
152+maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn CppCharLiteral {}])) =
164− = CppLambda [] args rtyp body
153+ CppLambda [] args rtyp body
165−maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn CppBooleanLiteral{}]))
154+maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn CppBooleanLiteral {}])) =
166− = CppLambda [] args rtyp body
155+ CppLambda [] args rtyp body
167−maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn CppAccessor{}]))
156+maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn CppAccessor {}])) =
168− = CppLambda [] args rtyp body
157+ CppLambda [] args rtyp body
169maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn (CppVar "unit")])) -- TODO: not really safe
158maybeRemCaps (CppLambda [CaptureAll] args rtyp body@(CppBlock [CppReturn (CppVar "unit")])) -- TODO: not really safe
170− = CppLambda [] args rtyp body
159+ = CppLambda [] args rtyp body
171maybeRemCaps cpp = cpp
160maybeRemCaps cpp = cpp
172
161
173---------------------------------------------------------------------------------------------------
162---------------------------------------------------------------------------------------------------
174−
175fileBegin :: ModuleName -> String -> [Cpp]
163fileBegin :: ModuleName -> String -> [Cpp]
176−fileBegin mn suffix = [CppRaw ("#ifndef " ++ fileModName mn suffix),
164+fileBegin mn suffix =
177− CppRaw ("#define " ++ fileModName mn suffix)]
165+ [CppRaw ("#ifndef " ++ fileModName mn suffix), CppRaw ("#define " ++ fileModName mn suffix)]
178
166
179fileEnd :: ModuleName -> String -> [Cpp]
167fileEnd :: ModuleName -> String -> [Cpp]
180fileEnd mn suffix = [CppRaw ("#endif // " ++ fileModName mn suffix)]
168fileEnd mn suffix = [CppRaw ("#endif // " ++ fileModName mn suffix)]
@@ -187,14 +175,15 @@ isMain (ModuleName [ProperName "Main"]) = True
187isMain _ = False
175isMain _ = False
188
176
189nativeMain :: Cpp
177nativeMain :: Cpp
178+nativeMain =
190−nativeMain = CppFunction "main"
179+ CppFunction
191− [ ([], Just $ Primitive "int")
180+ "main"
192− , ([], Just $ Primitive "char *[]")
181+ [([], Just $ Primitive "int"), ([], Just $ Primitive "char *[]")]
193− ]
194− (Just $ Primitive "int")
182+ (Just $ Primitive "int")
195− []
183+ []
184+ (CppBlock
196− (CppBlock [ CppUseNamespace "Main"
185+ [ CppUseNamespace "Main"
197− , CppApp (CppVar "INITIALIZE_GC") []
186+ , CppApp (CppVar "INITIALIZE_GC") []
198− , CppApp (CppAccessor (CppVar "main") (CppVar "Main")) []
187+ , CppApp (CppAccessor (CppVar "main") (CppVar "Main")) []
199− , CppReturn (CppNumericLiteral (Left 0))
188+ , CppReturn (CppNumericLiteral (Left 0))
200− ])
189+ ])
src/Language/PureScript/CodeGen/Cpp/Types.hs+4−3
@@ -12,7 +12,6 @@
12-- Types for native C++11 translation
12-- Types for native C++11 translation
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15−
16{-# LANGUAGE PatternGuards #-}
15{-# LANGUAGE PatternGuards #-}
17{-# LANGUAGE DeriveDataTypeable #-}
16{-# LANGUAGE DeriveDataTypeable #-}
18
17
@@ -105,8 +104,10 @@ runCaptureType CaptureAll = "="
105-- TODO: move or remove this
104-- TODO: move or remove this
106--
105--
107qualifiedToStr :: ModuleName -> (a -> Ident) -> Qualified a -> String
106qualifiedToStr :: ModuleName -> (a -> Ident) -> Qualified a -> String
108−qualifiedToStr _ f (Qualified (Just (ModuleName [ProperName mn])) a) | mn == C.prim = runIdent $ f a
107+qualifiedToStr _ f (Qualified (Just (ModuleName [ProperName mn])) a)
108+ | mn == C.prim = runIdent $ f a
109−qualifiedToStr m f (Qualified (Just m') a) | m /= m' = moduleNameToCpp m' ++ "::" ++ identToCpp (f a)
109+qualifiedToStr m f (Qualified (Just m') a)
110+ | m /= m' = moduleNameToCpp m' ++ "::" ++ identToCpp (f a)
110qualifiedToStr _ f (Qualified _ a) = identToCpp (f a)
111qualifiedToStr _ f (Qualified _ a) = identToCpp (f a)
111
112
112boolType :: CppType
113boolType :: CppType
src/Language/PureScript/Pretty/Cpp.hs+67−52
@@ -12,15 +12,14 @@
12-- Pretty printer for the C++11 AST
12-- Pretty printer for the C++11 AST
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15−
16{-# LANGUAGE PatternGuards #-}
15{-# LANGUAGE PatternGuards #-}
17{-# LANGUAGE CPP #-}
16{-# LANGUAGE CPP #-}
18
17
19−module Language.PureScript.Pretty.Cpp (
18+module Language.PureScript.Pretty.Cpp
20− dotsTo,
19+ ( dotsTo
21− linebreak,
20+ , linebreak
22− prettyPrintCpp,
21+ , prettyPrintCpp
23−) where
22+ ) where
24
23
25import Prelude.Compat
24import Prelude.Compat
26
25
@@ -28,26 +27,28 @@ import Data.Bits
28import Data.Char
27import Data.Char
29import Data.List
28import Data.List
30import Data.Maybe (catMaybes, fromMaybe)
29import Data.Maybe (catMaybes, fromMaybe)
31−
32#if __GLASGOW_HASKELL__ < 710
30#if __GLASGOW_HASKELL__ < 710
33import Control.Applicative
31import Control.Applicative
34#endif
32#endif
35import Control.Arrow ((<+>))
33import Control.Arrow ((<+>))
34+import qualified Control.Arrow as A
36import Control.Monad.State
35import Control.Monad.State
37import Control.PatternArrows
36import Control.PatternArrows
38−import qualified Control.Arrow as A
39
37
40import Language.PureScript.CodeGen.Cpp.AST
38import Language.PureScript.CodeGen.Cpp.AST
41import Language.PureScript.CodeGen.Cpp.Types
39import Language.PureScript.CodeGen.Cpp.Types
42import Language.PureScript.Comments
40import Language.PureScript.Comments
43import qualified Language.PureScript.Constants as C
41import qualified Language.PureScript.Constants as C
44import Numeric
42import Numeric
45−-- import Debug.Trace
46
43
44+-- import Debug.Trace
47---------------------------------------------------------------------------------------------------
45---------------------------------------------------------------------------------------------------
48-- TODO: Go back to using Pretty.Common? (will require some work)
46-- TODO: Go back to using Pretty.Common? (will require some work)
49--
47--
50−newtype PrinterState = PrinterState { indent :: Int } deriving (Show, Read, Eq, Ord)
48+newtype PrinterState = PrinterState
49+ { indent :: Int
50+ } deriving (Show, Read, Eq, Ord)
51+
51-- |
52-- |
52-- Pretty print with a new indentation level
53-- Pretty print with a new indentation level
53--
54--
@@ -73,9 +74,9 @@ blockIndent = 2
73-- Wrap a string in parentheses
74-- Wrap a string in parentheses
74--
75--
75parens :: String -> String
76parens :: String -> String
76−parens s = '(':s ++ ")"
77+parens s = '(' : s ++ ")"
77−---------------------------------------------------------------------------------------------------
78
78
79+---------------------------------------------------------------------------------------------------
79literals :: Pattern PrinterState Cpp String
80literals :: Pattern PrinterState Cpp String
80literals = mkPattern' match
81literals = mkPattern' match
81 where
82 where
@@ -84,7 +85,8 @@ literals = mkPattern' match
84 match CppEndOfHeader = return []
85 match CppEndOfHeader = return []
85 match (CppNumericLiteral (Left n)) = return $ show n
86 match (CppNumericLiteral (Left n)) = return $ show n
86 match (CppNumericLiteral n) = return $ either show show n
87 match (CppNumericLiteral n) = return $ either show show n
88+ match (CppStringLiteral s)
87− match (CppStringLiteral s) | all isAscii s = return $ string s
89+ | all isAscii s = return $ string s
88 match (CppStringLiteral s) = return $ "u8" ++ string s
90 match (CppStringLiteral s) = return $ "u8" ++ string s
89 match (CppCharLiteral c) = return $ show c
91 match (CppCharLiteral c) = return $ show c
90 match (CppBooleanLiteral True) = return "true"
92 match (CppBooleanLiteral True) = return "true"
@@ -119,17 +121,17 @@ literals = mkPattern' match
119 match (CppMapLiteral _ ps) = fmap concat $ sequence
121 match (CppMapLiteral _ ps) = fmap concat $ sequence
120 [ return $ runType (mapType $ length ps + 1) ++ "{{\n"
122 [ return $ runType (mapType $ length ps + 1) ++ "{{\n"
121 , withIndent $ do
123 , withIndent $ do
124+ cpps <-
122− cpps <- forM ps $ \(key, value) -> do
125+ forM ps $ \(key, value) -> do
123− value' <- prettyPrintCpp' value
126+ value' <- prettyPrintCpp' value
124− key' <- prettyPrintCpp' key
127+ key' <- prettyPrintCpp' key
125− return $ "{ " ++ key' ++ ", " ++ value' ++ " }"
128+ return $ "{ " ++ key' ++ ", " ++ value' ++ " }"
126 indentString <- currentIndent
129 indentString <- currentIndent
127 return $ intercalate ", \n" $ map (indentString ++) (cpps ++ ["{ nullptr, nullptr }"])
130 return $ intercalate ", \n" $ map (indentString ++) (cpps ++ ["{ nullptr, nullptr }"])
128 , return "\n"
131 , return "\n"
129 , currentIndent
132 , currentIndent
130 , return "}}"
133 , return "}}"
131 ]
134 ]
132−
133 match (CppFunction name args rty qs ret) =
135 match (CppFunction name args rty qs ret) =
134 fmap concat $ sequence
136 fmap concat $ sequence
135 [ return . concatMap (++ " ") . filter (not . null) $ runValueQual <$> qs
137 [ return . concatMap (++ " ") . filter (not . null) $ runValueQual <$> qs
@@ -173,19 +175,22 @@ literals = mkPattern' match
173 , return "\n"
175 , return "\n"
174 , currentIndent
176 , currentIndent
175 , return "}#"
177 , return "}#"
176− ]
178+ ] ++
177− ++ let (cpp', cpps') = fromNested nested' in
179+ let (cpp', cpps') = fromNested nested'
178− map match cpp'
180+ in map match cpp' ++
181+ if null cpps'
182+ then []
179− ++ if null cpps' then [] else [match (CppNamespace name (filter isUseNamespace sts ++ cpps'))]
183+ else [match (CppNamespace name (filter isUseNamespace sts ++ cpps'))]
180 where
184 where
181 (sts', nested') = break isNestedNamespace sts
185 (sts', nested') = break isNestedNamespace sts
182 fromNested :: [Cpp] -> ([Cpp], [Cpp])
186 fromNested :: [Cpp] -> ([Cpp], [Cpp])
183− fromNested [] = ([],[])
187+ fromNested [] = ([], [])
184 fromNested cpps@((CppNamespace nm _):_) = ([foldl1 combineNamespaces namespaces], others)
188 fromNested cpps@((CppNamespace nm _):_) = ([foldl1 combineNamespaces namespaces], others)
185 where
189 where
186 (namespaces, others) = span inSameNamespace cpps
190 (namespaces, others) = span inSameNamespace cpps
187 inSameNamespace :: Cpp -> Bool
191 inSameNamespace :: Cpp -> Bool
188− inSameNamespace (CppNamespace nm' _) | nm' == nm = True
192+ inSameNamespace (CppNamespace nm' _)
193+ | nm' == nm = True
189 inSameNamespace _ = False
194 inSameNamespace _ = False
190 fromNested _ = error "Not a nested namespace"
195 fromNested _ = error "Not a nested namespace"
191 combineNamespaces :: Cpp -> Cpp -> Cpp
196 combineNamespaces :: Cpp -> Cpp -> Cpp
@@ -193,7 +198,7 @@ literals = mkPattern' match
193 | nm == nm' = CppNamespace nm (ss ++ filter (not . isUseNamespace) ss')
198 | nm == nm' = CppNamespace nm (ss ++ filter (not . isUseNamespace) ss')
194 combineNamespaces _ _ = error "Cannot fold cpps"
199 combineNamespaces _ _ = error "Cannot fold cpps"
195 isUseNamespace :: Cpp -> Bool
200 isUseNamespace :: Cpp -> Bool
196− isUseNamespace (CppUseNamespace{}) = True
201+ isUseNamespace (CppUseNamespace {}) = True
197 isUseNamespace _ = False
202 isUseNamespace _ = False
198 match (CppStruct (name) []) = return $ "struct " ++ name ++ " {}"
203 match (CppStruct (name) []) = return $ "struct " ++ name ++ " {}"
199 match (CppStruct (name) mems) = fmap concat $ sequence $
204 match (CppStruct (name) mems) = fmap concat $ sequence $
@@ -230,20 +235,20 @@ literals = mkPattern' match
230 match (CppCast typ val) = return $
235 match (CppCast typ val) = return $
231 case val of
236 case val of
232 CppNumericLiteral {} -> vstr
237 CppNumericLiteral {} -> vstr
233− CppStringLiteral {} -> vstr
238+ CppStringLiteral {} -> vstr
234 CppBooleanLiteral {} -> vstr
239 CppBooleanLiteral {} -> vstr
235 _ -> "cast" ++ angles (runType typ) ++ parens val'
240 _ -> "cast" ++ angles (runType typ) ++ parens val'
236 where
241 where
237 vstr = prettyPrintCpp1 val
242 vstr = prettyPrintCpp1 val
238 val' | '(' `elem` vstr || '[' `elem` vstr = parens vstr
243 val' | '(' `elem` vstr || '[' `elem` vstr = parens vstr
239 | otherwise = vstr
244 | otherwise = vstr
240−
245+ match (CppVar ident)
241− match (CppVar ident) | ident == C.__unused = match (CppVar $ '$':ident)
246+ | ident == C.__unused = match (CppVar $ '$' : ident)
242 match (CppVar ident) = return ident
247 match (CppVar ident) = return ident
243 match (CppSymbol ident) = return $ "SYMBOL" ++ parens (symbolname ident)
248 match (CppSymbol ident) = return $ "SYMBOL" ++ parens (symbolname ident)
244 match (CppApp v [CppNoOp]) = return (prettyPrintCpp1 v)
249 match (CppApp v [CppNoOp]) = return (prettyPrintCpp1 v)
245 match (CppVariableIntroduction (ident, typ) qs value)
250 match (CppVariableIntroduction (ident, typ) qs value)
246− | ident == C.__unused = match (CppVariableIntroduction ('$':ident, typ) qs value)
251+ | ident == C.__unused = match (CppVariableIntroduction ('$' : ident, typ) qs value)
247 match (CppVariableIntroduction (ident, typ) qs value) =
252 match (CppVariableIntroduction (ident, typ) qs value) =
248 fmap concat $ sequence
253 fmap concat $ sequence
249 [ return . concatMap (++ " ") . filter (not . null) $ runValueQual <$> qs
254 [ return . concatMap (++ " ") . filter (not . null) $ runValueQual <$> qs
@@ -290,9 +295,9 @@ literals = mkPattern' match
290 ]
295 ]
291 where
296 where
292 cast :: Cpp -> Cpp -> Cpp
297 cast :: Cpp -> Cpp -> Cpp
293− cast CppNumericLiteral{} cpp' = CppCast intType cpp'
298+ cast CppNumericLiteral {} cpp' = CppCast intType cpp'
294− cast CppBooleanLiteral{} cpp' = CppCast boolType cpp'
299+ cast CppBooleanLiteral {} cpp' = CppCast boolType cpp'
295− cast CppCharLiteral{} cpp' = CppCast charType cpp'
300+ cast CppCharLiteral {} cpp' = CppCast charType cpp'
296 cast _ cpp' = cpp'
301 cast _ cpp' = cpp'
297 match (CppReturn (CppBlock (cpp:cpps))) = fmap concat $ sequence
302 match (CppReturn (CppBlock (cpp:cpps))) = fmap concat $ sequence
298 [ do s <- prettyPrintCpp' cpp
303 [ do s <- prettyPrintCpp' cpp
@@ -332,16 +337,13 @@ literals = mkPattern' match
332 commentLines :: Comment -> [String]
337 commentLines :: Comment -> [String]
333 commentLines (LineComment s) = [s]
338 commentLines (LineComment s) = [s]
334 commentLines (BlockComment s) = lines s
339 commentLines (BlockComment s) = lines s
335−
336 asLine :: String -> StateT PrinterState Maybe String
340 asLine :: String -> StateT PrinterState Maybe String
337 asLine s = do
341 asLine s = do
338 i <- currentIndent
342 i <- currentIndent
339 return $ i ++ " * " ++ removeComments s ++ "\n"
343 return $ i ++ " * " ++ removeComments s ++ "\n"
340−
341 removeComments :: String -> String
344 removeComments :: String -> String
342− removeComments ('*' : '/' : s) = removeComments s
345+ removeComments ('*':'/':s) = removeComments s
343− removeComments (c : s) = c : removeComments s
346+ removeComments (c:s) = c : removeComments s
344−
345 removeComments [] = []
347 removeComments [] = []
346 match (CppRaw cpp) = return cpp
348 match (CppRaw cpp) = return cpp
347 match _ = mzero
349 match _ = mzero
@@ -359,8 +361,8 @@ string s = '"' : concatMap encodeChar (decodeSurrogates s) ++ "\""
359 fromEnum b >= 0xD800 && fromEnum b <= 0xDFFF
361 fromEnum b >= 0xD800 && fromEnum b <= 0xDFFF
360 = Just . chr $ 0x10000 + shiftL (fromEnum a .&. 0x03FF) 10 + (fromEnum b .&. 0x03FF)
362 = Just . chr $ 0x10000 + shiftL (fromEnum a .&. 0x03FF) 10 + (fromEnum b .&. 0x03FF)
361 decodePair a _
363 decodePair a _
362− | fromEnum a >= 0xD800 && fromEnum a <= 0xDFFF = Nothing
364+ | fromEnum a >= 0xD800 && fromEnum a <= 0xDFFF = Nothing
363− decodePair a _ = Just a
365+ decodePair a _ = Just a
364 encodeChar :: Char -> String
366 encodeChar :: Char -> String
365 encodeChar '\b' = "\\b"
367 encodeChar '\b' = "\\b"
366 encodeChar '\t' = "\\t"
368 encodeChar '\t' = "\\t"
@@ -370,14 +372,19 @@ string s = '"' : concatMap encodeChar (decodeSurrogates s) ++ "\""
370 encodeChar '\r' = "\\r"
372 encodeChar '\r' = "\\r"
371 encodeChar '"' = "\\\""
373 encodeChar '"' = "\\\""
372 encodeChar '\\' = "\\\\"
374 encodeChar '\\' = "\\\\"
375+ encodeChar c
373− encodeChar c | fromEnum c > 0xFFFF = "\\U" ++ leading ++ hex
376+ | fromEnum c > 0xFFFF = "\\U" ++ leading ++ hex
374 where
377 where
375 hex = showHex (fromEnum c) ""
378 hex = showHex (fromEnum c) ""
376 leading = replicate (8 - length hex) '0'
379 leading = replicate (8 - length hex) '0'
380+ encodeChar c
377− encodeChar c | fromEnum c > 0xFFF = "\\u" ++ showHex (fromEnum c) ""
381+ | fromEnum c > 0xFFF = "\\u" ++ showHex (fromEnum c) ""
382+ encodeChar c
378− encodeChar c | fromEnum c > 0xFF = "\\u0" ++ showHex (fromEnum c) ""
383+ | fromEnum c > 0xFF = "\\u0" ++ showHex (fromEnum c) ""
384+ encodeChar c
379− encodeChar c | fromEnum c < 0x10 = "\\x0" ++ showHex (fromEnum c) ""
385+ | fromEnum c < 0x10 = "\\x0" ++ showHex (fromEnum c) ""
386+ encodeChar c
380− encodeChar c | fromEnum c > 0x7E || fromEnum c < 0x20 = "\\x" ++ showHex (fromEnum c) ""
387+ | fromEnum c > 0x7E || fromEnum c < 0x20 = "\\x" ++ showHex (fromEnum c) ""
381 encodeChar c = [c]
388 encodeChar c = [c]
382
389
383accessor :: Pattern PrinterState Cpp (String, Cpp)
390accessor :: Pattern PrinterState Cpp (String, Cpp)
@@ -399,8 +406,7 @@ indexer = mkPattern' match
399lam :: Pattern PrinterState Cpp ((String, [(String, Maybe CppType)], Maybe CppType), Cpp)
406lam :: Pattern PrinterState Cpp ((String, [(String, Maybe CppType)], Maybe CppType), Cpp)
400lam = mkPattern match
407lam = mkPattern match
401 where
408 where
402− match (CppLambda caps args rty ret) =
403− Just ((concatMap runCaptureType caps, args, rty), ret)
409+ match (CppLambda caps args rty ret) = Just ((concatMap runCaptureType caps, args, rty), ret)
404 match _ = Nothing
410 match _ = Nothing
405
411
406app :: Pattern PrinterState Cpp (String, Cpp)
412app :: Pattern PrinterState Cpp (String, Cpp)
@@ -418,7 +424,8 @@ unary' op mkStr = Wrap match (++)
418 match :: Pattern PrinterState Cpp (String, Cpp)
424 match :: Pattern PrinterState Cpp (String, Cpp)
419 match = mkPattern match'
425 match = mkPattern match'
420 where
426 where
427+ match' (CppUnary op' val)
421− match' (CppUnary op' val) | op' == op = Just (mkStr val, val)
428+ | op' == op = Just (mkStr val, val)
422 match' _ = Nothing
429 match' _ = Nothing
423
430
424unary :: UnaryOperator -> String -> Operator PrinterState Cpp String
431unary :: UnaryOperator -> String -> Operator PrinterState Cpp String
@@ -438,7 +445,8 @@ binary op str = AssocL match (\v1 v2 -> v1 ++ str ++ v2)
438 where
445 where
439 match' (CppBinary op' v1@(CppStringLiteral _) v2@(CppStringLiteral _))
446 match' (CppBinary op' v1@(CppStringLiteral _) v2@(CppStringLiteral _))
440 | op' == op = Just (CppApp (CppVar "std::string") [v1], v2)
447 | op' == op = Just (CppApp (CppVar "std::string") [v1], v2)
441− match' (CppBinary op' v1 v2) | op' == op = Just (v1, v2)
448+ match' (CppBinary op' v1 v2)
449+ | op' == op = Just (v1, v2)
442 match' _ = Nothing
450 match' _ = Nothing
443
451
444prettyStatements :: [Cpp] -> StateT PrinterState Maybe String
452prettyStatements :: [Cpp] -> StateT PrinterState Maybe String
@@ -449,9 +457,11 @@ prettyStatements sts = do
449 where
457 where
450 addsemi :: String -> String
458 addsemi :: String -> String
451 addsemi [] = []
459 addsemi [] = []
460+ addsemi s
452− addsemi s | all isSpace s = []
461+ | all isSpace s = []
453 addsemi s@('#':_) = s
462 addsemi s@('#':_) = s
463+ addsemi s
454− addsemi s | last s == '#' = init s
464+ | last s == '#' = init s
455 addsemi s = s ++ ";"
465 addsemi s = s ++ ";"
456
466
457-- |
467-- |
@@ -516,11 +526,16 @@ dotsTo chr' = map (\c -> if c == '.' then chr' else c)
516
526
517argstr :: (String, Maybe CppType) -> String
527argstr :: (String, Maybe CppType) -> String
518argstr (name, Nothing) = argStr name (Auto [])
528argstr (name, Nothing) = argStr name (Auto [])
529+argstr (name, Just typ)
519−argstr (name, Just typ) | name == C.__unused = argStr [] typ
530+ | name == C.__unused = argStr [] typ
520argstr (name, Just typ) = argStr name typ
531argstr (name, Just typ) = argStr name typ
521
532
522argStr :: String -> CppType -> String
533argStr :: String -> CppType -> String
523−argStr name typ = runType typ ++ if null name then [] else " " ++ name
534+argStr name typ =
535+ runType typ ++
536+ if null name
537+ then []
538+ else " " ++ name
524
539
525templDecl :: [(String, Int)] -> String
540templDecl :: [(String, Int)] -> String
526templDecl ps = "template " ++ angles (intercalate ", " (go <$> ps))
541templDecl ps = "template " ++ angles (intercalate ", " (go <$> ps))