1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
10import Prelude hiding (cycle)
11import Control.Monad (foldM)
12import qualified Data.Map as Map
13import qualified Data.Set as Set
15import qualified AST.Canonical as Can
16import qualified AST.Optimized as Opt
17import qualified AST.Module.Name as ModuleName
18import qualified Data.Index as Index
19import qualified Elm.Name as N
20import qualified Optimize.Expression as Expr
21import qualified Optimize.Names as Names
22import qualified Optimize.Port as Port
23import qualified Reporting.Annotation as A
32 { _fields :: Map.Map N.Name Int
38 Map.Map Opt.Global Opt.Node
41optimize :: Can.Module -> Graph
42optimize (Can.Module home _ _ decls unions aliases _ effects) =
43 addEffects home effects $
44 addUnions home unions $
45 addAliases home aliases $
47 Graph Map.empty Map.empty
54addUnions :: ModuleName.Canonical -> Map.Map N.Name Can.Union -> Graph -> Graph
55addUnions home unions (Graph fields nodes) =
57 Map.foldr (addUnion home) nodes unions
60addUnion :: ModuleName.Canonical -> Can.Union -> Nodes -> Nodes
61addUnion home (Can.Union _ ctors) nodes =
63 Map.fromList (Index.indexedMap (ctorToNode home) ctors)
66ctorToNode :: ModuleName.Canonical -> Index.ZeroBased -> (N.Name, [t]) -> (Opt.Global, Opt.Node)
67ctorToNode home index (name, args) =
68 ( Opt.Global home name, Opt.Ctor name index (length args) )
75addAliases :: ModuleName.Canonical -> Map.Map N.Name Can.Alias -> Graph -> Graph
76addAliases home aliases graph =
77 Map.foldrWithKey (addAlias home) graph aliases
80addAlias :: ModuleName.Canonical -> N.Name -> Can.Alias -> Graph -> Graph
81addAlias home name (Can.Alias _ _ maybeFields) graph@(Graph fieldCounts nodes) =
89 Opt.Function fields $ Opt.Record $
90 Map.fromList $ map toPair fields
93 Opt.Define function Set.empty Set.empty
96 (foldr addOne fieldCounts fields)
97 (Map.insert (Opt.Global home name) node nodes)
100toPair :: N.Name -> (N.Name, Opt.Expr)
102 ( field, Opt.VarLocal field )
105addOne :: N.Name -> Map.Map N.Name Int -> Map.Map N.Name Int
107 Map.insertWith (+) name 1 fields
114addEffects :: ModuleName.Canonical -> Can.Effects -> Graph -> Graph
115addEffects home effects graph@(Graph fields nodes) =
121 Map.foldrWithKey (addPort home) graph ports
123 Can.Manager _ _ _ manager ->
126 fx = Opt.Global home "$fx$"
127 cmd = Opt.Global home "command"
128 sub = Opt.Global home "subscription"
133 Map.insert cmd link $
134 Map.insert fx (Opt.Manager Opt.Cmd) nodes
137 Map.insert sub link $
138 Map.insert fx (Opt.Manager Opt.Sub) nodes
141 Map.insert cmd link $
142 Map.insert sub link $
143 Map.insert fx (Opt.Manager Opt.Fx) nodes
147addPort :: ModuleName.Canonical -> N.Name -> Can.Port -> Graph -> Graph
148addPort home name port_ graph =
150 Can.Incoming _ tipe ->
152 (kernels, globals, fields, decoder) = Names.run (Port.toDecoder tipe)
153 node = Opt.PortIncoming decoder kernels globals
155 addToGraph (Opt.Global home name) node fields graph
157 Can.Outgoing _ tipe ->
159 (kernels, globals, fields, encoder) = Names.run (Port.toEncoder tipe)
160 node = Opt.PortOutgoing encoder kernels globals
162 addToGraph (Opt.Global home name) node fields graph
169addDecls :: ModuleName.Canonical -> Can.Decls -> Graph -> Graph
170addDecls home decls graph =
172 Can.Declare def subDecls ->
173 addDecls home subDecls (addDef home def graph)
175 Can.DeclareRec defs subDecls ->
176 addDecls home subDecls (addRecDefs home defs graph)
178 Can.SaveTheEnvironment ->
186addDef :: ModuleName.Canonical -> Can.Def -> Graph -> Graph
187addDef home def graph =
189 Can.Def (A.At _ name) args body ->
190 addDefHelp (Opt.Global home name) args body graph
192 Can.TypedDef (A.At _ name) _ typedArgs body _ ->
193 addDefHelp (Opt.Global home name) (map fst typedArgs) body graph
196addDefHelp :: Opt.Global -> [Can.Pattern] -> Can.Expr -> Graph -> Graph
197addDefHelp name args body graph =
201 (kernels, globals, fields, value) =
202 Names.run (Expr.optimize Set.empty body)
204 addToGraph name (Opt.Define value kernels globals) fields graph
208 (kernels, globals, fields, function) =
210 do (argNames, defss) <- Expr.destructArgs args
211 obody <- Expr.optimize Set.empty body
212 pure $ Opt.Function argNames $
213 foldr Opt.Let obody (concat defss)
215 addToGraph name (Opt.Define function kernels globals) fields graph
218addToGraph :: Opt.Global -> Opt.Node -> Map.Map N.Name Int -> Graph -> Graph
219addToGraph name node fields (Graph fieldCounts nodes) =
221 (Map.unionWith (+) fields fieldCounts)
222 (Map.insert name node nodes)
229addRecDefs :: ModuleName.Canonical -> [Can.Def] -> Graph -> Graph
230addRecDefs home defs graph =
233 foldr addValueName Set.empty defs
236 Opt.Global home (N.toCompositeName cycleValues)
238 (kernels, globals, fields, State cyclicValuePairs newGraph) =
240 foldM (addRecDef home dummyName cycleValues) (State [] graph) defs
243 Opt.Cycle cyclicValuePairs kernels globals
245 addToGraph dummyName node fields newGraph
248addValueName :: Can.Def -> Set.Set N.Name -> Set.Set N.Name
249addValueName def valueNames =
251 Can.Def (A.At _ name) [] _ ->
252 Set.insert name valueNames
254 Can.TypedDef (A.At _ name) _ [] _ _ ->
255 Set.insert name valueNames
267 { _values :: [(N.Name, Opt.Expr)]
272addRecDef :: ModuleName.Canonical -> Opt.Global -> Expr.Cycle -> State -> Can.Def -> Names.Tracker State
273addRecDef home dummyName cycle state@(State values graph) def =
275 Can.Def (A.At _ name) [] body ->
276 addRecValue home dummyName cycle name body state
278 Can.TypedDef (A.At _ name) _ [] body _ ->
279 addRecValue home dummyName cycle name body state
283 (kernels, globals, fields, odef) =
284 Names.run (Expr.optimizePotentialTailCall Set.empty def)
286 pure $ State values $
289 let node = Opt.Define body kernels globals in
290 addToGraph (Opt.Global home name) node fields graph
292 Opt.TailDef name args body ->
293 let node = Opt.DefineTailFunc args body kernels globals in
294 addToGraph (Opt.Global home name) node fields graph
297addRecValue :: ModuleName.Canonical -> Opt.Global -> Expr.Cycle -> N.Name -> Can.Expr -> State -> Names.Tracker State
298addRecValue home dummyName cycle name body (State values (Graph fields nodes)) =
299 do obody <- Expr.optimize cycle body
302 { _values = (name, obody) : values
303 , _graph = Graph fields $
304 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