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 Elm.Name as N
19import qualified Optimize.Expression as Expr
20import qualified Optimize.Names as Names
21import qualified Optimize.Port as Port
22import qualified Reporting.Annotation as A
31 { _fields :: Map.Map N.Name Int
37 Map.Map Opt.Global Opt.Node
40optimize :: Can.Module -> Graph
41optimize (Can.Module home _ _ decls unions aliases _ effects) =
42 addEffects home effects $
43 addUnions home unions $
44 addAliases home aliases $
46 Graph Map.empty Map.empty
53addUnions :: ModuleName.Canonical -> Map.Map N.Name Can.Union -> Graph -> Graph
54addUnions home unions (Graph fields nodes) =
56 Map.foldr (addUnion home) nodes unions
59addUnion :: ModuleName.Canonical -> Can.Union -> Nodes -> Nodes
60addUnion home (Can.Union _ ctors) nodes =
61 foldr (addCtor home) nodes ctors
64addCtor :: ModuleName.Canonical -> (N.Name, [t]) -> Nodes -> Nodes
65addCtor home (ctor, args) nodes =
68 map N.localFromInt [ 1 .. length args ]
71 Opt.Function argNames $
72 Opt.Ctor ctor (map Opt.VarLocal argNames)
75 Opt.Define function Set.empty Set.empty
77 Map.insert (Opt.Global home ctor) node nodes
84addAliases :: ModuleName.Canonical -> Map.Map N.Name Can.Alias -> Graph -> Graph
85addAliases home aliases graph =
86 Map.foldrWithKey (addAlias home) graph aliases
89addAlias :: ModuleName.Canonical -> N.Name -> Can.Alias -> Graph -> Graph
90addAlias home name (Can.Alias _ _ maybeFields) graph@(Graph fieldCounts nodes) =
98 Opt.Function fields $ Opt.Record $
99 Map.fromList $ map toPair fields
102 Opt.Define function Set.empty Set.empty
105 (foldr addOne fieldCounts fields)
106 (Map.insert (Opt.Global home name) node nodes)
109toPair :: N.Name -> (N.Name, Opt.Expr)
111 ( field, Opt.VarLocal field )
114addOne :: N.Name -> Map.Map N.Name Int -> Map.Map N.Name Int
116 Map.insertWith (+) name 1 fields
123addEffects :: ModuleName.Canonical -> Can.Effects -> Graph -> Graph
124addEffects home effects graph@(Graph fields nodes) =
130 Map.foldrWithKey (addPort home) graph ports
132 Can.Manager _ _ _ manager ->
135 fx = Opt.Global home "$fx$"
136 cmd = Opt.Global home "command"
137 sub = Opt.Global home "subscription"
142 Map.insert cmd link $
143 Map.insert fx (Opt.Manager Opt.Cmd) nodes
146 Map.insert sub link $
147 Map.insert fx (Opt.Manager Opt.Sub) nodes
150 Map.insert cmd link $
151 Map.insert sub link $
152 Map.insert fx (Opt.Manager Opt.Fx) nodes
156addPort :: ModuleName.Canonical -> N.Name -> Can.Port -> Graph -> Graph
157addPort home name port_ graph =
159 Can.Incoming _ tipe ->
161 (kernels, globals, fields, decoder) = Names.run (Port.toDecoder tipe)
162 node = Opt.PortIncoming decoder kernels globals
164 addToGraph (Opt.Global home name) node fields graph
166 Can.Outgoing _ tipe ->
168 (kernels, globals, fields, encoder) = Names.run (Port.toEncoder tipe)
169 node = Opt.PortOutgoing encoder kernels globals
171 addToGraph (Opt.Global home name) node fields graph
178addDecls :: ModuleName.Canonical -> Can.Decls -> Graph -> Graph
179addDecls home decls graph =
181 Can.Declare def subDecls ->
182 addDecls home subDecls (addDef home def graph)
184 Can.DeclareRec defs subDecls ->
185 addDecls home subDecls (addRecDefs home defs graph)
187 Can.SaveTheEnvironment ->
195addDef :: ModuleName.Canonical -> Can.Def -> Graph -> Graph
196addDef home def graph =
198 Can.Def (A.At _ name) args body ->
199 addDefHelp (Opt.Global home name) args body graph
201 Can.TypedDef (A.At _ name) _ typedArgs body _ ->
202 addDefHelp (Opt.Global home name) (map fst typedArgs) body graph
205addDefHelp :: Opt.Global -> [Can.Pattern] -> Can.Expr -> Graph -> Graph
206addDefHelp name args body graph =
210 (kernels, globals, fields, value) =
211 Names.run (Expr.optimize Set.empty body)
213 addToGraph name (Opt.Define value kernels globals) fields graph
217 (kernels, globals, fields, function) =
219 do (argNames, defss) <- Expr.destructArgs args
220 obody <- Expr.optimize Set.empty body
221 pure $ Opt.Function argNames $
222 foldr Opt.Let obody (concat defss)
224 addToGraph name (Opt.Define function kernels globals) fields graph
227addToGraph :: Opt.Global -> Opt.Node -> Map.Map N.Name Int -> Graph -> Graph
228addToGraph name node fields (Graph fieldCounts nodes) =
230 (Map.unionWith (+) fields fieldCounts)
231 (Map.insert name node nodes)
238addRecDefs :: ModuleName.Canonical -> [Can.Def] -> Graph -> Graph
239addRecDefs home defs graph =
242 foldr addValueName Set.empty defs
245 Opt.Global home (N.toCompositeName cycleValues)
247 (kernels, globals, fields, State cyclicValuePairs newGraph) =
249 foldM (addRecDef home dummyName cycleValues) (State [] graph) defs
252 Opt.Cycle cyclicValuePairs kernels globals
254 addToGraph dummyName node fields newGraph
257addValueName :: Can.Def -> Set.Set N.Name -> Set.Set N.Name
258addValueName def valueNames =
260 Can.Def (A.At _ name) [] _ ->
261 Set.insert name valueNames
263 Can.TypedDef (A.At _ name) _ [] _ _ ->
264 Set.insert name valueNames
276 { _values :: [(N.Name, Opt.Expr)]
281addRecDef :: ModuleName.Canonical -> Opt.Global -> Expr.Cycle -> State -> Can.Def -> Names.Tracker State
282addRecDef home dummyName cycle state@(State values graph) def =
284 Can.Def (A.At _ name) [] body ->
285 addRecValue home dummyName cycle name body state
287 Can.TypedDef (A.At _ name) _ [] body _ ->
288 addRecValue home dummyName cycle name body state
292 (kernels, globals, fields, odef) =
293 Names.run (Expr.optimizePotentialTailCall Set.empty def)
295 pure $ State values $
298 let node = Opt.Define body kernels globals in
299 addToGraph (Opt.Global home name) node fields graph
301 Opt.TailDef name args body ->
302 let node = Opt.DefineTailFunc args body kernels globals in
303 addToGraph (Opt.Global home name) node fields graph
306addRecValue :: ModuleName.Canonical -> Opt.Global -> Expr.Cycle -> N.Name -> Can.Expr -> State -> Names.Tracker State
307addRecValue home dummyName cycle name body (State values (Graph fields nodes)) =
308 do obody <- Expr.optimize cycle body
311 { _values = (name, obody) : values
312 , _graph = Graph fields $
313 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