@@ -2,6 +2,7 @@
2module Canonicalize.Expression
2module Canonicalize.Expression
3 ( canonicalize
3 ( canonicalize
4 , removeLocals
4 , removeLocals
@@ -10,9 +11,10 @@ import qualified Data.Graph as Graph
10import qualified Data.Map.Strict as Map
11import qualified Data.Map.Strict as Map
11import qualified Data.Set as Set
12import qualified Data.Set as Set
13−import qualified AST.Utils.Binop as Binop
14import qualified AST.Canonical as Can
14import qualified AST.Canonical as Can
15import qualified AST.Source as Src
15import qualified AST.Source as Src
16+import qualified AST.Utils.Binop as Binop
17+import qualified AST.Utils.Type as Type
16import qualified AST.Valid as Valid
18import qualified AST.Valid as Valid
17import qualified Canonicalize.Environment as Env
19import qualified Canonicalize.Environment as Env
18import qualified Canonicalize.Environment.Dups as Dups
20import qualified Canonicalize.Environment.Dups as Dups
@@ -76,12 +78,14 @@ canonicalize env (A.A region expression) =
76 Valid.Binops ops final ->
78 Valid.Binops ops final ->
77 A.drop <$> canonicalizeBinops region env ops final
79 A.drop <$> canonicalizeBinops region env ops final
79− Valid.Lambda args body ->
81+ Valid.Lambda srcArgs body ->
80 addLocals $
82 addLocals $
81− do cargs@(Can.Args _ destructors) <- Pattern.canonicalizeArgs env args
83+ do (args, destructors) <-
84+ Pattern.verify Error.DPLambdaArgs $
85+ Index.indexedTraverse (Pattern.canonicalizeArg env) srcArgs
82 newEnv <- Env.addLocals destructors env
86 newEnv <- Env.addLocals destructors env
83 removeLocals Warning.Pattern destructors $
87 removeLocals Warning.Pattern destructors $
84− Can.Lambda cargs <$> canonicalize newEnv body
88+ Can.Lambda args destructors <$> canonicalize newEnv body
86 Valid.Call func args ->
90 Valid.Call func args ->
@@ -99,7 +103,7 @@ canonicalize env (A.A region expression) =
99 Valid.Case expr branches ->
103 Valid.Case expr branches ->
101 <$> canonicalize env expr
105 <$> canonicalize env expr
102− <*> Index.indexedTraverse (canonicalizeCaseBranch env) branches
106+ <*> traverse (canonicalizeCaseBranch env) branches
104 Valid.Accessor field ->
108 Valid.Accessor field ->
105 Result.ok $ Can.Accessor field
109 Result.ok $ Can.Accessor field
@@ -165,13 +169,15 @@ canonicalizeIfBranch env (condition, branch) =
165-- CANONICALIZE CASE BRANCH
169-- CANONICALIZE CASE BRANCH
168−canonicalizeCaseBranch :: Env.Env -> Index.ZeroBased -> (Src.Pattern, Valid.Expr) -> Result FreeLocals Can.CaseBranch
172+canonicalizeCaseBranch :: Env.Env -> (Src.Pattern, Valid.Expr) -> Result FreeLocals Can.CaseBranch
169−canonicalizeCaseBranch env index (pattern, expr) =
173+canonicalizeCaseBranch env (pattern, expr) =
170 addLocals $
174 addLocals $
175+ do (cpattern, destructors) <-
176+ Pattern.verify Error.DPCaseBranch $
171− do (cpattern, destructors) <- Pattern.canonicalize env index pattern
177+ Pattern.canonicalize env Index.first pattern
172 newEnv <- Env.addLocals destructors env
178 newEnv <- Env.addLocals destructors env
173 removeLocals Warning.Pattern destructors $
179 removeLocals Warning.Pattern destructors $
174− Can.CaseBranch index cpattern destructors <$> canonicalize newEnv expr
180+ Can.CaseBranch cpattern destructors <$> canonicalize newEnv expr
@@ -262,15 +268,18 @@ toBinop (Env.Binop op home name annotation _ _) left right =
264canonicalizeLet :: R.Region -> Env.Env -> [Valid.Def] -> Valid.Expr -> Result FreeLocals Can.Expr
270canonicalizeLet :: R.Region -> Env.Env -> [Valid.Def] -> Valid.Expr -> Result FreeLocals Can.Expr
265−canonicalizeLet region env defs body =
271+canonicalizeLet letRegion env defs body =
266 addLocals $
272 addLocals $
267− do (bindings, boundNames) <- Pattern.canonicalizeBindings env defs
273+ do let keyedDefs = zip defs [ 0 .. length defs ]
274+ let toError name () () = Error.DuplicatePattern Error.DPLetBinding name
275+ let namesBag = foldr addBindings Bag.empty keyedDefs
276+ boundNames <- Dups.detect toError (Bag.toList namesBag)
268 newEnv <- Env.addLocals boundNames env
277 newEnv <- Env.addLocals boundNames env
269 let defKeys = Map.map A.drop boundNames
278 let defKeys = Map.map A.drop boundNames
270− nodes <- Result.untracked $ traverse (bindingToNode defKeys newEnv) bindings
279+ nodes <- traverse (defToNode defKeys newEnv) keyedDefs
271 removeLocals Warning.Binding boundNames $
280 removeLocals Warning.Binding boundNames $
272 do cbody <- canonicalize env body
281 do cbody <- canonicalize env body
273− detectCycles region (Graph.stronglyConnComp nodes) cbody
282+ detectCycles letRegion (Graph.stronglyConnComp nodes) cbody
276addLocals :: Result () (expr, FreeLocals) -> Result FreeLocals expr
285addLocals :: Result () (expr, FreeLocals) -> Result FreeLocals expr
@@ -312,35 +321,114 @@ toUnusedWarning unused (name, A.A region _) =
328+ Bag.Bag ( N.Name, [Dups.Info () (A.Located Int)] )
331+addBindings :: (Valid.Def, Int) -> KeyBag -> KeyBag
332+addBindings (def, key) bag =
334+ Valid.Define defRegion (A.A region name) _ _ _ ->
335+ Bag.insert (Dups.info name region () (A.A defRegion key)) bag
337+ Valid.Destruct defRegion pattern _ ->
338+ addBindingsHelp (A.A defRegion key) pattern bag
341+addBindingsHelp :: A.Located Int -> Src.Pattern -> KeyBag -> KeyBag
342+addBindingsHelp key (A.A region pattern) bag =
348+ Bag.insert (Dups.info name region () key) bag
350+ Src.PRecord fields ->
352+ fieldToInfo (A.A fieldRegion name) =
353+ Dups.info name fieldRegion () key
355+ foldr (\f b -> Bag.insert (fieldToInfo f) b) bag fields
360+ Src.PTuple a b cs ->
361+ foldr (addBindingsHelp key) bag (a:b:cs)
363+ Src.PCtor _ _ _ patterns ->
364+ foldr (addBindingsHelp key) bag patterns
366+ Src.PList patterns ->
367+ foldr (addBindingsHelp key) bag patterns
369+ Src.PCons first rest ->
370+ addBindingsHelp key rest (addBindingsHelp key first bag)
372+ Src.PAlias ptrn (A.A reg name) ->
373+ addBindingsHelp key ptrn (Bag.insert (Dups.info name reg () key) bag)
315-- BUILD BINDINGS GRAPH
386-- BUILD BINDINGS GRAPH
389+data Node = Node Binding FreeLocals
318data Binding
392data Binding
319 = Define R.Region Can.Def
393 = Define R.Region Can.Def
320 | Destruct R.Region Can.Pattern Can.Destructors Can.Expr
394 | Destruct R.Region Can.Pattern Can.Destructors Can.Expr
323−data Node = Node Binding FreeLocals
326−bindingToNode :: Map.Map N.Name Int -> Env.Env -> Pattern.Binding -> Result () (Node, Int, [Int])
397+defToNode :: Map.Map N.Name Int -> Env.Env -> (Valid.Def, Int) -> Result () (Node, Int, [Int])
327−bindingToNode defKeys env binding =
398+defToNode defKeys env (def, key) =
328− case binding of
399+ case def of
329− Pattern.Define region index name args body maybeType ->
400+ Valid.Define region aname@(A.A _ name) srcArgs body Nothing ->
330− do cargs@(Can.Args _ destructors) <- Pattern.canonicalizeArgs env args
401+ do (args, destructors) <-
331− maybeAnnotation <- traverse (Type.toAnnotation env) maybeType
402+ Pattern.verify (Error.DPFuncArgs name) $
403+ Index.indexedTraverse (Pattern.canonicalizeArg env) srcArgs
332 newEnv <- Env.addLocals destructors env
404 newEnv <- Env.addLocals destructors env
333− toNode defKeys destructors index $
405+ toNode defKeys key destructors $
334 do cbody <- canonicalize newEnv body
406 do cbody <- canonicalize newEnv body
335− return $ Define region $ Can.Def name cargs cbody maybeAnnotation
407+ return $ Define region $
336−
408+ Can.Def aname args destructors cbody
337− Pattern.Destruct region index pattern destructors body ->
410+ Valid.Destruct region pattern body ->
411+ do (cpattern, destructors) <-
412+ Pattern.verify Error.DPDestruct $
413+ Pattern.canonicalize env Index.first pattern
338− toNode defKeys Map.empty index $
415+ toNode defKeys key destructors $
339− Destruct region pattern destructors <$> canonicalize env body
416+ Destruct region cpattern destructors <$> canonicalize env body
418+ Valid.Define region aname@(A.A _ name) srcArgs body (Just tipe) ->
419+ do (Can.Forall freeVars ctipe) <- Type.toAnnotation env tipe
420+ ((args, resultType), destructors) <-
421+ Pattern.verify (Error.DPFuncArgs name) $
422+ gatherTypedArgs env name srcArgs ctipe Index.first []
423+ newEnv <- Env.addLocals destructors env
424+ toNode defKeys key destructors $
425+ do cbody <- canonicalize newEnv body
426+ return $ Define region $
427+ Can.TypedDef aname freeVars args destructors cbody resultType
342−toNode :: Map.Map N.Name Int -> Map.Map N.Name a -> Int -> Result FreeLocals Binding -> Result () (Node, Int, [Int])
430+toNode :: Map.Map N.Name Int -> Int -> Map.Map N.Name a -> Result FreeLocals Binding -> Result () (Node, Int, [Int])
343−toNode defKeys args index (Result.Result freeLocals warnings answer) =
431+toNode defKeys key args (Result.Result freeLocals warnings answer) =
344 Result.Result () warnings $
432 Result.Result () warnings $
345 case answer of
433 case answer of
346 Result.Err err ->
434 Result.Err err ->
@@ -353,70 +441,91 @@ toNode defKeys args index (Result.Result freeLocals warnings answer) =
354 Result.Ok
442 Result.Ok
355 ( Node binding actuallyFreeLocals
443 ( Node binding actuallyFreeLocals
357 , Map.elems locallyDefinedLocals
445 , Map.elems locallyDefinedLocals
453+gatherTypedArgs :: Env.Env -> N.Name -> [Src.Pattern] -> Can.Type -> Index.ZeroBased -> [Can.TypedArg] -> Result Pattern.Bag ([Can.TypedArg], Can.Type)
454+gatherTypedArgs env name srcArgs tipe index revTypedArgs =
457+ return (reverse revTypedArgs, tipe)
459+ srcArg : otherSrcArgs ->
460+ case Type.iteratedDealias tipe of
461+ Can.TLambda argType resultType ->
462+ do typedArg <- Can.TypedArg index argType
463+ <$> Pattern.canonicalize env index srcArg
464+ gatherTypedArgs env name otherSrcArgs resultType (Index.next index) $
465+ typedArg : revTypedArgs
468+ let (A.A start _, A.A end _) = (head srcArgs, last srcArgs) in
469+ Result.throw (R.merge start end) $
470+ Error.AnnotationTooShort name index (length srcArgs)
362-- DETECT CYCLES
474-- DETECT CYCLES
365detectCycles :: R.Region -> [Graph.SCC Node] -> Can.Expr -> Result FreeLocals Can.Expr
477detectCycles :: R.Region -> [Graph.SCC Node] -> Can.Expr -> Result FreeLocals Can.Expr
366−detectCycles region sccs body =
478+detectCycles letRegion sccs body =
367 case sccs of
479 case sccs of
369 Result.ok body
481 Result.ok body
371 scc : subSccs ->
483 scc : subSccs ->
372− A.A region <$>
484+ A.A letRegion <$>
373 case scc of
485 case scc of
374 Graph.AcyclicSCC (Node binding freeLocals) ->
486 Graph.AcyclicSCC (Node binding freeLocals) ->
375 case binding of
487 case binding of
376 Define _ def ->
488 Define _ def ->
377 Result.accumulate freeLocals (Can.Let def)
489 Result.accumulate freeLocals (Can.Let def)
378− <*> detectCycles region subSccs body
490+ <*> detectCycles letRegion subSccs body
380 Destruct _ pattern destructors expr ->
492 Destruct _ pattern destructors expr ->
381 Result.accumulate freeLocals (Can.LetDestruct pattern destructors expr)
493 Result.accumulate freeLocals (Can.LetDestruct pattern destructors expr)
382− <*> detectCycles region subSccs body
494+ <*> detectCycles letRegion subSccs body
384 Graph.CyclicSCC nodes ->
496 Graph.CyclicSCC nodes ->
385− case unzip <$> traverse requireDefine nodes of
497+ case unzip <$> traverse requireFunction nodes of
386 Nothing ->
498 Nothing ->
387− Result.throw region (Error.RecursiveLet (map toCycleNodes nodes))
499+ Result.throw letRegion (Error.RecursiveLet (map toCycleNodes nodes))
389 Just (defs, freeLocals) ->
501 Just (defs, freeLocals) ->
390 Result.accumulate (Set.unions freeLocals) (Can.LetRec defs)
502 Result.accumulate (Set.unions freeLocals) (Can.LetRec defs)
391− <*> detectCycles region subSccs body
503+ <*> detectCycles letRegion subSccs body
395−requireDefine :: Node -> Maybe (Can.Def, FreeLocals)
506+requireFunction :: Node -> Maybe (Can.Def, FreeLocals)
396−requireDefine (Node binding freeLocals) =
507+requireFunction (Node binding freeLocals) =
397 case binding of
508 case binding of
398− Define _ def@(Can.Def _ (Can.Args args _) _ _) ->
509+ Define _ def@(Can.Def _ (_:_) _ _) ->
399− case args of
510+ Just (def, freeLocals)
403− _ ->
512+ Define _ def@(Can.TypedDef _ _ (_:_) _ _ _) ->
404− Just (def, freeLocals)
513+ Just (def, freeLocals)
406− Destruct _ _ _ _ ->
515+ _ ->
410toCycleNodes :: Node -> Error.CycleNode
519toCycleNodes :: Node -> Error.CycleNode
411toCycleNodes (Node binding _) =
520toCycleNodes (Node binding _) =
412 case binding of
521 case binding of
413− Define _ (Can.Def name (Can.Args args _) _ _) ->
522+ Define _ def ->
414− case args of
523+ case def of
415− [] ->
524+ Can.Def name args _ _ ->
416− Error.CycleValue name
525+ if null args then Error.CycleValue name else Error.CycleFunc name
418− _ ->
527+ Can.TypedDef name _ args _ _ _ ->
419− Error.CycleFunc name
528+ if null args then Error.CycleValue name else Error.CycleFunc name
421 Destruct _ pattern _ _ ->
530 Destruct _ pattern _ _ ->
422 Error.CyclePattern pattern
531 Error.CyclePattern pattern