1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
9import Prelude hiding (cycle)
10import Control.Monad (foldM)
11import qualified Data.Map as Map
12import qualified Data.Set as Set
14import qualified AST.Canonical as Can
15import qualified AST.Optimized as Opt
16import qualified AST.Module.Name as ModuleName
17import qualified Elm.Name as N
18import qualified Optimize.Expression as Expr
19import qualified Optimize.Names as Names
20import qualified Optimize.Port as Port
21import qualified Reporting.Annotation as A
28optimize :: Can.Module -> Opt.Graph
29optimize (Can.Module home _ _ decls unions aliases _ effects) =
30 addEffects home effects $
31 addUnions home unions $
32 addAliases home aliases $
34 Opt.Graph Map.empty Map.empty
41addUnions :: ModuleName.Canonical -> Map.Map N.Name Can.Union -> Opt.Graph -> Opt.Graph
42addUnions home unions (Opt.Graph fields nodes) =
44 Map.foldr (addUnion home) nodes unions
48 Map.Map Opt.Global Opt.Node
51addUnion :: ModuleName.Canonical -> Can.Union -> Nodes -> Nodes
52addUnion home (Can.Union _ ctors) nodes =
53 foldr (addCtor home) nodes ctors
56addCtor :: ModuleName.Canonical -> (N.Name, [t]) -> Nodes -> Nodes
57addCtor home (ctor, args) nodes =
60 map N.localFromInt [ 1 .. length args ]
63 Opt.Function argNames $
64 Opt.Ctor ctor (map Opt.VarLocal argNames)
67 Opt.Define function Set.empty Set.empty
69 Map.insert (Opt.Global home ctor) node nodes
76addAliases :: ModuleName.Canonical -> Map.Map N.Name Can.Alias -> Opt.Graph -> Opt.Graph
77addAliases home aliases graph =
78 Map.foldrWithKey (addAlias home) graph aliases
81addAlias :: ModuleName.Canonical -> N.Name -> Can.Alias -> Opt.Graph -> Opt.Graph
82addAlias home name (Can.Alias _ _ maybeFields) graph@(Opt.Graph fieldCounts nodes) =
90 Opt.Function fields $ Opt.Record $
91 Map.fromList $ map toPair fields
94 Opt.Define function Set.empty Set.empty
97 (foldr addOne fieldCounts fields)
98 (Map.insert (Opt.Global home name) node nodes)
101toPair :: N.Name -> (N.Name, Opt.Expr)
103 ( field, Opt.VarLocal field )
106addOne :: N.Name -> Map.Map N.Name Int -> Map.Map N.Name Int
108 Map.insertWith (+) name 1 fields
115addEffects :: ModuleName.Canonical -> Can.Effects -> Opt.Graph -> Opt.Graph
116addEffects home effects graph@(Opt.Graph fields nodes) =
122 Map.foldrWithKey (addPort home) graph ports
124 Can.Manager _ _ _ manager ->
127 fx = Opt.Global home "$fx$"
128 cmd = Opt.Global home "command"
129 sub = Opt.Global home "subscription"
134 Map.insert cmd link $
135 Map.insert fx (Opt.Manager Opt.Cmd) nodes
138 Map.insert sub link $
139 Map.insert fx (Opt.Manager Opt.Sub) nodes
142 Map.insert cmd link $
143 Map.insert sub link $
144 Map.insert fx (Opt.Manager Opt.Fx) nodes
148addPort :: ModuleName.Canonical -> N.Name -> Can.Port -> Opt.Graph -> Opt.Graph
149addPort home name port_ graph =
151 Can.Incoming _ tipe ->
153 (kernels, globals, fields, decoder) = Names.run (Port.toDecoder tipe)
154 node = Opt.PortIncoming decoder kernels globals
156 addToGraph (Opt.Global home name) node fields graph
158 Can.Outgoing _ tipe ->
160 (kernels, globals, fields, encoder) = Names.run (Port.toEncoder tipe)
161 node = Opt.PortOutgoing encoder kernels globals
163 addToGraph (Opt.Global home name) node fields graph
170addDecls :: ModuleName.Canonical -> Can.Decls -> Opt.Graph -> Opt.Graph
171addDecls home decls graph =
173 Can.Declare def subDecls ->
174 addDecls home subDecls (addDef home def graph)
176 Can.DeclareRec defs subDecls ->
177 addDecls home subDecls (addRecDefs home defs graph)
179 Can.SaveTheEnvironment ->
187addDef :: ModuleName.Canonical -> Can.Def -> Opt.Graph -> Opt.Graph
188addDef home def graph =
190 Can.Def (A.At _ name) args body ->
191 addDefHelp (Opt.Global home name) args body graph
193 Can.TypedDef (A.At _ name) _ typedArgs body _ ->
194 addDefHelp (Opt.Global home name) (map fst typedArgs) body graph
197addDefHelp :: Opt.Global -> [Can.Pattern] -> Can.Expr -> Opt.Graph -> Opt.Graph
198addDefHelp name args body graph =
202 (kernels, globals, fields, value) =
203 Names.run (Expr.optimize Set.empty body)
205 addToGraph name (Opt.Define value kernels globals) fields graph
209 (kernels, globals, fields, function) =
211 do (argNames, defss) <- Expr.destructArgs args
212 obody <- Expr.optimize Set.empty body
213 pure $ Opt.Function argNames $
214 foldr Opt.Let obody (concat defss)
216 addToGraph name (Opt.Define function kernels globals) fields graph
219addToGraph :: Opt.Global -> Opt.Node -> Map.Map N.Name Int -> Opt.Graph -> Opt.Graph
220addToGraph name node fields (Opt.Graph fieldCounts nodes) =
222 (Map.unionWith (+) fields fieldCounts)
223 (Map.insert name node nodes)
230addRecDefs :: ModuleName.Canonical -> [Can.Def] -> Opt.Graph -> Opt.Graph
231addRecDefs home defs graph =
234 foldr addValueName Set.empty defs
237 Opt.Global home (N.toCompositeName cycleValues)
239 (kernels, globals, fields, State cyclicValuePairs newGraph) =
241 foldM (addRecDef home dummyName cycleValues) (State [] graph) defs
244 Opt.Cycle cyclicValuePairs kernels globals
246 addToGraph dummyName node fields newGraph
249addValueName :: Can.Def -> Set.Set N.Name -> Set.Set N.Name
250addValueName def valueNames =
252 Can.Def (A.At _ name) [] _ ->
253 Set.insert name valueNames
255 Can.TypedDef (A.At _ name) _ [] _ _ ->
256 Set.insert name valueNames
268 { _values :: [(N.Name, Opt.Expr)]
269 , _graph :: Opt.Graph
273addRecDef :: ModuleName.Canonical -> Opt.Global -> Expr.Cycle -> State -> Can.Def -> Names.Tracker State
274addRecDef home dummyName cycle state@(State values graph) def =
276 Can.Def (A.At _ name) [] body ->
277 addRecValue home dummyName cycle name body state
279 Can.TypedDef (A.At _ name) _ [] body _ ->
280 addRecValue home dummyName cycle name body state
284 (kernels, globals, fields, odef) =
285 Names.run (Expr.optimizePotentialTailCall Set.empty def)
287 pure $ State values $
290 let node = Opt.Define body kernels globals in
291 addToGraph (Opt.Global home name) node fields graph
293 Opt.TailDef name args body ->
294 let node = Opt.DefineTailFunc args body kernels globals in
295 addToGraph (Opt.Global home name) node fields graph
298addRecValue :: ModuleName.Canonical -> Opt.Global -> Expr.Cycle -> N.Name -> Can.Expr -> State -> Names.Tracker State
299addRecValue home dummyName cycle name body (State values (Opt.Graph fields nodes)) =
300 do obody <- Expr.optimize cycle body
303 { _values = (name, obody) : values
304 , _graph = Opt.Graph fields $
305 Map.insert (Opt.Global home name) (Opt.Link dummyName) nodes
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