1{-# OPTIONS_GHC -Wall #-}
2module Canonicalize.Pattern
11import qualified AST.Canonical as Can
12import qualified AST.Source as Src
13import qualified Canonicalize.Environment as Env
14import qualified Canonicalize.Environment.Dups as Dups
15import qualified Data.Index as Index
16import qualified Reporting.Annotation as A
17import qualified Reporting.Error.Canonicalize as Error
18import qualified Reporting.Region as R
19import qualified Reporting.Result as Result
20import qualified Reporting.Warning as Warning
28 Result.Result i Warning.Warning Error.Error
35verify :: Error.DuplicatePatternContext -> Result Bindings a -> Result () (a, Can.Destructors)
36verify context (Result.Result bindings warnings answer) =
39 do let toError name () () = Error.DuplicatePattern context name
40 destructors <- Dups.detect toError bindings
41 Result.Result () warnings $ Result.Ok (value, destructors)
44 Result.Result () warnings (Result.Err err)
51canonicalizeArg :: Env.Env -> Index.ZeroBased -> Src.Pattern -> Result Bindings Can.Arg
52canonicalizeArg env index pattern =
53 Can.Arg index <$> canonicalize env index pattern
61 Dups.Dict () (A.Located Can.Destructor)
64canonicalize :: Env.Env -> Index.ZeroBased -> Src.Pattern -> Result Bindings Can.Pattern
65canonicalize env index pattern =
66 process env (Can.DRoot index) pattern
69process :: Env.Env -> Can.Destructor -> Src.Pattern -> Result Bindings Can.Pattern
70process env destructor (A.A region pattern) =
74 Result.ok Can.PAnything
78 (Dups.one name region () (A.A region destructor))
83 addField (A.A reg name) dict =
84 Dups.insert name reg () (A.A reg (Can.DField name destructor)) dict
87 (foldr addField Dups.none fields)
88 (Can.PRecord (map A.drop fields))
95 <$> process env (Can.DIndex Index.first destructor) a
96 <*> process env (Can.DIndex Index.second destructor) b
97 <*> processTuple region env destructor cs
99 Src.PCtor nameRegion maybePrefix name patterns ->
101 toCanonicalArg index ptrn tipe =
102 Can.PatternCtorArg index tipe
103 <$> process env (Can.DIndex index destructor) ptrn
105 do (Env.Pattern home tipe vars args) <- Env.findPattern nameRegion env maybePrefix name
106 verifiedList <- Index.indexedZipWithA toCanonicalArg patterns args
108 Index.LengthMatch cargs ->
109 Result.ok $ Can.PCtor home tipe vars name cargs
111 Index.LengthMismatch actualLength expectedLength ->
112 Result.throw region (error "TODO" actualLength expectedLength)
114 Src.PList patterns ->
115 Can.PList <$> processList env destructor patterns
117 Src.PCons first rest ->
119 <$> process env (Can.DIndex Index.first destructor) first
120 <*> process env (Can.DIndex Index.second destructor) rest
122 Src.PAlias ptrn (A.A reg name) ->
123 do cpattern <- process env destructor ptrn
125 (Dups.one name reg () (A.A reg destructor))
126 (Can.PAlias cpattern name)
129 Result.ok (Can.PChr chr)
132 Result.ok (Can.PStr str)
135 Result.ok (Can.PInt int)
138processTuple :: R.Region -> Env.Env -> Can.Destructor -> [Src.Pattern] -> Result Bindings (Maybe Can.Pattern)
139processTuple tupleRegion env destructor extras =
145 Just <$> process env (Can.DIndex Index.third destructor) three
148 let (A.A r1 _, A.A r2 _) = (head others, last others) in
149 Result.throw tupleRegion (Error.TupleLargerThanThree (R.merge r1 r2))
152processList :: Env.Env -> Can.Destructor -> [Src.Pattern] -> Result Bindings [Can.Pattern]
153processList env destructor list =
158 pattern : otherPatterns ->
160 <$> process env (Can.DIndex Index.first destructor) pattern
161 <*> processList env (Can.DIndex Index.second destructor) otherPatterns
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