@@ -2,6 +2,7 @@
22module Canonicalize.Expression
33 ( canonicalize
44 , removeLocals
5+ , gatherTypedArgs
56 )
67 where
78
@@ -10,9 +11,10 @@ import qualified Data.Graph as Graph
1011import qualified Data.Map.Strict as Map
1112import qualified Data.Set as Set
1213
13−import qualified AST.Utils.Binop as Binop
1414import qualified AST.Canonical as Can
1515import qualified AST.Source as Src
16+import qualified AST.Utils.Binop as Binop
17+import qualified AST.Utils.Type as Type
1618import qualified AST.Valid as Valid
1719import qualified Canonicalize.Environment as Env
1820import qualified Canonicalize.Environment.Dups as Dups
@@ -76,12 +78,14 @@ canonicalize env (A.A region expression) =
7678 Valid.Binops ops final ->
7779 A.drop <$> canonicalizeBinops region env ops final
7880
79− Valid.Lambda args body ->
81+ Valid.Lambda srcArgs body ->
8082 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
8286 newEnv <- Env.addLocals destructors env
8387 removeLocals Warning.Pattern destructors $
84− Can.Lambda cargs <$> canonicalize newEnv body
88+ Can.Lambda args destructors <$> canonicalize newEnv body
8589
8690 Valid.Call func args ->
8791 Can.Call
@@ -99,7 +103,7 @@ canonicalize env (A.A region expression) =
99103 Valid.Case expr branches ->
100104 Can.Case
101105 <$> canonicalize env expr
102− <*> Index.indexedTraverse (canonicalizeCaseBranch env) branches
106+ <*> traverse (canonicalizeCaseBranch env) branches
103107
104108 Valid.Accessor field ->
105109 Result.ok $ Can.Accessor field
@@ -165,13 +169,15 @@ canonicalizeIfBranch env (condition, branch) =
165169-- CANONICALIZE CASE BRANCH
166170
167171
168−canonicalizeCaseBranch :: Env.Env -> Index.ZeroBased -> (Src.Pattern, Valid.Expr) -> Result FreeLocals Can.CaseBranch
169−canonicalizeCaseBranch env index (pattern, expr) =
172+canonicalizeCaseBranch :: Env.Env -> (Src.Pattern, Valid.Expr) -> Result FreeLocals Can.CaseBranch
173+canonicalizeCaseBranch env (pattern, expr) =
170174 addLocals $
171− do (cpattern, destructors) <- Pattern.canonicalize env index pattern
175+ do (cpattern, destructors) <-
176+ Pattern.verify Error.DPCaseBranch $
177+ Pattern.canonicalize env Index.first pattern
172178 newEnv <- Env.addLocals destructors env
173179 removeLocals Warning.Pattern destructors $
174− Can.CaseBranch index cpattern destructors <$> canonicalize newEnv expr
180+ Can.CaseBranch cpattern destructors <$> canonicalize newEnv expr
175181
176182
177183
@@ -262,15 +268,18 @@ toBinop (Env.Binop op home name annotation _ _) left right =
262268
263269
264270canonicalizeLet :: R.Region -> Env.Env -> [Valid.Def] -> Valid.Expr -> Result FreeLocals Can.Expr
265−canonicalizeLet region env defs body =
271+canonicalizeLet letRegion env defs body =
266272 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)
268277 newEnv <- Env.addLocals boundNames env
269278 let defKeys = Map.map A.drop boundNames
270− nodes <- Result.untracked $ traverse (bindingToNode defKeys newEnv) bindings
279+ nodes <- traverse (defToNode defKeys newEnv) keyedDefs
271280 removeLocals Warning.Binding boundNames $
272281 do cbody <- canonicalize env body
273− detectCycles region (Graph.stronglyConnComp nodes) cbody
282+ detectCycles letRegion (Graph.stronglyConnComp nodes) cbody
274283
275284
276285addLocals :: Result () (expr, FreeLocals) -> Result FreeLocals expr
@@ -312,35 +321,114 @@ toUnusedWarning unused (name, A.A region _) =
312321
313322
314323
324+-- ADD BINDINGS
325+
326+
327+type KeyBag =
328+ Bag.Bag ( N.Name, [Dups.Info () (A.Located Int)] )
329+
330+
331+addBindings :: (Valid.Def, Int) -> KeyBag -> KeyBag
332+addBindings (def, key) bag =
333+ case def of
334+ Valid.Define defRegion (A.A region name) _ _ _ ->
335+ Bag.insert (Dups.info name region () (A.A defRegion key)) bag
336+
337+ Valid.Destruct defRegion pattern _ ->
338+ addBindingsHelp (A.A defRegion key) pattern bag
339+
340+
341+addBindingsHelp :: A.Located Int -> Src.Pattern -> KeyBag -> KeyBag
342+addBindingsHelp key (A.A region pattern) bag =
343+ case pattern of
344+ Src.PAnything ->
345+ bag
346+
347+ Src.PVar name ->
348+ Bag.insert (Dups.info name region () key) bag
349+
350+ Src.PRecord fields ->
351+ let
352+ fieldToInfo (A.A fieldRegion name) =
353+ Dups.info name fieldRegion () key
354+ in
355+ foldr (\f b -> Bag.insert (fieldToInfo f) b) bag fields
356+
357+ Src.PUnit ->
358+ bag
359+
360+ Src.PTuple a b cs ->
361+ foldr (addBindingsHelp key) bag (a:b:cs)
362+
363+ Src.PCtor _ _ _ patterns ->
364+ foldr (addBindingsHelp key) bag patterns
365+
366+ Src.PList patterns ->
367+ foldr (addBindingsHelp key) bag patterns
368+
369+ Src.PCons first rest ->
370+ addBindingsHelp key rest (addBindingsHelp key first bag)
371+
372+ Src.PAlias ptrn (A.A reg name) ->
373+ addBindingsHelp key ptrn (Bag.insert (Dups.info name reg () key) bag)
374+
375+ Src.PChr _ ->
376+ bag
377+
378+ Src.PStr _ ->
379+ bag
380+
381+ Src.PInt _ ->
382+ bag
383+
384+
385+
315386-- BUILD BINDINGS GRAPH
316387
317388
389+data Node = Node Binding FreeLocals
390+
391+
318392data Binding
319393 = Define R.Region Can.Def
320394 | Destruct R.Region Can.Pattern Can.Destructors Can.Expr
321395
322396
323−data Node = Node Binding FreeLocals
324−
325−
326−bindingToNode :: Map.Map N.Name Int -> Env.Env -> Pattern.Binding -> Result () (Node, Int, [Int])
327−bindingToNode defKeys env binding =
328− case binding of
329− Pattern.Define region index name args body maybeType ->
330− do cargs@(Can.Args _ destructors) <- Pattern.canonicalizeArgs env args
331− maybeAnnotation <- traverse (Type.toAnnotation env) maybeType
397+defToNode :: Map.Map N.Name Int -> Env.Env -> (Valid.Def, Int) -> Result () (Node, Int, [Int])
398+defToNode defKeys env (def, key) =
399+ case def of
400+ Valid.Define region aname@(A.A _ name) srcArgs body Nothing ->
401+ do (args, destructors) <-
402+ Pattern.verify (Error.DPFuncArgs name) $
403+ Index.indexedTraverse (Pattern.canonicalizeArg env) srcArgs
332404 newEnv <- Env.addLocals destructors env
333− toNode defKeys destructors index $
405+ toNode defKeys key destructors $
334406 do cbody <- canonicalize newEnv body
335− return $ Define region $ Can.Def name cargs cbody maybeAnnotation
336−
337− Pattern.Destruct region index pattern destructors body ->
338− toNode defKeys Map.empty index $
339− Destruct region pattern destructors <$> canonicalize env body
407+ return $ Define region $
408+ Can.Def aname args destructors cbody
409+
410+ Valid.Destruct region pattern body ->
411+ do (cpattern, destructors) <-
412+ Pattern.verify Error.DPDestruct $
413+ Pattern.canonicalize env Index.first pattern
414+
415+ toNode defKeys key destructors $
416+ Destruct region cpattern destructors <$> canonicalize env body
417+
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
340428
341429
342−toNode :: Map.Map N.Name Int -> Map.Map N.Name a -> Int -> Result FreeLocals Binding -> Result () (Node, Int, [Int])
343−toNode defKeys args index (Result.Result freeLocals warnings answer) =
430+toNode :: Map.Map N.Name Int -> Int -> Map.Map N.Name a -> Result FreeLocals Binding -> Result () (Node, Int, [Int])
431+toNode defKeys key args (Result.Result freeLocals warnings answer) =
344432 Result.Result () warnings $
345433 case answer of
346434 Result.Err err ->
@@ -353,70 +441,91 @@ toNode defKeys args index (Result.Result freeLocals warnings answer) =
353441 in
354442 Result.Ok
355443 ( Node binding actuallyFreeLocals
356− , index
444+ , key
357445 , Map.elems locallyDefinedLocals
358446 )
359447
360448
361449
450+-- GATHER TYPED ARGS
451+
452+
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 =
455+ case srcArgs of
456+ [] ->
457+ return (reverse revTypedArgs, tipe)
458+
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
466+
467+ _ ->
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)
471+
472+
473+
362474-- DETECT CYCLES
363475
364476
365477detectCycles :: R.Region -> [Graph.SCC Node] -> Can.Expr -> Result FreeLocals Can.Expr
366−detectCycles region sccs body =
478+detectCycles letRegion sccs body =
367479 case sccs of
368480 [] ->
369481 Result.ok body
370482
371483 scc : subSccs ->
372− A.A region <$>
484+ A.A letRegion <$>
373485 case scc of
374486 Graph.AcyclicSCC (Node binding freeLocals) ->
375487 case binding of
376488 Define _ def ->
377489 Result.accumulate freeLocals (Can.Let def)
378− <*> detectCycles region subSccs body
490+ <*> detectCycles letRegion subSccs body
379491
380492 Destruct _ pattern destructors expr ->
381493 Result.accumulate freeLocals (Can.LetDestruct pattern destructors expr)
382− <*> detectCycles region subSccs body
494+ <*> detectCycles letRegion subSccs body
383495
384496 Graph.CyclicSCC nodes ->
385− case unzip <$> traverse requireDefine nodes of
497+ case unzip <$> traverse requireFunction nodes of
386498 Nothing ->
387− Result.throw region (Error.RecursiveLet (map toCycleNodes nodes))
499+ Result.throw letRegion (Error.RecursiveLet (map toCycleNodes nodes))
388500
389501 Just (defs, freeLocals) ->
390502 Result.accumulate (Set.unions freeLocals) (Can.LetRec defs)
391− <*> detectCycles region subSccs body
392−
503+ <*> detectCycles letRegion subSccs body
393504
394505
395−requireDefine :: Node -> Maybe (Can.Def, FreeLocals)
396−requireDefine (Node binding freeLocals) =
506+requireFunction :: Node -> Maybe (Can.Def, FreeLocals)
507+requireFunction (Node binding freeLocals) =
397508 case binding of
398− Define _ def@(Can.Def _ (Can.Args args _) _ _) ->
399− case args of
400− [] ->
401− Nothing
509+ Define _ def@(Can.Def _ (_:_) _ _) ->
510+ Just (def, freeLocals)
402511
403− _ ->
404− Just (def, freeLocals)
512+ Define _ def@(Can.TypedDef _ _ (_:_) _ _ _) ->
513+ Just (def, freeLocals)
405514
406− Destruct _ _ _ _ ->
515+ _ ->
407516 Nothing
408517
409518
410519toCycleNodes :: Node -> Error.CycleNode
411520toCycleNodes (Node binding _) =
412521 case binding of
413− Define _ (Can.Def name (Can.Args args _) _ _) ->
414− case args of
415− [] ->
416− Error.CycleValue name
522+ Define _ def ->
523+ case def of
524+ Can.Def name args _ _ ->
525+ if null args then Error.CycleValue name else Error.CycleFunc name
417526
418− _ ->
419− Error.CycleFunc name
527+ Can.TypedDef name _ args _ _ _ ->
528+ if null args then Error.CycleValue name else Error.CycleFunc name
420529
421530 Destruct _ pattern _ _ ->
422531 Error.CyclePattern pattern