on master help sign in
Shuffle the optimized AST to make code gen easier
8a89c86Evan Czaplicki
src/AST/Optimized.hs+25−27
@@ -39,17 +39,16 @@ data Expr
39 | VarLocal N.Name
39 | VarLocal N.Name
40 | VarGlobal Global
40 | VarGlobal Global
41 | VarCycle ModuleName.Canonical N.Name
41 | VarCycle ModuleName.Canonical N.Name
42− | VarDebug N.Name ModuleName.Canonical R.Region (Maybe Expr)
42+ | VarDebug N.Name ModuleName.Canonical R.Region (Maybe N.Name)
43 | VarKernel N.Name N.Name
43 | VarKernel N.Name N.Name
44 | List [Expr]
44 | List [Expr]
45 | Function [N.Name] Expr
45 | Function [N.Name] Expr
46 | Call Expr [Expr]
46 | Call Expr [Expr]
47− | TailCall N.Name [N.Name] [Expr]
47+ | TailCall N.Name [(N.Name, Expr)]
48 | If [(Expr, Expr)] Expr
48 | If [(Expr, Expr)] Expr
49 | Let Def Expr
49 | Let Def Expr
50− | Case N.Name (Decider Choice) [(Int, Expr)]
50+ | Case N.Name N.Name (Decider Choice) [(Int, Expr)]
51− | Ctor N.Name [Expr]
51+ | Index Expr Int
52− | CtorAccess Expr Index.ZeroBased
53 | Accessor N.Name
52 | Accessor N.Name
54 | Access Expr N.Name
53 | Access Expr N.Name
55 | Update Expr (Map.Map N.Name Expr)
54 | Update Expr (Map.Map N.Name Expr)
@@ -116,6 +115,7 @@ data Main
116data Node
115data Node
117 = Define Expr (Set.Set N.Name) (Set.Set Global)
116 = Define Expr (Set.Set N.Name) (Set.Set Global)
118 | DefineTailFunc [N.Name] Expr (Set.Set N.Name) (Set.Set Global)
117 | DefineTailFunc [N.Name] Expr (Set.Set N.Name) (Set.Set Global)
118+ | Ctor N.Name Index.ZeroBased Int
119 | Link Global
119 | Link Global
120 | Cycle [(N.Name, Expr)] (Set.Set N.Name) (Set.Set Global)
120 | Cycle [(N.Name, Expr)] (Set.Set N.Name) (Set.Set Global)
121 | PortIncoming Expr (Set.Set N.Name) (Set.Set Global)
121 | PortIncoming Expr (Set.Set N.Name) (Set.Set Global)
@@ -150,19 +150,18 @@ instance Binary Expr where
150 List a -> putWord8 9 >> put a
150 List a -> putWord8 9 >> put a
151 Function a b -> putWord8 10 >> put a >> put b
151 Function a b -> putWord8 10 >> put a >> put b
152 Call a b -> putWord8 11 >> put a >> put b
152 Call a b -> putWord8 11 >> put a >> put b
153− TailCall a b c -> putWord8 12 >> put a >> put b >> put c
153+ TailCall a b -> putWord8 12 >> put a >> put b
154 If a b -> putWord8 13 >> put a >> put b
154 If a b -> putWord8 13 >> put a >> put b
155 Let a b -> putWord8 14 >> put a >> put b
155 Let a b -> putWord8 14 >> put a >> put b
156− Case a b c -> putWord8 15 >> put a >> put b >> put c
156+ Case a b c d -> putWord8 15 >> put a >> put b >> put c >> put d
157− Ctor a b -> putWord8 16 >> put a >> put b
157+ Index a b -> putWord8 16 >> put a >> put b
158− CtorAccess a b -> putWord8 17 >> put a >> put b
159− Accessor a -> putWord8 18 >> put a
158+ Accessor a -> putWord8 17 >> put a
160− Access a b -> putWord8 19 >> put a >> put b
159+ Access a b -> putWord8 18 >> put a >> put b
161− Update a b -> putWord8 20 >> put a >> put b
160+ Update a b -> putWord8 19 >> put a >> put b
162− Record a -> putWord8 21 >> put a
161+ Record a -> putWord8 20 >> put a
163− Unit -> putWord8 22
162+ Unit -> putWord8 21
164− Tuple a b c -> putWord8 23 >> put a >> put b >> put c
163+ Tuple a b c -> putWord8 22 >> put a >> put b >> put c
165− Shader a -> putWord8 24 >> put a
164+ Shader a -> putWord8 23 >> put a
166
165
167 get =
166 get =
168 do word <- getWord8
167 do word <- getWord8
@@ -179,19 +178,18 @@ instance Binary Expr where
179 9 -> liftM List get
178 9 -> liftM List get
180 10 -> liftM2 Function get get
179 10 -> liftM2 Function get get
181 11 -> liftM2 Call get get
180 11 -> liftM2 Call get get
182− 12 -> liftM3 TailCall get get get
181+ 12 -> liftM2 TailCall get get
183 13 -> liftM2 If get get
182 13 -> liftM2 If get get
184 14 -> liftM2 Let get get
183 14 -> liftM2 Let get get
185− 15 -> liftM3 Case get get get
184+ 15 -> liftM4 Case get get get get
186− 16 -> liftM2 Ctor get get
185+ 16 -> liftM2 Index get get
187− 17 -> liftM2 CtorAccess get get
188− 18 -> liftM Accessor get
186+ 17 -> liftM Accessor get
187+ 18 -> liftM2 Access get get
189− 19 -> liftM2 Access get get
188+ 19 -> liftM2 Update get get
190− 20 -> liftM2 Update get get
191− 21 -> liftM Record get
189+ 20 -> liftM Record get
192− 22 -> pure Unit
190+ 21 -> pure Unit
193− 23 -> liftM3 Tuple get get get
191+ 22 -> liftM3 Tuple get get get
194− 24 -> liftM Shader get
192+ 23 -> liftM Shader get
195 _ -> error "problem getting Opt.Expr binary"
193 _ -> error "problem getting Opt.Expr binary"
196
194
197
195
src/Optimize/Case.hs+11−25
@@ -20,13 +20,21 @@ import qualified Optimize.DecisionTree as DT
20-- OPTIMIZE A CASE EXPRESSION
20-- OPTIMIZE A CASE EXPRESSION
21
21
22
22
23−optimize :: N.Name -> [(Can.Pattern, Opt.Expr)] -> Opt.Expr
23+optimize :: N.Name -> N.Name -> [(Can.Pattern, Opt.Expr)] -> Opt.Expr
24−optimize exprName optBranches =
24+optimize temp root optBranches =
25 let
25 let
26 (patterns, indexedBranches) =
26 (patterns, indexedBranches) =
27 unzip (zipWith indexify [0..] optBranches)
27 unzip (zipWith indexify [0..] optBranches)
28+
29+ decider = treeToDecider (DT.compile patterns)
30+ targetCounts = countTargets decider
31+
32+ (choices, maybeJumps) =
33+ unzip (map (createChoices targetCounts) indexedBranches)
28 in
34 in
29− treeToExpr exprName (DT.compile patterns) indexedBranches
35+ Opt.Case temp root
36+ (insertChoices (Map.fromList choices) decider)
37+ (Maybe.catMaybes maybeJumps)
30
38
31
39
32indexify :: Int -> (a,b) -> ((a,Int), (Int,b))
40indexify :: Int -> (a,b) -> ((a,Int), (Int,b))
@@ -37,28 +45,6 @@ indexify index (pattern, branch) =
37
45
38
46
39
47
40−-- CONVERT A TREE TO AN EXPRESSION
41−
42−
43−treeToExpr :: N.Name -> DT.DecisionTree -> [(Int, Opt.Expr)] -> Opt.Expr
44−treeToExpr name decisionTree allJumps =
45− let
46− decider =
47− treeToDecider decisionTree
48−
49− targetCounts =
50− countTargets decider
51−
52− (choices, maybeJumps) =
53− unzip (map (createChoices targetCounts) allJumps)
54− in
55− Opt.Case
56− name
57− (insertChoices (Map.fromList choices) decider)
58− (Maybe.catMaybes maybeJumps)
59−
60−
61−
62-- TREE TO DECIDER
48-- TREE TO DECIDER
63--
49--
64-- Decision trees may have some redundancies, so we convert them to a Decider
50-- Decision trees may have some redundancies, so we convert them to a Decider
src/Optimize/DecisionTree.hs+20−19
@@ -21,7 +21,7 @@ as SML/NJ to get nice trees.
21-}
21-}
22
22
23import Control.Arrow (second)
23import Control.Arrow (second)
24−import Control.Monad (liftM, liftM2)
24+import Control.Monad (liftM, liftM2, liftM3)
25import Data.Binary
25import Data.Binary
26import qualified Data.List as List
26import qualified Data.List as List
27import qualified Data.Maybe as Maybe
27import qualified Data.Maybe as Maybe
@@ -29,6 +29,7 @@ import qualified Data.Set as Set
29import Data.Text (Text)
29import Data.Text (Text)
30
30
31import qualified AST.Canonical as Can
31import qualified AST.Canonical as Can
32+import qualified Data.Index as Index
32import qualified Elm.Name as N
33import qualified Elm.Name as N
33import qualified Reporting.Annotation as A
34import qualified Reporting.Annotation as A
34
35
@@ -70,7 +71,7 @@ data DecisionTree
70
71
71
72
72data Test
73data Test
73− = IsCtor Int N.Name
74+ = IsCtor Int N.Name Index.ZeroBased
74 | IsInt Int
75 | IsInt Int
75 | IsChr Text
76 | IsChr Text
76 | IsStr Text
77 | IsStr Text
@@ -162,7 +163,7 @@ toDecisionTree rawBranches =
162isComplete :: [Test] -> Bool
163isComplete :: [Test] -> Bool
163isComplete tests =
164isComplete tests =
164 case head tests of
165 case head tests of
165− IsCtor alts _ ->
166+ IsCtor alts _ _ ->
166 alts == length tests
167 alts == length tests
167
168
168 _ ->
169 _ ->
@@ -207,7 +208,7 @@ flatten pathPattern@(path, A.At region pattern) =
207 Can.PTuple a b (Just c) ->
208 Can.PTuple a b (Just c) ->
208 concatMap flatten (subPositions path [a,b,c])
209 concatMap flatten (subPositions path [a,b,c])
209
210
210− Can.PCtor _ _ _ (Can.CtorAlts numAlts _) _ args ->
211+ Can.PCtor _ _ _ (Can.CtorAlts numAlts _) _ _ args ->
211 if numAlts == 1 then
212 if numAlts == 1 then
212 concatMap flatten (subPositions path (map dearg args))
213 concatMap flatten (subPositions path (map dearg args))
213 else
214 else
@@ -304,8 +305,8 @@ testAtPath selectedPath (Branch _ pathPatterns) =
304
305
305 Just (A.At _ pattern) ->
306 Just (A.At _ pattern) ->
306 case pattern of
307 case pattern of
307− Can.PCtor _ _ _ (Can.CtorAlts numAlts _) name _ ->
308+ Can.PCtor _ _ _ (Can.CtorAlts numAlts _) name index _ ->
308− Just (IsCtor numAlts name)
309+ Just (IsCtor numAlts name index)
309
310
310 Can.PInt int ->
311 Can.PInt int ->
311 Just (IsInt int)
312 Just (IsInt int)
@@ -346,12 +347,12 @@ testAtPath selectedPath (Branch _ pathPatterns) =
346
347
347{-# NOINLINE nilTest #-}
348{-# NOINLINE nilTest #-}
348nilTest :: Test
349nilTest :: Test
349−nilTest = IsCtor 2 "[]"
350+nilTest = IsCtor 2 "[]" (Index.unsafe (-1))
350
351
351
352
352{-# NOINLINE consTest #-}
353{-# NOINLINE consTest #-}
353consTest :: Test
354consTest :: Test
354−consTest = IsCtor 2 "::"
355+consTest = IsCtor 2 "::" (Index.unsafe (-2))
355
356
356
357
357
358
@@ -370,27 +371,27 @@ toRelevantBranch test path branch@(Branch goal pathPatterns) =
370 case extract path pathPatterns of
371 case extract path pathPatterns of
371 Just (start, A.At region pattern, end) ->
372 Just (start, A.At region pattern, end) ->
372 case pattern of
373 case pattern of
373− Can.PCtor _ _ _ (Can.CtorAlts numAlts _) name args ->
374+ Can.PCtor _ _ _ (Can.CtorAlts numAlts _) name index args ->
374− if test == IsCtor numAlts name then
375+ if test == IsCtor numAlts name index then
375 Just (Branch goal (start ++ subPositions path (map dearg args) ++ end))
376 Just (Branch goal (start ++ subPositions path (map dearg args) ++ end))
376 else
377 else
377 Nothing
378 Nothing
378
379
379 Can.PList [] ->
380 Can.PList [] ->
380− if test == IsCtor 2 "[]" then
381+ if test == nilTest then
381 Just (Branch goal (start ++ end))
382 Just (Branch goal (start ++ end))
382 else
383 else
383 Nothing
384 Nothing
384
385
385 Can.PList (hd:tl) ->
386 Can.PList (hd:tl) ->
386− if test == IsCtor 2 "::" then
387+ if test == consTest then
387 let tl' = A.At region (Can.PList tl) in
388 let tl' = A.At region (Can.PList tl) in
388 Just (Branch goal (start ++ subPositions path [ hd, tl' ] ++ end))
389 Just (Branch goal (start ++ subPositions path [ hd, tl' ] ++ end))
389 else
390 else
390 Nothing
391 Nothing
391
392
392 Can.PCons hd tl ->
393 Can.PCons hd tl ->
393− if test == IsCtor 2 "::" then
394+ if test == consTest then
394 Just (Branch goal (start ++ subPositions path [hd,tl] ++ end))
395 Just (Branch goal (start ++ subPositions path [hd,tl] ++ end))
395 else
396 else
396 Nothing
397 Nothing
@@ -471,7 +472,7 @@ needsTests (A.At _ pattern) =
471 Can.PRecord _ ->
472 Can.PRecord _ ->
472 False
473 False
473
474
474− Can.PCtor _ _ _ _ _ _ ->
475+ Can.PCtor _ _ _ _ _ _ _ ->
475 True
476 True
476
477
477 Can.PList _ ->
478 Can.PList _ ->
@@ -573,15 +574,15 @@ smallBranchingFactor branches path =
573instance Binary Test where
574instance Binary Test where
574 put test =
575 put test =
575 case test of
576 case test of
576− IsCtor a b -> putWord8 0 >> put a >> put b
577+ IsCtor a b c -> putWord8 0 >> put a >> put b >> put c
577− IsChr a -> putWord8 1 >> put a
578+ IsChr a -> putWord8 1 >> put a
578− IsStr a -> putWord8 2 >> put a
579+ IsStr a -> putWord8 2 >> put a
579− IsInt a -> putWord8 3 >> put a
580+ IsInt a -> putWord8 3 >> put a
580
581
581 get =
582 get =
582 do word <- getWord8
583 do word <- getWord8
583 case word of
584 case word of
584− 0 -> liftM2 IsCtor get get
585+ 0 -> liftM3 IsCtor get get get
585 1 -> liftM IsChr get
586 1 -> liftM IsChr get
586 2 -> liftM IsStr get
587 2 -> liftM IsStr get
587 3 -> liftM IsInt get
588 3 -> liftM IsInt get
src/Optimize/Expression.hs+40−31
@@ -130,14 +130,14 @@ optimize cycle (A.At region expression) =
130 obranch <- optimize cycle branch
130 obranch <- optimize cycle branch
131 pure (pattern, foldr Opt.Let obranch defs)
131 pure (pattern, foldr Opt.Let obranch defs)
132 in
132 in
133+ do temp <- Names.generate
133− do oexpr <- optimize cycle expr
134+ oexpr <- optimize cycle expr
134 case oexpr of
135 case oexpr of
135 Opt.VarLocal root ->
136 Opt.VarLocal root ->
136− Case.optimize root <$> traverse (optimizeBranch root) branches
137+ Case.optimize temp root <$> traverse (optimizeBranch root) branches
137
138
138 _ ->
139 _ ->
139− do root <- Names.generate
140− Case.optimize root <$> traverse (optimizeBranch root) branches
140+ Case.optimize temp temp <$> traverse (optimizeBranch temp) branches
141
141
142 Can.Accessor field ->
142 Can.Accessor field ->
143 Names.registerField field (Opt.Accessor field)
143 Names.registerField field (Opt.Accessor field)
@@ -246,13 +246,13 @@ destructHelp root (A.At region pattern) revDefs =
246 let newRevDefs = Opt.Def name root : revDefs
246 let newRevDefs = Opt.Def name root : revDefs
247 case maybeC of
247 case maybeC of
248 Nothing ->
248 Nothing ->
249− destructHelp (Opt.CtorAccess tuple Index.second) b =<<
249+ destructHelp (Opt.Index tuple 1) b =<<
250− destructHelp (Opt.CtorAccess tuple Index.first) a newRevDefs
250+ destructHelp (Opt.Index tuple 0) a newRevDefs
251
251
252 Just c ->
252 Just c ->
253− destructHelp (Opt.CtorAccess tuple Index.third) c =<<
253+ destructHelp (Opt.Index tuple 2) c =<<
254− destructHelp (Opt.CtorAccess tuple Index.second) b =<<
254+ destructHelp (Opt.Index tuple 1) b =<<
255− destructHelp (Opt.CtorAccess tuple Index.first) a newRevDefs
255+ destructHelp (Opt.Index tuple 0) a newRevDefs
256
256
257 Can.PList [] ->
257 Can.PList [] ->
258 pure revDefs
258 pure revDefs
@@ -272,7 +272,7 @@ destructHelp root (A.At region pattern) revDefs =
272 Can.PInt _ ->
272 Can.PInt _ ->
273 pure revDefs
273 pure revDefs
274
274
275− Can.PCtor _ _ _ _ _ args ->
275+ Can.PCtor _ _ _ _ _ _ args ->
276 do name <- Names.generate
276 do name <- Names.generate
277 foldM
277 foldM
278 (destructCtorArg (Opt.VarLocal name))
278 (destructCtorArg (Opt.VarLocal name))
@@ -284,13 +284,13 @@ destructCons :: Opt.Expr -> Can.Pattern -> Can.Pattern -> [Opt.Def] -> Names.Tra
284destructCons root hd tl revDefs =
284destructCons root hd tl revDefs =
285 do name <- Names.generate
285 do name <- Names.generate
286 let list = Opt.VarLocal name
286 let list = Opt.VarLocal name
287− destructHelp (Opt.CtorAccess list Index.first) hd =<<
287+ destructHelp (Opt.Index list 0) hd =<<
288− destructHelp (Opt.CtorAccess list Index.second) tl (Opt.Def name root : revDefs)
288+ destructHelp (Opt.Index list 1) tl (Opt.Def name root : revDefs)
289
289
290
290
291destructCtorArg :: Opt.Expr -> [Opt.Def] -> Can.PatternCtorArg -> Names.Tracker [Opt.Def]
291destructCtorArg :: Opt.Expr -> [Opt.Def] -> Can.PatternCtorArg -> Names.Tracker [Opt.Def]
292destructCtorArg root revDefs (Can.PatternCtorArg index _ arg) =
292destructCtorArg root revDefs (Can.PatternCtorArg index _ arg) =
293− destructHelp (Opt.CtorAccess root index) arg revDefs
293+ destructHelp (Opt.Index root (Index.toZeroBased index)) arg revDefs
294
294
295
295
296
296
@@ -312,37 +312,46 @@ optimizePotentialTailCall cycle def =
312
312
313
313
314optimizeTail :: Cycle -> N.Name -> [N.Name] -> Can.Expr -> Names.Tracker Opt.Expr
314optimizeTail :: Cycle -> N.Name -> [N.Name] -> Can.Expr -> Names.Tracker Opt.Expr
315−optimizeTail cycle name argNames locExpr@(A.At _ expression) =
315+optimizeTail cycle rootName argNames locExpr@(A.At _ expression) =
316 case expression of
316 case expression of
317− Can.Call (A.At _ (Can.VarTopLevel _ funcName)) args ->
317+ Can.Call func@(A.At _ (Can.VarTopLevel _ name)) args ->
318− if funcName == name && length args == length argNames then
318+ do oargs <- traverse (optimize cycle) args
319+ if name == rootName
320+ then
321+ case Index.indexedZipWith (\_ a b -> (a,b)) argNames oargs of
322+ Index.LengthMatch pairs ->
319− Opt.TailCall name argNames <$> traverse (optimize cycle) args
323+ pure $ Opt.TailCall name pairs
324+
325+ Index.LengthMismatch _ _ ->
326+ do ofunc <- optimize cycle func
327+ pure $ Opt.Call ofunc oargs
320− else
328+ else
321− optimize cycle locExpr
329+ do ofunc <- optimize cycle func
330+ pure $ Opt.Call ofunc oargs
322
331
323 Can.If branches finally ->
332 Can.If branches finally ->
324 let
333 let
325 optimizeBranch (condition, branch) =
334 optimizeBranch (condition, branch) =
326 (,)
335 (,)
327 <$> optimize cycle condition
336 <$> optimize cycle condition
328− <*> optimizeTail cycle name argNames branch
337+ <*> optimizeTail cycle rootName argNames branch
329 in
338 in
330 Opt.If
339 Opt.If
331 <$> traverse optimizeBranch branches
340 <$> traverse optimizeBranch branches
332− <*> optimizeTail cycle name argNames finally
341+ <*> optimizeTail cycle rootName argNames finally
333
342
334 Can.Let def body ->
343 Can.Let def body ->
335− optimizeDef cycle def =<< optimizeTail cycle name argNames body
344+ optimizeDef cycle def =<< optimizeTail cycle rootName argNames body
336
345
337 Can.LetRec defs body ->
346 Can.LetRec defs body ->
338 case defs of
347 case defs of
339 [def] ->
348 [def] ->
340 Opt.Let
349 Opt.Let
341 <$> optimizePotentialTailCall cycle def
350 <$> optimizePotentialTailCall cycle def
342− <*> optimizeTail cycle name argNames body
351+ <*> optimizeTail cycle rootName argNames body
343
352
344 _ ->
353 _ ->
345− do obody <- optimizeTail cycle name argNames body
354+ do obody <- optimizeTail cycle rootName argNames body
346 foldM (\bod def -> optimizeDef cycle def bod) obody defs
355 foldM (\bod def -> optimizeDef cycle def bod) obody defs
347
356
348 Can.LetDestruct pattern expr body ->
357 Can.LetDestruct pattern expr body ->
@@ -356,17 +365,17 @@ optimizeTail cycle name argNames locExpr@(A.At _ expression) =
356 let
365 let
357 optimizeBranch root (Can.CaseBranch pattern branch) =
366 optimizeBranch root (Can.CaseBranch pattern branch) =
358 do defs <- destructHelp (Opt.VarLocal root) pattern []
367 do defs <- destructHelp (Opt.VarLocal root) pattern []
359− obranch <- optimizeTail cycle name argNames branch
368+ obranch <- optimizeTail cycle rootName argNames branch
360 pure (pattern, foldr Opt.Let obranch defs)
369 pure (pattern, foldr Opt.Let obranch defs)
361 in
370 in
371+ do temp <- Names.generate
362− do oexpr <- optimize cycle expr
372+ oexpr <- optimize cycle expr
363 case oexpr of
373 case oexpr of
364 Opt.VarLocal root ->
374 Opt.VarLocal root ->
365− Case.optimize root <$> traverse (optimizeBranch root) branches
375+ Case.optimize temp root <$> traverse (optimizeBranch root) branches
366
376
367 _ ->
377 _ ->
368− do root <- Names.generate
369− Case.optimize root <$> traverse (optimizeBranch root) branches
378+ Case.optimize temp temp <$> traverse (optimizeBranch temp) branches
370
379
371 _ ->
380 _ ->
372 optimize cycle locExpr
381 optimize cycle locExpr
@@ -387,7 +396,7 @@ toTailDef name argNames defss body =
387hasTailCall :: Opt.Expr -> Bool
396hasTailCall :: Opt.Expr -> Bool
388hasTailCall expression =
397hasTailCall expression =
389 case expression of
398 case expression of
390− Opt.TailCall _ _ _ ->
399+ Opt.TailCall _ _ ->
391 True
400 True
392
401
393 Opt.If branches finally ->
402 Opt.If branches finally ->
@@ -396,7 +405,7 @@ hasTailCall expression =
396 Opt.Let _ body ->
405 Opt.Let _ body ->
397 hasTailCall body
406 hasTailCall body
398
407
399− Opt.Case _ _ branches ->
408+ Opt.Case _ _ _ branches ->
400 any (hasTailCall . snd) branches
409 any (hasTailCall . snd) branches
401
410
402 _ ->
411 _ ->
src/Optimize/Module.hs+6−15
@@ -15,6 +15,7 @@ import qualified Data.Set as Set
15import qualified AST.Canonical as Can
15import qualified AST.Canonical as Can
16import qualified AST.Optimized as Opt
16import qualified AST.Optimized as Opt
17import qualified AST.Module.Name as ModuleName
17import qualified AST.Module.Name as ModuleName
18+import qualified Data.Index as Index
18import qualified Elm.Name as N
19import qualified Elm.Name as N
19import qualified Optimize.Expression as Expr
20import qualified Optimize.Expression as Expr
20import qualified Optimize.Names as Names
21import qualified Optimize.Names as Names
@@ -58,23 +59,13 @@ addUnions home unions (Graph fields nodes) =
58
59
59addUnion :: ModuleName.Canonical -> Can.Union -> Nodes -> Nodes
60addUnion :: ModuleName.Canonical -> Can.Union -> Nodes -> Nodes
60addUnion home (Can.Union _ ctors) nodes =
61addUnion home (Can.Union _ ctors) nodes =
61− foldr (addCtor home) nodes ctors
62+ Map.union nodes $
63+ Map.fromList (Index.indexedMap (ctorToNode home) ctors)
62
64
63
65
64−addCtor :: ModuleName.Canonical -> (N.Name, [t]) -> Nodes -> Nodes
66+ctorToNode :: ModuleName.Canonical -> Index.ZeroBased -> (N.Name, [t]) -> (Opt.Global, Opt.Node)
65−addCtor home (ctor, args) nodes =
67+ctorToNode home index (name, args) =
66− let
68+ ( Opt.Global home name, Opt.Ctor name index (length args) )
67− argNames =
68− map N.localFromInt [ 1 .. length args ]
69−
70− function =
71− Opt.Function argNames $
72− Opt.Ctor ctor (map Opt.VarLocal argNames)
73−
74− node =
75− Opt.Define function Set.empty Set.empty
76− in
77− Map.insert (Opt.Global home ctor) node nodes
78
69
79
70
80
71
src/Optimize/Port.hs+14−14
@@ -68,13 +68,13 @@ toEncoder tipe =
68 let
68 let
69 encodeField (name, fieldType) =
69 encodeField (name, fieldType) =
70 do encoder <- toEncoder fieldType
70 do encoder <- toEncoder fieldType
71− let value = Opt.Call encoder [Opt.Access (Opt.VarLocal "r") name]
71+ let value = Opt.Call encoder [Opt.Access (Opt.VarLocal N.dollar) name]
72 return $ Opt.Tuple (Opt.Str name) value Nothing
72 return $ Opt.Tuple (Opt.Str name) value Nothing
73 in
73 in
74 do object <- encode "object"
74 do object <- encode "object"
75 keyValuePairs <- traverse encodeField (Map.toList fields)
75 keyValuePairs <- traverse encodeField (Map.toList fields)
76 Names.registerFieldDict fields $
76 Names.registerFieldDict fields $
77− Opt.Function ["r"] (Opt.Call object [Opt.List keyValuePairs])
77+ Opt.Function [N.dollar] (Opt.Call object [Opt.List keyValuePairs])
78
78
79
79
80
80
@@ -86,12 +86,12 @@ encodeMaybe tipe =
86 do null <- encode "null"
86 do null <- encode "null"
87 encoder <- toEncoder tipe
87 encoder <- toEncoder tipe
88
88
89− let test = (DT.Empty, DT.IsCtor 2 "Nothing")
89+ let test = (DT.Empty, DT.IsCtor 2 "Just" Index.first)
90− let just = Opt.Call encoder [ Opt.CtorAccess (Opt.VarLocal "m") Index.first ]
90+ let just = Opt.Call encoder [ Opt.Index (Opt.VarLocal N.dollar) 0 ]
91 let leaf expr = Opt.Leaf (Opt.Inline expr)
91 let leaf expr = Opt.Leaf (Opt.Inline expr)
92
92
93− return $ Opt.Function ["m"] $
93+ return $ Opt.Function [N.dollar] $
94− Opt.Case "m" (Opt.Chain [test] (leaf null) (leaf just)) []
94+ Opt.Case N.dollar N.dollar (Opt.Chain [test] (leaf just) (leaf null)) []
95
95
96
96
97encodeList :: Can.Type -> Names.Tracker Opt.Expr
97encodeList :: Can.Type -> Names.Tracker Opt.Expr
@@ -100,8 +100,8 @@ encodeList tipe =
100 map_ <- Names.registerGlobal ModuleName.list "map"
100 map_ <- Names.registerGlobal ModuleName.list "map"
101 encoder <- toEncoder tipe
101 encoder <- toEncoder tipe
102 return $
102 return $
103− Opt.Function ["xs"] $
103+ Opt.Function [N.dollar] $
104− Opt.Call list [ Opt.Call map_ [ encoder, Opt.VarLocal "xs" ] ]
104+ Opt.Call list [ Opt.Call map_ [ encoder, Opt.VarLocal N.dollar ] ]
105
105
106
106
107encodeArray :: Can.Type -> Names.Tracker Opt.Expr
107encodeArray :: Can.Type -> Names.Tracker Opt.Expr
@@ -110,8 +110,8 @@ encodeArray tipe =
110 map_ <- Names.registerGlobal ModuleName.array "map"
110 map_ <- Names.registerGlobal ModuleName.array "map"
111 encoder <- toEncoder tipe
111 encoder <- toEncoder tipe
112 return $
112 return $
113− Opt.Function ["xs"] $
113+ Opt.Function [N.dollar] $
114− Opt.Call array [ Opt.Call map_ [ encoder, Opt.VarLocal "xs" ] ]
114+ Opt.Call array [ Opt.Call map_ [ encoder, Opt.VarLocal N.dollar ] ]
115
115
116
116
117encodeTuple :: Can.Type -> Can.Type -> Maybe Can.Type -> Names.Tracker Opt.Expr
117encodeTuple :: Can.Type -> Can.Type -> Maybe Can.Type -> Names.Tracker Opt.Expr
@@ -119,18 +119,18 @@ encodeTuple a b maybeC =
119 let
119 let
120 convert index tipe =
120 convert index tipe =
121 do encoder <- toEncoder tipe
121 do encoder <- toEncoder tipe
122− return $ Opt.Call encoder [ Opt.CtorAccess (Opt.VarLocal "t") index ]
122+ return $ Opt.Call encoder [ Opt.Index (Opt.VarLocal N.dollar) index ]
123 in
123 in
124− Opt.Function ["t"] <$> (
124+ Opt.Function [N.dollar] <$> (
125 Opt.Call
125 Opt.Call
126 <$> encode "list"
126 <$> encode "list"
127 <*>
127 <*>
128 case maybeC of
128 case maybeC of
129 Nothing ->
129 Nothing ->
130− Index.indexedTraverse convert [a,b]
130+ sequence [ convert 0 a, convert 1 b ]
131
131
132 Just c ->
132 Just c ->
133− Index.indexedTraverse convert [a,b,c]
133+ sequence [ convert 0 a, convert 1 b, convert 2 c ]
134 )
134 )
135
135
136
136