summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-03-27 14:53:37 -0400
committerJoe Crayne <joe@jerkface.net>2019-03-27 14:53:37 -0400
commitcae75f8c303edc717ca222adb9058b65a0f6ded6 (patch)
tree5c58c537f0d5cae10fc50f40c92990dd8030663a
parent331690db265faaa8cb8b350d029c0fd6db88083a (diff)
Switched grokStatement to use StateT.
-rw-r--r--Unique.hs1
-rw-r--r--monkeypatch.hs75
2 files changed, 40 insertions, 36 deletions
diff --git a/Unique.hs b/Unique.hs
index 13ae7cf..d0d3eb1 100644
--- a/Unique.hs
+++ b/Unique.hs
@@ -1,5 +1,6 @@
1module Unique 1module Unique
2 ( UniqueFactory 2 ( UniqueFactory
3 , freshUniques
3 , Unique 4 , Unique
4 , uniqueSymbol 5 , uniqueSymbol
5 , substituteUnique 6 , substituteUnique
diff --git a/monkeypatch.hs b/monkeypatch.hs
index 3b93e5b..ceeaf25 100644
--- a/monkeypatch.hs
+++ b/monkeypatch.hs
@@ -127,6 +127,9 @@ capitalize xs = concatMap (cap . drop 1) gs
127 gs = groupBy (\a b -> b/='_') $ '_':xs 127 gs = groupBy (\a b -> b/='_') $ '_':xs
128 cap (c:cs) = toUpper c : cs 128 cap (c:cs) = toUpper c : cs
129 129
130mb :: Functor m => m a -> StateT t m a
131mb m = StateT $ \s -> fmap (, s) m
132
130transField :: CDeclaration t -> [(TH.Name, TH.Bang, TH.Type)] 133transField :: CDeclaration t -> [(TH.Name, TH.Bang, TH.Type)]
131transField (CDecl [CTypeSpec (CTypeDef ctyp _)] vars _) 134transField (CDecl [CTypeSpec (CTypeDef ctyp _)] vars _)
132 = do 135 = do
@@ -345,10 +348,10 @@ isGlobalRef fe sym = fromMaybe False $ do
345-- expression. 348-- expression.
346grokExpression :: FunctionEnvironment 349grokExpression :: FunctionEnvironment
347 -> CExpression a 350 -> CExpression a
348 -> Maybe ([Computation FormalLambda], Computation (HS.Exp ())) 351 -> StateT UniqueFactory Maybe ([Computation FormalLambda], Computation (HS.Exp ()))
349grokExpression fe (CVar cv _) = 352grokExpression fe (CVar cv _) =
350 let v = identToString cv 353 let v = identToString cv
351 in Just $ 354 in return $
352 if isGlobalRef fe v 355 if isGlobalRef fe v
353 then let k = uniqIdentifier "go" (varmap [v,hv]) 356 then let k = uniqIdentifier "go" (varmap [v,hv])
354 s = Computation 357 s = Computation
@@ -367,9 +370,9 @@ grokExpression fe (CVar cv _) =
367 { compFree = Map.singleton (identToString cv) () 370 { compFree = Map.singleton (identToString cv) ()
368 } 371 }
369grokExpression fe (CConst (CIntConst n _)) = 372grokExpression fe (CConst (CIntConst n _)) =
370 Just $ (,) [] $ mkcomp $ Lit () (Int () (getCInteger n) (show n)) 373 return $ (,) [] $ mkcomp $ Lit () (Int () (getCInteger n) (show n))
371grokExpression fe (CConst (CStrConst s _)) = 374grokExpression fe (CConst (CStrConst s _)) =
372 Just $ (,) [] $ mkcomp $ Lit () (HS.String () (getCString s) (getCString s)) 375 return $ (,) [] $ mkcomp $ Lit () (HS.String () (getCString s) (getCString s))
373grokExpression fe (CBinary op a b _) = do 376grokExpression fe (CBinary op a b _) = do
374 (as,ca) <- grokExpression fe a 377 (as,ca) <- grokExpression fe a
375 (bs0,cb0) <- grokExpression fe b 378 (bs0,cb0) <- grokExpression fe b
@@ -432,8 +435,8 @@ grokExpression fe (C.CCall fn exps u) = grokCall fe True (C.CCall fn exps u)
432grokExpression fe (CStatExpr (CCompound idents xs _) _) = do 435grokExpression fe (CStatExpr (CCompound idents xs _) _) = do
433 let (y,ys) = splitAt 1 (reverse xs) 436 let (y,ys) = splitAt 1 (reverse xs)
434 y' <- case y of 437 y' <- case y of
435 [CBlockStmt (CExpr mexp ni)] -> Just $ CBlockStmt (CReturn mexp ni) 438 [CBlockStmt (CExpr mexp ni)] -> return $ CBlockStmt (CReturn mexp ni)
436 _ -> Just (head y) -- Nothing FIXME 439 _ -> return (head y) -- Nothing FIXME
437 gs <- mapM (grokStatement fe) (reverse $ y' : ys) 440 gs <- mapM (grokStatement fe) (reverse $ y' : ys)
438 let s0 = foldr applyComputation (mkcomp retUnit) gs 441 let s0 = foldr applyComputation (mkcomp retUnit) gs
439 s1 = fmap (\xp -> Paren () xp) s0 442 s1 = fmap (\xp -> Paren () xp) s0
@@ -451,7 +454,7 @@ grokExpression fe (CStatExpr (CCompound idents xs _) _) = do
451 { compFree = Map.singleton hv () 454 { compFree = Map.singleton hv ()
452 } 455 }
453grokExpression fe (CAssign CAssignOp cvar expr _) = do 456grokExpression fe (CAssign CAssignOp cvar expr _) = do
454 v <- cvarName cvar 457 v <- mb $ cvarName cvar
455 (ss,x) <- grokExpression fe expr 458 (ss,x) <- grokExpression fe expr
456 let k = uniqIdentifier "go" (Map.insert v () $ foldr (\s m -> compFree s `Map.union` compIntro s `Map.union` m) Map.empty ss) 459 let k = uniqIdentifier "go" (Map.insert v () $ foldr (\s m -> compFree s `Map.union` compIntro s `Map.union` m) Map.empty ss)
457 s = x 460 s = x
@@ -462,7 +465,7 @@ grokExpression fe (CAssign CAssignOp cvar expr _) = do
462 } 465 }
463 return $ (,) (ss ++ [s]) $ mkcomp (hsvar v) 466 return $ (,) (ss ++ [s]) $ mkcomp (hsvar v)
464grokExpression fe (CMember cvar fld isptr _) = do 467grokExpression fe (CMember cvar fld isptr _) = do
465 v <- cvarName cvar 468 v <- mb $ cvarName cvar
466 let fieldlbl = identToString fld 469 let fieldlbl = identToString fld
467 hv = v ++ fieldlbl 470 hv = v ++ fieldlbl
468 e = App () (App () (hsvar "get") 471 e = App () (App () (hsvar "get")
@@ -473,12 +476,12 @@ grokExpression fe (CMember cvar fld isptr _) = do
473 s = (FormalLambda k <$> fmap (($ Lambda () [hspvar hv] (hsvar k)) . (`infixOp` ">>=")) e') 476 s = (FormalLambda k <$> fmap (($ Lambda () [hspvar hv] (hsvar k)) . (`infixOp` ">>=")) e')
474 { compIntro = Map.singleton hv () } 477 { compIntro = Map.singleton hv () }
475 return $ (,) [s] (mkcomp $ hsvar hv){ compFree = Map.singleton hv () } 478 return $ (,) [s] (mkcomp $ hsvar hv){ compFree = Map.singleton hv () }
476grokExpression fe _ = Nothing 479grokExpression fe _ = mzero
477 480
478grokCall :: FunctionEnvironment 481grokCall :: FunctionEnvironment
479 -> Bool 482 -> Bool
480 -> CExpression a 483 -> CExpression a
481 -> Maybe ([Computation FormalLambda], Computation (HS.Exp ())) 484 -> StateT UniqueFactory Maybe ([Computation FormalLambda], Computation (HS.Exp ()))
482grokCall fe wantsRet (C.CCall (CVar fn _) exps _) = do 485grokCall fe wantsRet (C.CCall (CVar fn _) exps _) = do
483 gs <- mapM (grokExpression fe) exps 486 gs <- mapM (grokExpression fe) exps
484 let ss = concatMap fst gs -- TODO: resolve variable name conflicts 487 let ss = concatMap fst gs -- TODO: resolve variable name conflicts
@@ -519,14 +522,14 @@ grokCall fe wantsRet (C.CCall fnx@(CMember cvar fld isptr _) exps _) = do
519 return $ (,) (ss++[s]) (mkcomp $ hsvar hv) 522 return $ (,) (ss++[s]) (mkcomp $ hsvar hv)
520 { compFree = Map.singleton hv () 523 { compFree = Map.singleton hv ()
521 } 524 }
522grokCall _ _ _ = Nothing 525grokCall _ _ _ = mzero
523 526
524 527
525grokInitialization :: Foldable t1 => 528grokInitialization :: Foldable t1 =>
526 FunctionEnvironment 529 FunctionEnvironment
527 -> t1 (CDeclarationSpecifier t2) 530 -> t1 (CDeclarationSpecifier t2)
528 -> (Maybe (CDeclarator a1), CInitializer a2) 531 -> (Maybe (CDeclarator a1), CInitializer a2)
529 -> Maybe (Computation FormalLambda) 532 -> StateT UniqueFactory Maybe (Computation FormalLambda)
530grokInitialization fe _ (Just (CDeclr (Just cv0) _ _ _ _),CInitExpr exp _) = do 533grokInitialization fe _ (Just (CDeclr (Just cv0) _ _ _ _),CInitExpr exp _) = do
531 let v = identToString cv0 534 let v = identToString cv0
532 (xs,x) <- grokExpression fe exp 535 (xs,x) <- grokExpression fe exp
@@ -547,7 +550,7 @@ grokInitialization fe ts (Just (CDeclr (Just cv0) _ _ _ _),CInitList exps _) = d
547 forM exps $ \(ms,initexpr) -> do 550 forM exps $ \(ms,initexpr) -> do
548 case initexpr of 551 case initexpr of
549 CInitExpr ie _ -> (grokExpression fe) ie >>= \g -> return (ms,g) 552 CInitExpr ie _ -> (grokExpression fe) ie >>= \g -> return (ms,g)
550 _ -> Nothing 553 _ -> mzero
551 let assigns = do 554 let assigns = do
552 (ms,(ss,x)) <- gs 555 (ms,(ss,x)) <- gs
553 let k2 = uniqIdentifier "gopoo" (compFree ret) 556 let k2 = uniqIdentifier "gopoo" (compFree ret)
@@ -577,8 +580,8 @@ grokInitialization fe ts (Just (CDeclr (Just cv0) _ _ _ _),CInitList exps _) = d
577 k = uniqIdentifier "go" Map.empty -- (compFree ret) TODO 580 k = uniqIdentifier "go" Map.empty -- (compFree ret) TODO
578 ret = foldr applyComputation (mkcomp $ hsvar k) $ newstruct : assigns 581 ret = foldr applyComputation (mkcomp $ hsvar k) $ newstruct : assigns
579 return $ fmap (FormalLambda k) ret 582 return $ fmap (FormalLambda k) ret
580 _ -> Nothing 583 _ -> mzero
581grokInitialization _ _ _ = Nothing 584grokInitialization _ _ _ = mzero
582 585
583hasBool :: HS.Type () -> Bool 586hasBool :: HS.Type () -> Bool
584hasBool = (1 <=) . gcount (mkQ False (\t -> case t of { HS.Ident () "Bool" -> True; _ -> False })) 587hasBool = (1 <=) . gcount (mkQ False (\t -> case t of { HS.Ident () "Bool" -> True; _ -> False }))
@@ -591,33 +594,33 @@ promote fe y@(Lit () (Int () n _)) | (n==0 || n==1) && hasBool (fe Map.! "") =
591promote _ y = y 594promote _ y = y
592 595
593 596
594grokStatement :: FunctionEnvironment -> CCompoundBlockItem a -> Maybe (Computation FormalLambda) 597grokStatement :: FunctionEnvironment -> CCompoundBlockItem a -> StateT UniqueFactory Maybe (Computation FormalLambda)
595grokStatement fe (CBlockStmt (CReturn (Just exp) _)) = do 598grokStatement fe (CBlockStmt (CReturn (Just exp) _)) = do
596 (xs,x) <- grokExpression fe exp 599 (xs,x) <- grokExpression fe exp
597 let k = uniqIdentifier "go" (compFree x `Map.union` compIntro x) 600 let k = uniqIdentifier "go" (compFree x `Map.union` compIntro x)
598 x' = fmap (\y -> App () (hsvar "return") $ promote (fnArgs fe) y) x 601 x' = fmap (\y -> App () (hsvar "return") $ promote (fnArgs fe) y) x
599 return $ fmap (\y -> FormalLambda k y) $ foldr applyComputation x' xs 602 return $ fmap (\y -> FormalLambda k y) $ foldr applyComputation x' xs
600grokStatement fe (CBlockStmt (CReturn Nothing _)) = 603grokStatement fe (CBlockStmt (CReturn Nothing _)) =
601 Just $ mkcomp $ FormalLambda "go" retUnit 604 return $ mkcomp $ FormalLambda "go" retUnit
602grokStatement fe (CBlockStmt (CCont _)) = 605grokStatement fe (CBlockStmt (CCont _)) =
603 Just (mkcomp $ FormalLambda "go" $ hsvar " continue") 606 return (mkcomp $ FormalLambda "go" $ hsvar " continue")
604 { compContinue = Just " continue" } 607 { compContinue = Just " continue" }
605grokStatement fe (CBlockStmt (CIf exp thn els _)) = do 608grokStatement fe (CBlockStmt (CIf exp thn els _)) = do
606 (xs,x) <- grokExpression fe exp 609 (xs,x) <- grokExpression fe exp
607 let mkif0 = If () (comp x) 610 let mkif0 = If () (comp x)
608 (mkif,stmts) <- case (thn,els) of 611 (mkif,stmts) <- case (thn,els) of
609 612
610 (CCompound [] stmts _, Nothing ) -> Just (mkif0, stmts) 613 (CCompound [] stmts _, Nothing ) -> return (mkif0, stmts)
611 (stmt , Nothing ) -> Just (mkif0, [CBlockStmt stmt]) 614 (stmt , Nothing ) -> return (mkif0, [CBlockStmt stmt])
612 (CCompound [] stmts _, Just (CExpr Nothing _) ) -> Just (mkif0, stmts) 615 (CCompound [] stmts _, Just (CExpr Nothing _) ) -> return (mkif0, stmts)
613 (CCompound [] stmts _, Just (CCompound [] [ CBlockStmt (CExpr Nothing _) ] _)) -> Just (mkif0, stmts) 616 (CCompound [] stmts _, Just (CCompound [] [ CBlockStmt (CExpr Nothing _) ] _)) -> return (mkif0, stmts)
614 617
615 (CExpr Nothing _ ,Just (CCompound [] stmts _)) -> Just (flip mkif0, stmts) 618 (CExpr Nothing _ ,Just (CCompound [] stmts _)) -> return (flip mkif0, stmts)
616 (CCompound [] [CBlockStmt (CExpr Nothing _)] _,Just (CCompound [] stmts _)) -> Just (flip mkif0, stmts) 619 (CCompound [] [CBlockStmt (CExpr Nothing _)] _,Just (CCompound [] stmts _)) -> return (flip mkif0, stmts)
617 (CExpr Nothing _ ,Just e@(CExpr (Just _) _)) -> Just (flip mkif0, [CBlockStmt e]) 620 (CExpr Nothing _ ,Just e@(CExpr (Just _) _)) -> return (flip mkif0, [CBlockStmt e])
618 (CCompound [] [CBlockStmt (CExpr Nothing _)] _,Just e@(CExpr (Just _) _)) -> Just (flip mkif0, [CBlockStmt e]) 621 (CCompound [] [CBlockStmt (CExpr Nothing _)] _,Just e@(CExpr (Just _) _)) -> return (flip mkif0, [CBlockStmt e])
619 622
620 _ -> trace ("Unhandled if: "++show (fmap (const LT) thn)) $ Nothing -- TODO 623 _ -> trace ("Unhandled if: "++show (fmap (const LT) thn)) $ mzero -- TODO
621 624
622 ss <- sequence $ map (grokStatement fe) stmts 625 ss <- sequence $ map (grokStatement fe) stmts
623 let s = foldr applyComputation (mkcomp $ hsvar k) ss 626 let s = foldr applyComputation (mkcomp $ hsvar k) ss
@@ -631,8 +634,8 @@ grokStatement fe (CBlockStmt (CIf exp thn els _)) = do
631grokStatement fe (CBlockStmt (CExpr (Just (C.CCall (CVar (C.Ident "__assert_fail" _ _) _) xs _)) _)) = do 634grokStatement fe (CBlockStmt (CExpr (Just (C.CCall (CVar (C.Ident "__assert_fail" _ _) _) xs _)) _)) = do
632 x <- case xs of 635 x <- case xs of
633 (CConst (CStrConst msg _):_) -> let s = getCString msg 636 (CConst (CStrConst msg _):_) -> let s = getCString msg
634 in Just $ mkcomp $ Lit () (HS.String () s s) 637 in return $ mkcomp $ Lit () (HS.String () s s)
635 _ -> Nothing 638 _ -> mzero
636 let k = uniqIdentifier "go" (compFree x `Map.union` compIntro x) 639 let k = uniqIdentifier "go" (compFree x `Map.union` compIntro x)
637 x' = fmap (\y -> App () (hsvar "error") y) x 640 x' = fmap (\y -> App () (hsvar "error") y) x
638 return $ fmap (FormalLambda k) x' 641 return $ fmap (FormalLambda k) x'
@@ -640,7 +643,7 @@ grokStatement fe (CBlockStmt (CExpr (Just
640 (CAssign CAssignOp 643 (CAssign CAssignOp
641 (CMember cvar fld isptr _) expr _)) _)) = do 644 (CMember cvar fld isptr _) expr _)) _)) = do
642 (xs,x) <- grokExpression fe expr 645 (xs,x) <- grokExpression fe expr
643 v <- cvarName cvar 646 v <- mb $ cvarName cvar
644 let fieldlbl = identToString fld 647 let fieldlbl = identToString fld
645 k1 = uniqIdentifier "go" (compFree x) 648 k1 = uniqIdentifier "go" (compFree x)
646 fieldinit = comp x 649 fieldinit = comp x
@@ -662,8 +665,8 @@ grokStatement fe (CBlockStmt (CExpr (Just (C.CCall cvarfun exps a)) _)) = do
662grokStatement fe (CBlockStmt (CExpr (Just 665grokStatement fe (CBlockStmt (CExpr (Just
663 (CAssign CAssignOp cvarnew 666 (CAssign CAssignOp cvarnew
664 (C.CCall cvarfun [] _) _)) _)) = do 667 (C.CCall cvarfun [] _) _)) _)) = do
665 v <- cvarName cvarnew 668 v <- mb $ cvarName cvarnew
666 fn <- cvarName cvarfun 669 fn <- mb $ cvarName cvarfun
667 let k = uniqIdentifier "go" (varmap [v,fn]) 670 let k = uniqIdentifier "go" (varmap [v,fn])
668 return Computation 671 return Computation
669 { compFree = Map.singleton fn () 672 { compFree = Map.singleton fn ()
@@ -690,7 +693,7 @@ grokStatement fe (CBlockStmt (CExpr (Just (CUnary CPostIncOp (CMember (CVar cv0
690 } 693 }
691grokStatement fe (CBlockStmt (CExpr mexpr _)) = do 694grokStatement fe (CBlockStmt (CExpr mexpr _)) = do
692 -- trace ("CExpr statement: " ++ take 50 (show $ fmap (fmap $ const ()) mexpr)) $ return () 695 -- trace ("CExpr statement: " ++ take 50 (show $ fmap (fmap $ const ()) mexpr)) $ return ()
693 (ss,pre) <- maybe (Just $ (,) [] $ mkcomp id) 696 (ss,pre) <- maybe (return $ (,) [] $ mkcomp id)
694 (let -- Discard pure value since we are interested only in side-effects. 697 (let -- Discard pure value since we are interested only in side-effects.
695 discard = const $ mkcomp id 698 discard = const $ mkcomp id
696 -- Alternate: keep pure-value using `seq` operator. 699 -- Alternate: keep pure-value using `seq` operator.
@@ -721,7 +724,7 @@ grokStatement fe (CBlockStmt (CWhile cond (CCompound [] bdy _) isDoWhile _)) = d
721 x = foldr applyComputation c' ss -- continue function 724 x = foldr applyComputation c' ss -- continue function
722 vs = [] -- Map.keys $ compIntro g 725 vs = [] -- Map.keys $ compIntro g
723 return $ fmap (FormalLambda "fin") $ fmap (factorOutFunction "continue" vs (comp x) " continue") g 726 return $ fmap (FormalLambda "fin") $ fmap (factorOutFunction "continue" vs (comp x) " continue") g
724grokStatement fe _ = Nothing 727grokStatement fe _ = mzero
725 728
726isFunctionDecl :: CExternalDeclaration a -> Bool 729isFunctionDecl :: CExternalDeclaration a -> Bool
727isFunctionDecl (CDeclExt (CDecl _ [(Just (CDeclr _ [CFunDeclr _ _ _] _ _ _),_,_)] _)) = True 730isFunctionDecl (CDeclExt (CDecl _ [(Just (CDeclr _ [CFunDeclr _ _ _] _ _ _),_,_)] _)) = True
@@ -851,7 +854,7 @@ transpile o fname incs (CTranslUnit edecls _) = do
851 then do printHeader 854 then do printHeader
852 forM_ bdy $ \d -> putStrLn $ ppShow $ cleanTree d 855 forM_ bdy $ \d -> putStrLn $ ppShow $ cleanTree d
853 else do 856 else do
854 let mhask = do 857 let mhask = (`evalStateT` freshUniques) $ do
855 xs <- mapM (grokStatement fe) bdy 858 xs <- mapM (grokStatement fe) bdy
856 return $ foldr applyComputation (mkcomp retUnit) xs 859 return $ foldr applyComputation (mkcomp retUnit) xs
857 case mhask of 860 case mhask of
@@ -861,7 +864,7 @@ transpile o fname incs (CTranslUnit edecls _) = do
861 printHeader 864 printHeader
862 forM_ bdy $ \d -> do 865 forM_ bdy $ \d -> do
863 putStrLn $ " C: " ++ show (pretty d) 866 putStrLn $ " C: " ++ show (pretty d)
864 case grokStatement fe d of 867 case grokStatement fe d `evalStateT` freshUniques of
865 868
866 Just hd -> do putStrLn $ "fr: " ++ intercalate " " (Map.keys (compFree hd)) 869 Just hd -> do putStrLn $ "fr: " ++ intercalate " " (Map.keys (compFree hd))
867 putStrLn $ "HS: " ++ HS.prettyPrint (informalize $ comp hd) 870 putStrLn $ "HS: " ++ HS.prettyPrint (informalize $ comp hd)