summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-03-27 13:42:37 -0400
committerJoe Crayne <joe@jerkface.net>2019-03-27 13:42:37 -0400
commit331690db265faaa8cb8b350d029c0fd6db88083a (patch)
tree5b2a7b2ded341ad893eba171793e59ad04e6d44f
parentec1c7a5c0e2673388c5601353f2e54b1b364fdb4 (diff)
WIP: do-while.
-rw-r--r--Unique.hs40
-rw-r--r--monkeypatch.cabal3
-rw-r--r--monkeypatch.hs79
3 files changed, 93 insertions, 29 deletions
diff --git a/Unique.hs b/Unique.hs
new file mode 100644
index 0000000..13ae7cf
--- /dev/null
+++ b/Unique.hs
@@ -0,0 +1,40 @@
1module Unique
2 ( UniqueFactory
3 , Unique
4 , uniqueSymbol
5 , substituteUnique
6 , multipleOccurances
7 ) where
8
9import Data.Generics.Aliases
10import Data.Generics.Schemes
11import Language.Haskell.Exts.Syntax
12
13newtype UniqueFactory = UniqueFactory Integer
14
15newtype Unique = Unique Integer
16 deriving (Eq,Ord)
17
18freshUniques :: UniqueFactory
19freshUniques = UniqueFactory 0
20
21genUnique :: UniqueFactory -> (Unique,UniqueFactory)
22genUnique (UniqueFactory c) = (Unique c, UniqueFactory (succ c))
23
24uniqueSymbol :: Unique -> Exp ()
25uniqueSymbol (Unique i) = Var () (UnQual () (Ident () (showSym i)))
26
27showSym :: Integer -> String
28showSym i = " u" ++ show i
29
30substituteUnique :: Unique -> Exp () -> Exp () -> Exp ()
31substituteUnique u inner outer = everywhere (mkT $ subst inner) outer
32 where
33 subst x t | t == uniqueSymbol u = x
34 | otherwise = t
35
36
37multipleOccurances :: Unique -> Exp () -> Bool
38multipleOccurances u x = case listify (== uniqueSymbol u) x of
39 (x:y:ys) -> True
40 _ -> False
diff --git a/monkeypatch.cabal b/monkeypatch.cabal
index 2b06032..281320f 100644
--- a/monkeypatch.cabal
+++ b/monkeypatch.cabal
@@ -52,7 +52,7 @@ extra-source-files: CHANGELOG.md
52 52
53executable monkeypatch 53executable monkeypatch
54 main-is: monkeypatch.hs 54 main-is: monkeypatch.hs
55 other-modules: GrepNested, Sweeten 55 other-modules: GrepNested, Sweeten, Unique
56 -- other-extensions: 56 -- other-extensions:
57 build-depends: base >=4.10.1.0 && <=4.12 57 build-depends: base >=4.10.1.0 && <=4.12
58 , containers ^>=0.5.10.2 58 , containers ^>=0.5.10.2
@@ -65,5 +65,6 @@ executable monkeypatch
65 , pretty-show 65 , pretty-show
66 , process 66 , process
67 , directory 67 , directory
68 , transformers
68 -- hs-source-dirs: 69 -- hs-source-dirs:
69 default-language: Haskell2010 70 default-language: Haskell2010
diff --git a/monkeypatch.hs b/monkeypatch.hs
index b3bbe2d..3b93e5b 100644
--- a/monkeypatch.hs
+++ b/monkeypatch.hs
@@ -11,7 +11,9 @@
11module Main where 11module Main where
12 12
13import Debug.Trace 13import Debug.Trace
14import Control.Arrow (left,first,second) 14
15import Control.Arrow (first, left, second)
16import Control.Monad.Trans.State.Lazy
15import Data.Bool 17import Data.Bool
16import Data.Either 18import Data.Either
17import Data.Generics.Aliases 19import Data.Generics.Aliases
@@ -21,39 +23,40 @@ import Control.Monad
21import qualified Data.ByteString.Char8 as B 23import qualified Data.ByteString.Char8 as B
22import Data.Char 24import Data.Char
23import Data.Data 25import Data.Data
24import Data.List
25import qualified Data.IntMap as IntMap 26import qualified Data.IntMap as IntMap
26 ;import Data.IntMap (IntMap) 27 ;import Data.IntMap (IntMap)
27import qualified Data.Map as Map 28import Data.List
28 ;import Data.Map (Map) 29import qualified Data.Map as Map
30 ;import Data.Map (Map)
29import Data.Maybe 31import Data.Maybe
30import Data.Ord 32import Data.Ord
31import qualified Data.Set as Set 33import qualified Data.Set as Set
32 ;import Data.Set (Set) 34 ;import Data.Set (Set)
33import Language.C.Data.Ident as C 35import qualified Language.C as C
34import Language.C.Data.Node as C 36 ;import Language.C as C hiding (prettyUsingInclude)
35import Language.C as C hiding (prettyUsingInclude) 37import Language.C.Data.Ident as C
36import qualified Language.C as C 38import Language.C.Data.Node as C
39import Language.C.Data.Position
37import Language.C.System.GCC 40import Language.C.System.GCC
38import Language.C.System.Preprocess 41import Language.C.System.Preprocess
39import Language.C.Data.Position 42import Language.Haskell.Exts.Parser as HS
40import Language.Haskell.Exts.Parser as HS 43import Language.Haskell.Exts.Pretty as HS
41import Language.Haskell.Exts.Pretty as HS 44import Language.Haskell.Exts.Syntax as HS
42import Language.Haskell.Exts.Syntax as HS
43import Language.Haskell.TH 45import Language.Haskell.TH
44import Language.Haskell.TH.Ppr 46import Language.Haskell.TH.Ppr
45import Language.Haskell.TH.Syntax as TH 47import Language.Haskell.TH.Syntax as TH
46import System.Directory 48import System.Directory
47import System.Environment 49import System.Environment
50import System.Exit
48import System.IO 51import System.IO
49import System.Process 52import System.Process
50import System.Exit 53import Text.PrettyPrint (Doc, doubleQuotes, empty, text, vcat,
51import Text.PrettyPrint (Doc, doubleQuotes, empty, text, vcat, ($$), 54 ($$), (<+>))
52 (<+>))
53import Text.Show.Pretty 55import Text.Show.Pretty
54 56
55import Sweeten 57import Sweeten
56import GrepNested 58import GrepNested
59import Unique
57 60
58{- 61{-
59trace :: p -> a -> a 62trace :: p -> a -> a
@@ -212,26 +215,34 @@ informalize :: FormalLambda -> HS.Exp ()
212informalize (FormalLambda k x) = Lambda () [hspvar k] x 215informalize (FormalLambda k x) = Lambda () [hspvar k] x
213 216
214 217
218factorOutFunction :: String -- ^ New function name to factor out.
219 -> [String] -- ^ Arguments to function.
220 -> HS.Exp () -- ^ Body of function.
221 -> String -- ^ Variable name place holder for call sites in template.
222 -> HS.Exp () -- ^ Template containing place-holder call sites.
223 -> HS.Exp ()
224factorOutFunction k vs bdy govar expr =
225 let matchgo (Var () (UnQual () (HS.Ident () v))) = v==govar
226 matchgo _ = False
227 subst x | matchgo x = callsite
228 | otherwise = x
229 callsite = foldl (App ()) (hsvar k) $ map hsvar vs
230 pats = map hspvar vs
231 in Let () (BDecls () [FunBind () [HS.Match () (HS.Ident () k) pats
232 (UnGuardedRhs () bdy) Nothing]])
233 (everywhere (mkT subst) expr)
234
215 235
216-- Like applyComputation, but creates a let-binding rather than inlining the continuation. 236-- Like applyComputation, but creates a let-binding rather than inlining the continuation.
217multiwayContinuation :: Computation FormalLambda -> Computation (HS.Exp ()) -> Computation (HS.Exp ()) 237multiwayContinuation :: Computation FormalLambda -> Computation (HS.Exp ()) -> Computation (HS.Exp ())
218multiwayContinuation a@Computation{ comp = FormalLambda govar exp } b = 238multiwayContinuation a@Computation{ comp = FormalLambda govar exp } b =
219 let k = uniqIdentifier "go" (foldr Map.union Map.empty [compFree a,compIntro a,compFree b,compIntro b]) 239 let k = uniqIdentifier "go" (foldr Map.union Map.empty [compFree a,compIntro a,compFree b,compIntro b])
220 vs = Map.keys $ compIntro a `Map.intersection` compFree b 240 vs = Map.keys $ compIntro a `Map.intersection` compFree b
221 matchgo (Var () (UnQual () (HS.Ident () v))) = v==govar
222 matchgo _ = False
223 subst x | matchgo x = callsite
224 | otherwise = x
225 callsite = foldl (App ()) (hsvar k) $ map hsvar vs
226 pats = map hspvar vs
227 letexpr = Let () (BDecls () [FunBind () [HS.Match () (HS.Ident () k) pats
228 (UnGuardedRhs () (comp b)) Nothing]])
229 (everywhere (mkT subst) exp)
230 in Computation 241 in Computation
231 { compFree = Map.union (compFree a) (compFree b) Map.\\ compIntro a 242 { compFree = Map.union (compFree a) (compFree b) Map.\\ compIntro a
232 , compIntro = compIntro a `Map.union` compIntro b 243 , compIntro = compIntro a `Map.union` compIntro b
233 , compContinue = Nothing 244 , compContinue = Nothing
234 , comp = letexpr 245 , comp = factorOutFunction k vs (comp b) govar exp
235 } 246 }
236 247
237 248
@@ -698,6 +709,18 @@ grokStatement fe (CBlockDecl (CDecl (t:ts) (v:vs) _)) = do
698 gs <- mapM (grokInitialization fe $ t:ts) initials 709 gs <- mapM (grokInitialization fe $ t:ts) initials
699 return $ fmap (FormalLambda "go") 710 return $ fmap (FormalLambda "go")
700 $ foldr applyComputation (mkcomp $ hsvar "go") gs 711 $ foldr applyComputation (mkcomp $ hsvar "go") gs
712grokStatement fe (CBlockStmt (CWhile cond (CCompound [] bdy _) isDoWhile _)) = do
713 gs <- mapM (grokStatement fe) bdy
714 (ss,c) <- grokExpression fe cond
715 let g = foldr applyComputation cnt gs -- body of loop
716 cnt = mkcomp $ hsvar " continue"
717 -- k = uniqIdentifier "go" (compFree g `Map.union` compIntro g)
718 loopcall = foldl (App ()) (hsvar "loop") $ map hsvar vs
719 -- c' = fmap (\cnd -> App () (App () (hsvar "when") cnd) (Paren () loopcall)) c
720 c' = fmap (\cnd -> If () cnd (Paren () loopcall) (hsvar "fin")) c
721 x = foldr applyComputation c' ss -- continue function
722 vs = [] -- Map.keys $ compIntro g
723 return $ fmap (FormalLambda "fin") $ fmap (factorOutFunction "continue" vs (comp x) " continue") g
701grokStatement fe _ = Nothing 724grokStatement fe _ = Nothing
702 725
703isFunctionDecl :: CExternalDeclaration a -> Bool 726isFunctionDecl :: CExternalDeclaration a -> Bool