git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: handle var intros with recursion
0aefd7bAndy Arvanitis
src/Language/PureScript/CodeGen/Cpp.hs+40−21
@@ -278,12 +278,12 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
278 aty = Just $ CppAny [CppConst, CppRef]
278 aty = Just $ CppAny [CppConst, CppRef]
279 rty = Just $ CppAny []
279 rty = Just $ CppAny []
280
280
281− declToCpp _ (_, ident) val = do
281+ declToCpp qs (_, ident) val = do
282 val' <- valueToCpp val
282 val' <- valueToCpp val
283 return $
283 return $
284 CppVariableIntroduction
284 CppVariableIntroduction
285 (identToCpp ident, Just $ CppAny [CppConst])
285 (identToCpp ident, Just $ CppAny [CppConst])
286− []
286+ qs
287 (Just val')
287 (Just val')
288
288
289 -------------------------------------------------------------------------------------------------
289 -------------------------------------------------------------------------------------------------
@@ -336,35 +336,46 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
336
336
337 recursive :: Cpp -> [Cpp]
337 recursive :: Cpp -> [Cpp]
338 recursive cpp'@(CppFunction _ _ _ qs _) | CppRecursive `elem` qs = [cpp']
338 recursive cpp'@(CppFunction _ _ _ qs _) | CppRecursive `elem` qs = [cpp']
339+ recursive cpp'@(CppVariableIntroduction _ qs _) | CppRecursive `elem` qs = [cpp']
339 recursive _ = []
340 recursive _ = []
340
341
341 removeRec :: Cpp -> Cpp
342 removeRec :: Cpp -> Cpp
342− removeRec(CppFunction _ _ _ qs _) | CppRecursive `elem` qs = CppNoOp
343+ removeRec (CppFunction _ _ _ qs _) | CppRecursive `elem` qs = CppNoOp
344+ removeRec (CppVariableIntroduction _ qs _) | CppRecursive `elem` qs = CppNoOp
343 removeRec cpp' = cpp'
345 removeRec cpp' = cpp'
344
346
347+ replaceVar :: [(String, Cpp)] -> Cpp -> Cpp
348+ replaceVar rs = go
349+ where
350+ go (CppVar var) | Just var' <- lookup var rs = var'
351+ go cpp' = cpp'
352+
345 dict :: Cpp
353 dict :: Cpp
346 dict = CppVariableIntroduction
354 dict = CppVariableIntroduction
347 (topdict, Just $ CppAny [CppConst])
355 (topdict, Just $ CppAny [CppConst])
348 []
356 []
349 (Just $ CppDataLiteral ((\(f,cpp) -> CppComment [LineComment f] cpp) <$> fns))
357 (Just $ CppDataLiteral ((\(f,cpp) -> CppComment [LineComment f] cpp) <$> fns))
350
358
359+ accessed :: String -> String -> (String, Cpp)
360+ accessed dictname name =
361+ (name, CppApp
362+ (CppIndexer
363+ (CppNumericLiteral .
364+ Left .
365+ fromIntegral .
366+ fromJust $ findIndex ((== name) . fst) fns)
367+ dict'')
368+ [dict'])
369+ where
370+ dict' = CppVar dictname
371+ dict'' = CppCast dataType dict'
372+
351 accessor :: String -> (String, Cpp) -> Cpp
373 accessor :: String -> (String, Cpp) -> Cpp
352 accessor dictname (name, _) =
374 accessor dictname (name, _) =
353 CppVariableIntroduction
375 CppVariableIntroduction
354 (name, Just $ CppAny [CppConst])
376 (name, Just $ CppAny [CppConst])
355 []
377 []
356− (Just accessed)
378+ (Just . snd $ accessed dictname name)
357− where
358− dict' = CppVar dictname
359− dict'' = CppCast dataType dict'
360− accessed = CppApp
361− (CppIndexer
362− (CppNumericLiteral .
363− Left .
364− fromIntegral .
365− fromJust $ findIndex ((== name) . fst) fns)
366− dict'')
367− [dict']
368
379
369 toelem :: Cpp -> (String, Cpp)
380 toelem :: Cpp -> (String, Cpp)
370 toelem (CppFunction name args rtyp _ body'@(CppBlock body)) =
381 toelem (CppFunction name args rtyp _ body'@(CppBlock body)) =
@@ -373,6 +384,12 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
373 args
384 args
374 rtyp
385 rtyp
375 (CppBlock $ (accessor localdict <$> filteredFns body') ++ body))
386 (CppBlock $ (accessor localdict <$> filteredFns body') ++ body))
387+
388+ toelem (CppVariableIntroduction (name, _) _ (Just body')) =
389+ let replacements = accessed localdict . fst <$> filteredFns body'
390+ replaced = everywhereOnCpp (replaceVar replacements) body'
391+ in (name, withdict . maybeRemCaps $ CppBlock [CppReturn replaced])
392+
376 toelem _ = error "not a function"
393 toelem _ = error "not a function"
377
394
378 withdict :: Cpp -> Cpp
395 withdict :: Cpp -> Cpp
@@ -495,19 +512,21 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
495 hasRecursion :: [Cpp] -> Bool
512 hasRecursion :: [Cpp] -> Bool
496 hasRecursion cpps' = any (everythingOnCpp (||) hasRecursiveRef) cpps'
513 hasRecursion cpps' = any (everythingOnCpp (||) hasRecursiveRef) cpps'
497 where
514 where
498− fnames :: [String]
515+ valnames :: [String]
499− fnames = concatMap (everythingOnCpp (++) fname) cpps'
516+ valnames = concatMap (everythingOnCpp (++) valname) cpps'
500
517
501− fname :: Cpp -> [String]
518+ valname :: Cpp -> [String]
502− fname (CppFunction name _ _ _ _) = [name]
519+ valname (CppFunction name _ _ _ _) = [name]
503− fname _ = []
520+ valname (CppVariableIntroduction (name, _) _ _) = [name]
521+ valname _ = []
504
522
505 hasRecursiveRef :: Cpp -> Bool
523 hasRecursiveRef :: Cpp -> Bool
506 hasRecursiveRef (CppFunction _ _ _ _ body) = everythingOnCpp (||) ref body
524 hasRecursiveRef (CppFunction _ _ _ _ body) = everythingOnCpp (||) ref body
525+ hasRecursiveRef (CppVariableIntroduction _ _ (Just value)) = everythingOnCpp (||) ref value
507 hasRecursiveRef _ = False
526 hasRecursiveRef _ = False
508
527
509 ref :: Cpp -> Bool
528 ref :: Cpp -> Bool
510− ref (CppVar name) | name `elem` fnames = True
529+ ref (CppVar name) | name `elem` valnames = True
511 ref _ = False
530 ref _ = False
512
531
513 valueToCpp Constructor{} = return CppNoOp
532 valueToCpp Constructor{} = return CppNoOp