1{-# OPTIONS_GHC -Wall #-}
2module Canonicalize.Sort (definitions) where
4import Control.Monad.State
5import Control.Applicative ((<$>),(<*>))
6import qualified Data.Graph as Graph
7import qualified Data.Map as Map
8import qualified Data.Maybe as Maybe
9import qualified Data.Set as Set
11import AST.Expression.General (Expr'(..), PortImpl(..))
12import qualified AST.Expression.Canonical as Canonical
13import qualified AST.Pattern as P
14import qualified AST.Variable as V
15import qualified Reporting.Annotation as A
20definitions :: Canonical.Expr -> Canonical.Expr
21definitions expression =
22 evalState (reorder expression) Set.empty
25free :: String -> State (Set.Set String) ()
30freeIfLocal :: V.Canonical -> State (Set.Set String) ()
31freeIfLocal (V.Canonical home name) =
34 V.BuiltIn -> return ()
35 V.Module _ -> return ()
40reorder :: Canonical.Expr -> State (Set.Set String) Canonical.Expr
41reorder (A.A ann expression) =
44 -- Be careful adding and restricting freeVars
49 Lambda pattern body ->
50 uncurry Lambda <$> bindingReorder (pattern,body)
52 Binop op leftExpr rightExpr ->
54 Binop op <$> reorder leftExpr <*> reorder rightExpr
57 Case <$> reorder expr <*> mapM bindingReorder cases
61 Data name <$> mapM reorder exprs
63 -- Just pipe the reorder though
67 Range lowExpr highExpr ->
68 Range <$> reorder lowExpr <*> reorder highExpr
71 ExplicitList <$> mapM reorder es
74 App <$> reorder func <*> reorder arg
76 MultiIf branches finally ->
78 <$> mapM (\(cond,branch) -> (,) <$> reorder cond <*> reorder branch) branches
81 Access record field ->
86 Remove record field ->
91 Insert record field expr ->
97 Modify record fields ->
100 <*> mapM (\(field,expr) -> (,) field <$> reorder expr) fields
104 <$> mapM (\(field,expr) -> (,) field <$> reorder expr) fields
115 Out name expr tipe ->
116 (\e -> Out name e tipe) <$> reorder expr
118 Task name expr tipe ->
119 (\e -> Task name e tipe) <$> reorder expr
124 -- Actually do some reordering
126 do body' <- reorder body
128 -- Sort defs into strongly connected components.This
129 -- allows the programmer to write definitions in whatever
130 -- order they please, we can still define things in order
131 -- and generalize polymorphic functions when appropriate.
132 sccs <- Graph.stronglyConnComp <$> buildDefGraph defs
133 let defss = map Graph.flattenSCC sccs
135 -- remove let-bound variables from the context
136 forM_ defs $ \(Canonical.Definition pattern _ _) -> do
138 mapM free (ctors pattern)
141 foldr (\ds bod -> A.A ann (Let ds bod)) body' defss
146ctors :: P.CanonicalPattern -> [String]
147ctors (A.A _ pattern) =
164 P.Data (V.Canonical home name) ps ->
166 V.Local -> name : rest
170 rest = concatMap ctors ps
173bound :: P.CanonicalPattern -> State (Set.Set String) ()
175 let boundVars = P.boundVarSet pattern
177 modify (\freeVars -> Set.difference freeVars boundVars)
181 :: (P.CanonicalPattern, Canonical.Expr)
182 -> State (Set.Set String) (P.CanonicalPattern, Canonical.Expr)
183bindingReorder (pattern, expr) =
184 do expr' <- reorder expr
186 mapM_ free (ctors pattern)
187 return (pattern, expr')
190-- BUILD DEPENDENCY GRAPH BETWEEN DEFINITIONS
192-- This also reorders the all of the sub-expressions in the Def list.
195 -> State (Set.Set String) [(Canonical.Def, Int, [Int])]
197 do pdefsDeps <- mapM reorderAndGetDependencies defs
198 return $ realDeps (addKey pdefsDeps)
200 addKey :: [(Canonical.Def, [String])] -> [(Canonical.Def, Int, [String])]
202 zipWith (\n (pdef,deps) -> (pdef,n,deps)) [0..]
204 variableToKey :: (Canonical.Def, Int, [String]) -> [(String, Int)]
205 variableToKey (Canonical.Definition pattern _ _, key, _) =
206 [ (var, key) | var <- P.boundVarList pattern ]
208 variableToKeyMap :: [(Canonical.Def, Int, [String])] -> Map.Map String Int
209 variableToKeyMap pdefsDeps =
210 Map.fromList (concatMap variableToKey pdefsDeps)
212 realDeps :: [(Canonical.Def, Int, [String])] -> [(Canonical.Def, Int, [Int])]
214 map convert pdefsDeps
216 varDict = variableToKeyMap pdefsDeps
217 convert (pdef, key, deps) =
218 (pdef, key, Maybe.mapMaybe (flip Map.lookup varDict) deps)
221reorderAndGetDependencies
223 -> State (Set.Set String) (Canonical.Def, [String])
224reorderAndGetDependencies (Canonical.Definition pattern expr mType) =
225 do globalFrees <- get
226 -- work in a fresh environment
228 expr' <- reorder expr
230 -- merge with global frees
231 modify (Set.union globalFrees)
232 return (Canonical.Definition pattern expr' mType, Set.toList localFrees)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list