@@ -1,346 +0,0 @@
1−{-# OPTIONS_GHC -Wall #-}
2−module Canonicalize.Sort (definitions) where
4−import qualified Data.Foldable as F
5−import qualified Data.Graph as Graph
6−import qualified Data.Map as Map
7−import qualified Data.Maybe as Maybe
8−import qualified Data.Set as Set
9−import Data.Text (Text)
11−import qualified AST.Expression.Canonical as C
12−import qualified AST.Pattern as P
13−import qualified AST.Variable as V
14−import qualified Reporting.Annotation as A
15−import qualified Reporting.Error.Canonicalize as E
16−import qualified Reporting.Result as R
23−definitions :: (Monoid i) => C.Expr -> R.Result i w E.Error C.Expr
24−definitions expression =
26− (R.Result _ warnings answer) =
29− R.Result mempty warnings answer
34− { _immediate :: Set.Set Text
35− , _delayed :: Set.Set Text
36− , _tags :: Set.Set Text
40−instance Monoid LocalVars where
42− LocalVars Set.empty Set.empty Set.empty
44− mappend (LocalVars i1 d1 t1) (LocalVars i2 d2 t2) =
45− LocalVars (Set.union i1 i2) (Set.union d1 d2) (Set.union t1 t2)
48−addTag :: Text -> a -> R.Result LocalVars w e a
50− R.accumulate (LocalVars Set.empty Set.empty (Set.singleton name)) value
53−addImmediate :: V.Canonical -> a -> R.Result LocalVars w e a
54−addImmediate (V.Canonical home name) value =
57− R.accumulate (LocalVars (Set.singleton name) Set.empty Set.empty) value
60− R.accumulate (LocalVars (Set.singleton name) Set.empty Set.empty) value
69−capture :: P.Canonical -> R.Result LocalVars w e a -> R.Result LocalVars w e a
70−capture pattern result =
71− captureVars (P.boundVarSet pattern) result
74−captureVars :: Set.Set Text -> R.Result LocalVars w e a -> R.Result LocalVars w e a
75−captureVars bound (R.Result (LocalVars immediate delayed tags) warnings result) =
78− LocalVars (Set.difference immediate bound) (Set.difference delayed bound) tags
80− R.Result localVars warnings result
83−delay :: R.Result LocalVars w e a -> R.Result LocalVars w e a
84−delay (R.Result (LocalVars immediate delayed tags) warnings result) =
85− R.Result (LocalVars Set.empty (Set.union immediate delayed) tags) warnings result
89−-- REORDER EXPRESSIONS
92−reorder :: C.Expr -> R.Result LocalVars w E.Error C.Expr
93−reorder (A.A region expression) =
97− addImmediate var expression
99− C.Lambda pattern body ->
101− bindingReorder C.Lambda (pattern, body)
103− C.Binop op leftExpr rightExpr ->
104− do binop <- C.Binop op <$> reorder leftExpr <*> reorder rightExpr
105− addImmediate op binop
107− C.Case expr cases ->
108− C.Case <$> reorder expr <*> traverse (bindingReorder (,)) cases
110− C.Ctor ctor@(V.Canonical _ name) exprs ->
111− addTag name =<< (C.Ctor ctor <$> traverse reorder exprs)
113− -- Just pipe the reorder though
118− C.List <$> traverse reorder es
121− C.App <$> reorder func <*> reorder arg
123− C.If branches finally ->
125− <$> traverse (\(cond,branch) -> (,) <$> reorder cond <*> reorder branch) branches
128− C.Access record field ->
133− C.Update record fields ->
136− <*> traverse (traverse reorder) fields
140− <$> traverse (traverse reorder) fields
148− C.OutgoingPort _ _ ->
151− C.IncomingPort _ _ ->
155− error "DANGER - Program AST nodes should not be in def sorting."
163− -- Actually do some reordering
165− case reorderDefs defs of
166− R.Result () warnings (R.Err errors) ->
167− R.Result mempty warnings (R.Err errors)
169− R.Result () warnings (R.Ok (boundVars, defGroups, defLocals)) ->
170− captureVars boundVars $
171− do _ <- R.Result mempty warnings (R.Ok ())
172− newBody <- reorder body
173− R.accumulate defLocals $ A.drop $
174− foldr (\defGroup expr -> A.A region (C.Let defGroup expr)) newBody defGroups
182− :: (P.Canonical -> C.Expr -> a)
183− -> (P.Canonical, C.Expr)
184− -> R.Result LocalVars w E.Error a
185−bindingReorder func (pattern, expr) =
186− do answer <- func pattern <$> capture pattern (reorder expr)
187− addPatternTags pattern answer
194−addPatternTags :: P.Canonical -> a -> R.Result LocalVars w e a
195−addPatternTags pattern value =
196− R.accumulate (LocalVars Set.empty Set.empty (getPatternTags pattern)) value
199−getPatternTags :: P.Canonical -> Set.Set Text
200−getPatternTags (A.A _ pattern) =
205− P.Alias _ subPattern ->
206− getPatternTags subPattern
217− P.Ctor (V.Canonical home name) patterns ->
220− Set.unions (map getPatternTags patterns)
224− Set.insert name freeCtors
227− Set.insert name freeCtors
237−-- REORDER DEFINITIONS
242− -> R.Result () w E.Error (Set.Set Text, [[C.Def]], LocalVars)
244− do rawNodes <- sequenceA $ zipWith toRawNode [0..] defs
245− let boundVarDict = toBoundVarDict rawNodes
246− _ <- detectLoops boundVarDict rawNodes
247− return $ groupDefs boundVarDict rawNodes
250−toRawNode :: Int -> C.Def -> R.Result () w E.Error (C.Def, Int, LocalVars)
251−toRawNode index (C.Def region pattern body maybeType) =
253− (R.Result localVars warnings answer) =
254− addPatternTags pattern =<< reorder body
256− toRawNodeHelp newBody =
257− ( C.Def region pattern newBody maybeType, index, localVars )
259− toRawNodeHelp <$> R.Result () warnings answer
262−toBoundVarDict :: [(C.Def, Int, a)] -> Map.Map Text Int
263−toBoundVarDict defAndDeps =
264− Map.fromList (concatMap toBoundVarDictHelp defAndDeps)
267−toBoundVarDictHelp :: (C.Def, Int, a) -> [(Text, Int)]
268−toBoundVarDictHelp (C.Def _ pattern _ _, key, _) =
269− map (\(A.A _ name) -> (name, key)) (P.boundVars pattern)
279− -> (C.Def, Int, deps)
280− -> (C.Def, Int, [Int])
281−toNode toVars boundVarDict (def, index, deps) =
284− Maybe.mapMaybe (\var -> Map.lookup var boundVarDict) (toVars deps)
286− ( def, index, localDeps )
289−immediateOnly :: LocalVars -> [Text]
290−immediateOnly (LocalVars immediate _ _) =
291− Set.toList immediate
294−allVars :: LocalVars -> [Text]
295−allVars (LocalVars immediate delayed tags) =
296− Set.toList immediate ++ Set.toList delayed ++ Set.toList tags
305− -> [(C.Def, Int, LocalVars)]
306− -> R.Result () w E.Error ()
307−detectLoops boundVarDict rawNodes =
308− F.traverse_ detectLoopsHelp $
309− Graph.stronglyConnComp $
310− map (toNode immediateOnly boundVarDict) rawNodes
313−detectLoopsHelp :: Graph.SCC C.Def -> R.Result () w E.Error ()
314−detectLoopsHelp scc =
316− Graph.AcyclicSCC _ ->
319− Graph.CyclicSCC defs ->
324− def@(C.Def region (A.A nameRegion _) _ _) : rest ->
325− R.throw region $ E.BadRecursion nameRegion def rest
334− -> [(C.Def, Int, LocalVars)]
335− -> ( Set.Set Text, [[C.Def]], LocalVars )
336−groupDefs boundVarDict rawNodes =
339− mconcat (map (\(_, _, localVars) -> localVars) rawNodes)
342− map Graph.flattenSCC $
343− Graph.stronglyConnComp $
344− map (toNode allVars boundVarDict) rawNodes
346− ( Map.keysSet boundVarDict, defGroups, allLocalVars )