on master help sign in
Begin supporting "define" in Parse and Validate phases

The main addition here is figuring out how to update Validate to share code a bit better now that 3 different things need to collapse annotations and definitions. I think the raw materials are there to handle “foreign effect modules” but right now that would not go well.

commit455dcb20f3f85e7d2a10c5caf29878443cc95d29 authorEvan Czaplicki <info@elm-lang.org> dateWed 3 Feb 2016, 16:39 (11 years ago) parent3bd0d85
12 files changed+636−325
src/AST/Expression/Source.hs+6 src/AST/Expression/Valid.hs+9 src/AST/Module.hs+111−83 src/Elm/Utils.hs+2−3 src/Optimize.hs+24−22 src/Parse/Declaration.hs+62−16 src/Parse/Expression.hs+39−17 src/Parse/Helpers.hs+3−3 src/Parse/Module.hs+10−9 src/Parse/Parse.hs+62−32 src/Reporting/Error/Syntax.hs+55−28 src/Validate.hs+253−112
src/AST/Expression/Source.hs+6
@@ -29,3 +29,9 @@ data Def'
2929 = Definition Pattern.Raw Expr
3030 | Annotation String Type.Raw
3131
32+
33+data Effect
34+ = Def Pattern.Raw Expr
35+ | Type String Type.Raw
36+ | With String Expr
37+
src/AST/Expression/Valid.hs+9
@@ -23,3 +23,12 @@ type Expr' =
2323data Def
2424 = Definition Pattern.Raw Expr (Maybe Type.Raw)
2525
26+
27+data Effect
28+ = Def Pattern.Raw Expr (Maybe Type.Raw)
29+
30+
31+data Foreign
32+ = Type String Type.Raw
33+ | With String Expr
34+
src/AST/Module.hs+111−83
@@ -1,13 +1,20 @@
11module AST.Module
2− ( Interfaces
3− , Types, Aliases, Unions
4− , UnionInfo, CanonicalUnion
5− , SourceModule, ValidModule, CanonicalModule, Optimized
6− , Module(..), Kind(..), Body(..)
7− , Header(..)
8− , Interface(..), toInterface
2+ ( Header(..), Module(..), Tag(..)
3+
4+ , Source, SourceInfo(..)
5+ , Valid, ValidInfo(..)
6+ , Canonical, Optimized, Info(..)
7+
98 , UserImport, DefaultImport, ImportMethod(..)
10− ) where
9+
10+ , Effects(..)
11+ , Types
12+ , Aliases
13+ , Unions, UnionInfo, CanonicalUnion
14+
15+ , Interfaces, Interface(..), toInterface
16+ )
17+ where
1118
1219import Data.Binary
1320import qualified Data.Map as Map
@@ -15,6 +22,7 @@ import qualified Data.Map as Map
1522import qualified AST.Declaration as Decl
1623import qualified AST.Expression.Canonical as Canonical
1724import qualified AST.Expression.Optimized as Optimized
25+import qualified AST.Expression.Valid as Valid
1826import qualified AST.Module.Name as Name
1927import qualified AST.Type as Type
2028import qualified AST.Variable as Var
@@ -25,118 +33,134 @@ import qualified Reporting.Annotation as A
2533
2634
2735
28−-- HELPFUL TYPE ALIASES
36+-- HEADERS FOR PARSING
2937
3038
31−type Interfaces =
32− Map.Map Name.Canonical Interface
39+{-| Basic info needed to identify modules and determine dependencies. -}
40+data Header imports =
41+ Header
42+ { _tag :: Tag
43+ , _name :: Name.Raw
44+ , _docs :: A.Located (Maybe String)
45+ , _exports :: Var.Listing (A.Located Var.Value)
46+ , _imports :: imports
47+ }
3348
3449
35−type Types =
36− Map.Map String Type.Canonical
3750
51+-- MODULES
3852
39−type Aliases =
40− Map.Map String ([String], Type.Canonical)
53+
54+data Module phase =
55+ Module
56+ { tag :: Tag
57+ , name :: Name.Canonical
58+ , path :: FilePath
59+ , info :: phase
60+ }
4161
4262
43−type Unions =
44− Map.Map String (UnionInfo String)
63+data Tag
64+ = None
65+ | Effect
66+ | Foreign
4567
4668
47−type UnionInfo v =
48− ( [String], [(v, [Type.Canonical])] )
69+type Source =
70+ Module SourceInfo
4971
5072
51−type CanonicalUnion =
52− ( Var.Canonical, UnionInfo Var.Canonical )
73+data SourceInfo =
74+ Source
75+ { srcDocs :: A.Located (Maybe String)
76+ , srcExports :: Var.Listing (A.Located Var.Value)
77+ , srcImports :: [UserImport]
78+ , srcDecls :: [Decl.Source]
79+ }
5380
5481
82+type Valid =
83+ Module ValidInfo
5584
56−-- MODULES
5785
86+data ValidInfo =
87+ Valid
88+ { validDocs :: A.Located (Maybe String)
89+ , validExports :: Var.Listing (A.Located Var.Value)
90+ , validImports :: ([DefaultImport], [UserImport])
91+ , validDecls :: [Decl.Valid]
92+ , validCmds :: [A.Commented Valid.Effect]
93+ , validSubs :: [A.Commented Valid.Effect]
94+ }
5895
59−type SourceModule =
60− Module
61− String
62− [UserImport]
63− (Var.Listing (A.Located Var.Value))
64− [Decl.SourceDecl]
6596
97+type Canonical =
98+ Module (Info Canonical.Expr)
6699
67−type ValidModule =
68− Module
69− String
70− ([DefaultImport], [UserImport])
71− (Var.Listing (A.Located Var.Value))
72− [Decl.ValidDecl]
73100
101+type Optimized =
102+ Module (Info [Optimized.Def])
74103
75−type CanonicalModule =
76− Module Docs.Centralized [Name.Raw] [Var.Value] (Body Canonical.Expr)
77104
78105
79−type Optimized =
80− Module Docs.Centralized [Name.Raw] [Var.Value] (Body [Optimized.Def])
106+-- IMPORTS
81107
82108
83−data Module docs imports exports body =
84− Module
85− { kind :: Kind
86− , name :: Name.Canonical
87− , path :: FilePath
88− , docs :: A.Located (Maybe docs)
89− , exports :: exports
90− , imports :: imports
91− , body :: body
109+type UserImport = A.Located (Name.Raw, ImportMethod)
110+
111+
112+type DefaultImport = (Name.Raw, ImportMethod)
113+
114+
115+data ImportMethod =
116+ ImportMethod
117+ { alias :: Maybe String
118+ , exposedVars :: !(Var.Listing Var.Value)
92119 }
93120
94121
95−data Kind
96− = Normal
97− | Effect
98− | Foreign
122+
123+-- LATE PHASE MODULE INFORMATION
99124
100125
101−data Body expr =
102− Body
103− { program :: expr
126+data Info expr =
127+ Info
128+ { docs :: Docs.Centralized
129+ , exports :: [Var.Value]
130+ , imports :: [Name.Raw]
131+ , program :: expr
104132 , types :: Types
105133 , fixities :: [(Decl.Assoc, Int, String)]
106134 , aliases :: Aliases
107135 , unions :: Unions
136+ , effects :: Effects
108137 }
109138
110139
140+type Types =
141+ Map.Map String Type.Canonical
111142
112−-- HEADERS
113−
114−
115−{-| Basic info needed to identify modules and determine dependencies. -}
116−data Header imports =
117− Header
118− { _kind :: Kind
119− , _name :: Name.Raw
120− , _docs :: A.Located (Maybe String)
121− , _exports :: Var.Listing (A.Located Var.Value)
122− , _imports :: imports
123− }
124143
144+type Aliases =
145+ Map.Map String ([String], Type.Canonical)
125146
126147
127−-- IMPORTs
148+type Unions =
149+ Map.Map String (UnionInfo String)
128150
129151
130−type UserImport = A.Located (Name.Raw, ImportMethod)
152+type UnionInfo v =
153+ ( [String], [(v, [Type.Canonical])] )
131154
132155
133−type DefaultImport = (Name.Raw, ImportMethod)
156+type CanonicalUnion =
157+ ( Var.Canonical, UnionInfo Var.Canonical )
134158
135159
136−data ImportMethod =
137− ImportMethod
138− { alias :: Maybe String
139− , exposedVars :: !(Var.Listing Var.Value)
160+data Effects =
161+ Effects
162+ { cmds :: [String]
163+ , subs :: [String]
140164 }
141165
142166
@@ -144,14 +168,18 @@ data ImportMethod =
144168-- INTERFACES
145169
146170
171+type Interfaces =
172+ Map.Map Name.Canonical Interface
173+
174+
147175{-| Key facts about a module, used when reading info from .elmi files. -}
148176data Interface =
149177 Interface
150178 { iVersion :: Package.Version
151179 , iPackage :: Package.Name
152180 , iExports :: [Var.Value]
153− , iTypes :: Types
154181 , iImports :: [Name.Raw]
182+ , iTypes :: Types
155183 , iUnions :: Unions
156184 , iAliases :: Aliases
157185 , iFixities :: [(Decl.Assoc, Int, String)]
@@ -161,18 +189,18 @@ data Interface =
161189toInterface :: Package.Name -> Optimized -> Interface
162190toInterface pkgName modul =
163191 let
164− body' =
165− body modul
192+ myInfo =
193+ info modul
166194 in
167195 Interface
168196 { iVersion = Compiler.version
169197 , iPackage = pkgName
170− , iExports = exports modul
171− , iTypes = types body'
172− , iImports = imports modul
173− , iUnions = unions body'
174− , iAliases = aliases body'
175− , iFixities = fixities body'
198+ , iExports = exports myInfo
199+ , iImports = imports myInfo
200+ , iTypes = types myInfo
201+ , iUnions = unions myInfo
202+ , iAliases = aliases myInfo
203+ , iFixities = fixities myInfo
176204 }
177205
178206
@@ -184,8 +212,8 @@ instance Binary Interface where
184212 do put (iVersion modul)
185213 put (iPackage modul)
186214 put (iExports modul)
187− put (iTypes modul)
188215 put (iImports modul)
216+ put (iTypes modul)
189217 put (iUnions modul)
190218 put (iAliases modul)
191219 put (iFixities modul)
src/Elm/Utils.hs+2−3
@@ -18,7 +18,6 @@ import System.FilePath ((</>))
1818import System.IO.Error (tryIOError)
1919import System.Process (readProcessWithExitCode)
2020
21−import qualified AST.Expression.Source as Source
2221import qualified AST.Pattern as Pattern
2322import qualified Elm.Compiler.Version as Version
2423import qualified Elm.Package as Pkg
@@ -154,8 +153,8 @@ errorNotFound name =
154153
155154isDeclaration :: String -> Maybe String
156155isDeclaration string =
157− case Parse.iParse Parse.definition string of
158− Right (A.A _ (Source.Definition pattern _)) ->
156+ case Parse.iParse (Parse.definition (,)) string of
157+ Right (A.A _ (pattern, _)) ->
159158 Just (List.intercalate "$" (Pattern.boundVarList pattern))
160159
161160 _ ->
src/Optimize.hs+24−22
@@ -23,16 +23,25 @@ import qualified Reporting.Region as R
2323-- OPTIMIZE
2424
2525
26−optimize :: DT.VariantDict -> Module.CanonicalModule -> Module.Optimized
27−optimize variantDict module_@(Module.Module _ home _ _ _ _ body) =
26+optimize :: DT.VariantDict -> Module.Canonical -> Module.Optimized
27+optimize variantDict module_@(Module.Module _ home _ info) =
2828 let
29+ (Module.Canonical docs exports imports body) =
30+ info
31+
2932 (defs, _) =
30− flattenLets [] (Module.program body)
33+ flattenLets [] (Module.program body)
3134
3235 optDefs =
3336 Env.run variantDict home (concat <$> mapM (optimizeDef True) defs)
37+
38+ optBody =
39+ body { Module.program = optDefs }
3440 in
35− module_ { Module.body = body { Module.program = optDefs } }
41+ module_
42+ { Module.info =
43+ Module.Optimized docs exports imports optBody
44+ }
3645
3746
3847flattenLets :: [Can.Def] -> Can.Expr -> ([Can.Def], Can.Expr)
@@ -67,8 +76,8 @@ optimizeDef isRoot (Can.Definition (Can.Facts deps) pattern expression _) =
6776optimizeDefHelp
6877 :: Maybe ModuleName.Canonical
6978 -> [Var.TopLevel]
70− -> P.CanonicalPattern
71− -> [P.CanonicalPattern]
79+ -> P.Canonical
80+ -> [P.Canonical]
7281 -> Can.Expr
7382 -> Env.Optimizer [Opt.Def]
7483optimizeDefHelp home deps pattern@(A.A _ ptrn) args rawBody =
@@ -118,7 +127,7 @@ optimizeDefHelp home deps pattern@(A.A _ ptrn) args rawBody =
118127
119128optimizeFunction
120129 :: Maybe String
121− -> [P.CanonicalPattern]
130+ -> [P.Canonical]
122131 -> Can.Expr
123132 -> Env.Optimizer ([String], Opt.Expr)
124133optimizeFunction maybeName patterns givenBody =
@@ -132,20 +141,13 @@ makeContext argNames name =
132141 Just (name, length argNames, argNames)
133142
134143
135−depatternArgs
136− :: ([String], Can.Expr)
137− -> P.CanonicalPattern
138− -> Env.Optimizer ([String], Can.Expr)
144+depatternArgs :: ([String], Can.Expr) -> P.Canonical -> Env.Optimizer ([String], Can.Expr)
139145depatternArgs (names, rawExpr) ptrn =
140146 do (name, expr) <- depattern ptrn rawExpr
141147 return (name : names, expr)
142148
143149
144−patternToDefs
145− :: Maybe ModuleName.Canonical
146− -> String
147− -> P.CanonicalPattern
148− -> [Opt.Def]
150+patternToDefs :: Maybe ModuleName.Canonical -> String -> P.Canonical -> [Opt.Def]
149151patternToDefs home rootName pattern =
150152 let
151153 (deps, rootExpr) =
@@ -170,7 +172,7 @@ patternToDefs home rootName pattern =
170172-- TURN A PATTERN INTO A BUNCH OF SUBSTITUTIONS
171173
172174
173−patternToSubstitutions :: Opt.Expr -> P.CanonicalPattern -> [(String, Opt.Expr)]
175+patternToSubstitutions :: Opt.Expr -> P.Canonical -> [(String, Opt.Expr)]
174176patternToSubstitutions expr (A.A _ pattern) =
175177 case pattern of
176178 P.Var name ->
@@ -322,8 +324,8 @@ optimizeBranch
322324 :: Context
323325 -> R.Region
324326 -> String
325− -> (P.CanonicalPattern, Can.Expr)
326− -> Env.Optimizer (P.CanonicalPattern, Opt.Expr)
327+ -> (P.Canonical, Can.Expr)
328+ -> Env.Optimizer (P.Canonical, Opt.Expr)
327329optimizeBranch context region exprName (rawPattern, canBranch) =
328330 let
329331 root =
@@ -340,9 +342,9 @@ optimizeBranch context region exprName (rawPattern, canBranch) =
340342
341343tagCrashBranch
342344 :: R.Region
343− -> P.CanonicalPattern
345+ -> P.Canonical
344346 -> Opt.Expr
345− -> Env.Optimizer (P.CanonicalPattern, Opt.Expr)
347+ -> Env.Optimizer (P.Canonical, Opt.Expr)
346348tagCrashBranch region pattern@(A.A pr _) expr =
347349 case expr of
348350 Opt.Call (Opt.Crash home _ _) [arg] ->
@@ -382,7 +384,7 @@ isTailCall context (A.A _ function) arity =
382384-- it out from there
383385
384386
385−depattern :: P.CanonicalPattern -> Can.Expr -> Env.Optimizer (String, Can.Expr)
387+depattern :: P.Canonical -> Can.Expr -> Env.Optimizer (String, Can.Expr)
386388depattern canPattern@(A.A _ pattern) expr =
387389 let
388390 ann =
src/Parse/Declaration.hs+62−16
@@ -2,19 +2,33 @@
22module Parse.Declaration where
33
44import Text.Parsec ( (<|>), (<?>), choice, digit, optionMaybe, string, try )
5+import qualified Text.Parsec.Indent as Indent
56
6−import qualified AST.Declaration as D
7+import qualified AST.Declaration as Decl
8+import qualified AST.Expression.Source as Source
79import qualified Parse.Expression as Expr
810import Parse.Helpers as Help
911import qualified Parse.Type as Type
12+import qualified Reporting.Annotation as A
1013
1114
1215
13−declaration :: IParser D.SourceDecl
16+declaration :: IParser Decl.Source
1417declaration =
18+ commentOr $ addLocation $
19+ choice
20+ [ Decl.Source <$> typeDecl
21+ , Decl.Source <$> infixDecl
22+ , defineDecl
23+ , Decl.Source <$> definition
24+ ]
25+
26+
27+commentOr :: IParser a -> IParser (Decl.CommentOr a)
28+commentOr parser =
1529 choice
16− [ D.Comment <$> Help.docComment
17− , D.Decl <$> addLocation (typeDecl <|> infixDecl <|> definition)
30+ [ Decl.Comment <$> addLocation Help.docComment
31+ , Decl.Whatever <$> parser
1832 ]
1933
2034
@@ -22,18 +36,17 @@ declaration =
2236-- TYPE ANNOTATIONS and DEFINITIONS
2337
2438
25−definition :: IParser D.SourceDecl'
39+definition :: IParser Decl.Source'
2640definition =
27− D.Definition
28− <$> (Expr.typeAnnotation <|> Expr.definition)
29− <?> "a value definition"
41+ do def <- Expr.def <?> "a value definition"
42+ return $ Decl.Def def
3043
3144
3245
3346-- TYPE ALIAS and UNION TYPES
3447
3548
36−typeDecl :: IParser D.SourceDecl'
49+typeDecl :: IParser Decl.Source'
3750typeDecl =
3851 do try (reserved "type") <?> "a type declaration"
3952 forcedWS
@@ -46,28 +59,61 @@ typeDecl =
4659 case isAlias of
4760 Just _ ->
4861 do tipe <- Type.expr <?> "a type"
49− return (D.TypeAlias name args tipe)
62+ return $ Decl.Alias name args tipe
5063
5164 Nothing ->
5265 do tcs <- pipeSep1 Type.constructor <?> "a constructor for a union type"
53− return $ D.Datatype name args tcs
66+ return $ Decl.Union name args tcs
5467
5568
5669
5770-- INFIX
5871
5972
60−infixDecl :: IParser D.SourceDecl'
73+infixDecl :: IParser Decl.Source'
6174infixDecl =
6275 expecting "an infix declaration" $
6376 do assoc <-
6477 choice
65− [ try (reserved "infixl") >> return D.L
66− , try (reserved "infixr") >> return D.R
67− , try (reserved "infix") >> return D.N
78+ [ try (reserved "infixl") >> return Decl.L
79+ , try (reserved "infixr") >> return Decl.R
80+ , try (reserved "infix") >> return Decl.N
6881 ]
6982 forcedWS
7083 n <- digit
7184 forcedWS
72− D.Fixity assoc (read [n]) <$> anyOp
85+ op <- anyOp
86+ return $ Decl.Fixity assoc (read [n]) op
87+
88+
89+
90+-- DEFINE
91+
92+
93+defineDecl :: IParser Decl.SourceOrDefine
94+defineDecl =
95+ do try (reserved "define")
96+ forcedWS
7397
98+ name <-
99+ string "commands" <|> string "subscriptions"
100+
101+ padded (reserved "as")
102+
103+ effects <-
104+ Indent.block (commentOr effectDef <* whitespace)
105+
106+ return (Decl.Define name effects)
107+
108+
109+effectDef :: IParser (A.Located Source.Effect)
110+effectDef =
111+ choice
112+ [ Expr.annotation Source.Type
113+ , Expr.definition Source.Def
114+ , addLocation $
115+ do name <- lowVar
116+ padded (reserved "with")
117+ expr <- Expr.expr
118+ return (Source.With name expr)
119+ ]
src/Parse/Expression.hs+39−17
@@ -1,4 +1,4 @@
1−module Parse.Expression (term, typeAnnotation, definition, expr) where
1+module Parse.Expression (term, annotation, definition, expr, def) where
22
33import qualified Data.List as List
44import Text.Parsec hiding (newline, spaces)
@@ -15,12 +15,15 @@ import qualified AST.Expression.General as E
1515import qualified AST.Expression.Source as Source
1616import qualified AST.Literal as L
1717import qualified AST.Pattern as P
18+import qualified AST.Type as T
1819import qualified AST.Variable as Var
1920import qualified Reporting.Annotation as A
2021
2122
23+
2224-------- Basic Terms --------
2325
26+
2427varTerm :: IParser Source.Expr'
2528varTerm =
2629 toVar <$> var
@@ -70,8 +73,10 @@ negative =
7073 nTerm
7174
7275
76+
7377-------- Complex Terms --------
7478
79+
7580listTerm :: IParser Source.Expr'
7681listTerm =
7782 shader' <|> braces (try range <|> E.ExplicitList <$> commaSep expr)
@@ -122,7 +127,6 @@ parensTerm =
122127 return (mkExpr start end)
123128
124129
125−
126130recordTerm :: IParser Source.Expr
127131recordTerm =
128132 addLocation $ brackets $ choice $
@@ -168,8 +172,10 @@ term =
168172 <?> "an expression"
169173
170174
175+
171176-------- Applications --------
172177
178+
173179appExpr :: IParser Source.Expr
174180appExpr =
175181 expecting "an expression" $
@@ -182,8 +188,10 @@ appExpr =
182188 _ -> List.foldl' (\f x -> A.merge f x $ E.App f x) t ts
183189
184190
191+
185192-------- Normal Expressions --------
186193
194+
187195expr :: IParser Source.Expr
188196expr =
189197 addLocation (choice [ letExpr, caseExpr, ifExpr ])
@@ -256,51 +264,65 @@ caseExpr =
256264 (,) p <$> expr
257265
258266
267+
259268-- LET
260269
270+
261271letExpr :: IParser Source.Expr'
262272letExpr =
263273 do try (reserved "let")
264274 whitespace
265275 defs <-
266− Indent.block $
267− do def <- typeAnnotation <|> definition
268− whitespace
269− return def
270− padded (reserved "in")
276+ Indent.block (def <* whitespace)
277+ whitespace
278+ reserved "in"
279+ whitespace
271280 E.Let defs <$> expr
272281
273282
283+def :: IParser Source.Def
284+def =
285+ choice
286+ [ annotation Source.Annotation
287+ , definition Source.Definition
288+ ]
289+
290+
291+
274292-- TYPE ANNOTATION
275293
276−typeAnnotation :: IParser Source.Def
277−typeAnnotation =
278− addLocation (Source.TypeAnnotation <$> try start <*> Type.expr)
279− where
294+
295+annotation :: (String -> T.Raw -> a) -> IParser (A.Located a)
296+annotation creator =
297+ let
280298 start =
281299 do v <- lowVar <|> parens symOp
282300 padded hasType
283301 return v
302+ in
303+ addLocation (creator <$> try start <*> Type.expr)
304+
284305
285306
286307-- DEFINITION
287308
288−definition :: IParser Source.Def
289−definition =
309+
310+definition :: (P.Raw -> Source.Expr -> a) -> IParser (A.Located a)
311+definition creator =
290312 addLocation $
291313 Indent.withPos $
292314 do (name, args) <- defStart
293315 padded equals
294316 body <- expr
295− return . Source.Definition name $ makeFunction args body
317+ return . creator name $ makeFunction args body
296318
297319
298−makeFunction :: [P.RawPattern] -> Source.Expr -> Source.Expr
320+makeFunction :: [P.Raw] -> Source.Expr -> Source.Expr
299321makeFunction args body@(A.A ann _) =
300− foldr (\arg body' -> A.A ann $ E.Lambda arg body') body args
322+ foldr (\arg body' -> A.A ann $ E.Lambda arg body') body args
301323
302324
303−defStart :: IParser (P.RawPattern, [P.RawPattern])
325+defStart :: IParser (P.Raw, [P.Raw])
304326defStart =
305327 expecting "the definition of a value (x = ...)" $
306328 do starter <- try Pattern.term <|> addLocation (P.Var <$> parens symOp)
src/Parse/Helpers.hs+3−3
@@ -29,9 +29,9 @@ reserveds =
2929 , "let", "in"
3030 , "type"
3131 , "module", "where"
32− , "import", "as", "hiding", "exposing"
33− , "port", "export", "foreign"
34− , "perform"
32+ , "import", "exposing", "hiding", "export"
33+ , "as"
34+ , "define", "with"
3535 , "deriving"
3636 ]
3737
src/Parse/Module.hs+10−9
@@ -1,3 +1,4 @@
1+{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
12module Parse.Module (moduleDecl, header, getModuleName) where
23
34import Text.Parsec hiding (newline, spaces)
@@ -12,12 +13,12 @@ import Reporting.Annotation as A
1213getModuleName :: String -> Maybe String
1314getModuleName source =
1415 let
15− getModuleName =
16+ minimalParser =
1617 do optional freshLine
1718 (_, names, _) <- moduleDecl
1819 return (ModuleName.toString names)
1920 in
20− case iParse getModuleName source of
21+ case iParse minimalParser source of
2122 Right name ->
2223 Just name
2324
@@ -28,9 +29,9 @@ getModuleName source =
2829header :: IParser (Module.Header [Module.UserImport])
2930header =
3031 do optional freshLine
31− (kind, names, exports) <-
32+ (tag, names, exports) <-
3233 option
33− (Module.Normal, ["Main"], Var.openListing)
34+ (Module.None, ["Main"], Var.openListing)
3435 (moduleDecl `followedBy` freshLine)
3536
3637 docs <-
@@ -41,17 +42,17 @@ header =
4142
4243 imports' <- imports
4344
44− return (Module.Header kind names docs exports imports')
45+ return (Module.Header tag names docs exports imports')
4546
4647
47−moduleDecl :: IParser (Module.Kind, [String], Var.Listing (A.Located Var.Value))
48+moduleDecl :: IParser (Module.Tag, [String], Var.Listing (A.Located Var.Value))
4849moduleDecl =
4950 expecting "a module declaration" $
5051 do
5152 kind <-
5253 choice
5354 [ do try (reserved "module")
54− return Module.Normal
55+ return Module.None
5556 , do try (reserved "effect")
5657 whitespace
5758 reserved "module"
@@ -114,14 +115,14 @@ listing item =
114115 expecting "a listing of values and types to expose, like (..)" $
115116 do try (whitespace >> char '(')
116117 whitespace
117− listing <-
118+ actualListing <-
118119 choice
119120 [ const Var.openListing <$> string ".."
120121 , Var.Listing <$> commaSep1 item <*> return False
121122 ]
122123 whitespace
123124 char ')'
124− return listing
125+ return actualListing
125126
126127
127128value :: IParser Var.Value
src/Parse/Parse.hs+62−32
@@ -1,4 +1,4 @@
1−{-# OPTIONS_GHC -Wall #-}
1+{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
22module Parse.Parse (program, parse) where
33
44import qualified Data.Map as Map
@@ -6,14 +6,14 @@ import qualified Data.Traversable as T
66import Text.Parsec (char, eof, letter, many, putState, (<|>))
77import qualified Text.Parsec.Error as Parsec
88
9−import qualified AST.Declaration as D
10−import qualified AST.Module as M
9+import qualified AST.Declaration as Decl
10+import qualified AST.Module as Module
1111import qualified AST.Module.Name as ModuleName
1212import qualified Elm.Compiler.Imports as Imports
1313import qualified Elm.Package as Package
1414import Parse.Helpers
15−import qualified Parse.Module as Module
16−import qualified Parse.Declaration as Decl
15+import qualified Parse.Module as Parse (header)
16+import qualified Parse.Declaration as Parse (declaration, infixDecl)
1717import qualified Reporting.Region as R
1818import qualified Reporting.Error.Syntax as Error
1919import qualified Reporting.Result as Result
@@ -25,50 +25,80 @@ program
2525 :: Package.Name
2626 -> OpTable
2727 -> String
28− -> Result.Result wrn Error.Error M.ValidModule
28+ -> Result.Result wrn Error.Error Module.Valid
2929program pkgName table src =
30− do (M.Module kind name filePath docs exports imports sourceDecls) <-
31− parseWithTable table src (programParser pkgName)
30+ do modul <-
31+ parseWithTable table src (programParser pkgName)
3232
33− validDecls <- Validate.declarations sourceDecls
33+ let
34+ (Module.Source docs exports imports sourceDecls) =
35+ Module.info modul
3436
35− -- determine if default imports should be added, only elm-lang/core is exempt
36− let ammendedImports =
37− ( if pkgName == Package.coreName then [] else Imports.defaults
38− , imports
39− )
37+ validDecls <-
38+ Validate.declarations sourceDecls
4039
41− return (M.Module kind name filePath docs exports ammendedImports validDecls)
40+ return $
41+ modul
42+ { Module.info =
43+ Module.Valid
44+ docs
45+ exports
46+ (addDefaults pkgName imports)
47+ validDecls
48+ (error "TODO")
49+ (error "TODO")
50+ }
51+
52+
53+-- determine if default imports should be added, only elm-lang/core is exempt
54+addDefaults
55+ :: Package.Name
56+ -> [Module.UserImport]
57+ -> ([Module.DefaultImport], [Module.UserImport])
58+addDefaults pkgName imports =
59+ flip (,) imports $
60+ if pkgName == Package.coreName then
61+ []
62+
63+ else
64+ Imports.defaults
4265
4366
4467
4568-- HEADERS AND DECLARATIONS
4669
4770
48−programParser :: Package.Name -> IParser M.SourceModule
71+programParser :: Package.Name -> IParser Module.Source
4972programParser pkgName =
50− do (M.Header kind name docs exports imports) <- Module.header
51− decls <- declarations
52− _ <- many (spaces <|> newline)
53− eof
73+ do (Module.Header tag name docs exports imports) <-
74+ Parse.header
5475
55− let canonicalName =
56− ModuleName.Canonical pkgName name
76+ decls <-
77+ declarations
78+
79+ many (spaces <|> newline)
80+
81+ eof
5782
58− return $ M.Module kind canonicalName "" docs exports imports decls
83+ return $
84+ Module.Module
85+ tag
86+ (ModuleName.Canonical pkgName name)
87+ ""
88+ (Module.Source docs exports imports decls)
5989
6090
61−declarations :: IParser [D.SourceDecl]
91+declarations :: IParser [Decl.Source]
6292declarations =
63− (:) <$> Decl.declaration
93+ (:) <$> Parse.declaration
6494 <*> many freshDef
6595
6696
67−freshDef :: IParser D.SourceDecl
97+freshDef :: IParser Decl.Source
6898freshDef =
6999 commitIf (freshLine >> (letter <|> char '_')) $
70− do _ <- freshLine
71− Decl.declaration
100+ do freshLine
101+ Parse.declaration
72102
73103
74104
@@ -108,9 +138,9 @@ parseWithTable table source parser =
108138
109139
110140makeInfixTable
111− :: Map.Map String (Int, D.Assoc)
141+ :: Map.Map String (Int, Decl.Assoc)
112142 -> [(String, InfixInfo)]
113− -> Result.Result wrn Error.Error (Map.Map String (Int, D.Assoc))
143+ -> Result.Result wrn Error.Error (Map.Map String (Int, Decl.Assoc))
114144makeInfixTable table newInfo =
115145 let add (op, info) dict =
116146 Map.insertWith (++) op [info] dict
@@ -140,12 +170,12 @@ parseFixities =
140170 where
141171 infics =
142172 do start <- getMyPosition
143− (D.Fixity assoc level op) <- Decl.infixDecl
173+ (Decl.Fixity assoc level op) <- Parse.infixDecl
144174 end <- getMyPosition
145175 return (op, InfixInfo (R.Region start end) (level, assoc))
146176
147177
148178data InfixInfo = InfixInfo
149179 { _region :: R.Region
150− , _info :: (Int, D.Assoc)
180+ , _info :: (Int, Decl.Assoc)
151181 }
src/Reporting/Error/Syntax.hs+55−28
@@ -15,10 +15,13 @@ data Error
1515 = Parse [Parsec.Message]
1616 | BadFunctionName Int
1717 | BadPattern String
18+ | CommentAfterAnnotation String
19+ | CommentOnComment
20+ | CommentOnNothing
21+ | DefineDuplicate String
22+ | DefineUnknown String
1823 | InfixDuplicate String
1924 | TypeWithoutDefinition String
20− | PortWithoutAnnotation String
21− | UnexpectedPort
2225 | DuplicateFieldName String
2326 | DuplicateValueDeclaration String
2427 | DuplicateTypeDeclaration String
@@ -64,6 +67,52 @@ toReport _localizer err =
6467 ]
6568 )
6669
70+ CommentAfterAnnotation name ->
71+ Report.report
72+ "STRAY COMMENT"
73+ Nothing
74+ ("The type annotation for `" ++ name ++ "` is followed by a documentation comment.")
75+ ( Help.reflowParagraph $
76+ "Documentation comments need to be *before* type annotations. Furthermore,\
77+ \ type annotations need to be right above the corresponding definition, no\
78+ \ comments in between."
79+ )
80+
81+ CommentOnComment ->
82+ Report.report
83+ "STRAY COMMENT"
84+ Nothing
85+ ("This comment is followed by another documentation comment.")
86+ ( Help.reflowParagraph $
87+ "All documentation comments need to be right above the declaration they\
88+ \ describe. Maybe some code got deleted or commented out by accident?"
89+ )
90+
91+ CommentOnNothing ->
92+ Report.report
93+ "STRAY COMMENT"
94+ Nothing
95+ ("This documentation comment is not followed by anything.")
96+ ( text "What is it documenting? Maybe it should just be removed?" )
97+
98+ DefineDuplicate name ->
99+ Report.report
100+ "DUPLICATE DEFINE"
101+ Nothing
102+ ("A module can have only one `define " ++ name ++ "` declaration.")
103+ ( text "This module has two though. You should combine them or remove one." )
104+
105+ DefineUnknown name ->
106+ Report.report
107+ "UNKNOWN DEFINE"
108+ Nothing
109+ ("You are trying to `define " ++ name ++ "`, but that is not recognized.")
110+ ( Help.reflowParagraph $
111+ "You can only define `commands` and `subscriptions` with this syntax.\
112+ \ Furthermore, you must be in an `effect module` or `foreign effect module` to\
113+ \ even have access to this syntax."
114+ )
115+
67116 InfixDuplicate opName ->
68117 Report.report
69118 "INFIX OVERLAP"
@@ -87,28 +136,6 @@ toReport _localizer err =
87136 ++ " " ++ valueName ++ " = 42"
88137 )
89138
90− PortWithoutAnnotation portName ->
91− Report.report
92− "PORT ERROR"
93− Nothing
94− ("Port `" ++ portName ++ "` does not have a type annotation!")
95− ( text $
96− "Directly above the port definition, I need something like this:\n\n"
97− ++ " port " ++ portName ++ " : Signal Int"
98− )
99−
100−
101− UnexpectedPort ->
102− Report.report
103− "PORT ERROR"
104− Nothing
105− "This module has ports, but ports can only appear in the main module."
106− ( Help.reflowParagraph $
107− "Ports in library code would create hidden dependencies where importing a\
108− \ module could bring in constraints not captured in the public API. Furthermore,\
109− \ if the module is imported twice, do we send values out the port twice?"
110− )
111−
112139 DuplicateFieldName name ->
113140 Report.report
114141 "DUPLICATE FIELD"
@@ -191,7 +218,7 @@ toReport _localizer err =
191218
192219
193220unboundTypeVars :: String -> String -> [String] -> [String] -> Report.Report
194−unboundTypeVars declKind typeName givenVars unboundVars@(tvar:_) =
221+unboundTypeVars declKind typeName givenVars unboundVars =
195222 Report.report
196223 "UNBOUND TYPE VARIABLES"
197224 Nothing
@@ -205,9 +232,9 @@ unboundTypeVars declKind typeName givenVars unboundVars@(tvar:_) =
205232 ++ map (dullyellow . text) unboundVars
206233 ++ map text ["=", "..."]
207234 , Help.reflowParagraph $
208− "Here's why. Imagine one `" ++ typeName ++ "` where `" ++ tvar ++ "` is an Int and\
209− \ another where it is a Bool. When we explicitly list the type variables, type\
210− \ checker can see that they are actually different types."
235+ "Here's why. Imagine one `" ++ typeName ++ "` where `" ++ head unboundVars ++
236+ "` is an Int and another where it is a Bool. When we explicitly list the type\
237+ \ variables, type checker can see that they are actually different types."
211238 ]
212239 )
213240
src/Validate.hs+253−112
@@ -3,6 +3,7 @@ module Validate (declarations) where
33
44import Control.Monad (foldM)
55import qualified Data.Map as Map
6+import qualified Data.Maybe as Maybe
67import qualified Data.Set as Set
78import qualified Data.Foldable as F
89import qualified Data.Traversable as T
@@ -21,94 +22,225 @@ import qualified Reporting.Result as Result
2122
2223
2324
24−-- VALIDATE DECLARATIONS
25+-- COLLAPSE COMMENTS
26+
27+
28+type Commented a =
29+ A.Annotated (R.Region, Maybe (A.Located String)) a
30+
31+
32+collapseComments
33+ :: [D.CommentOr (A.Located a)]
34+ -> Result.Result wrn Error.Error [Commented a]
35+collapseComments listWithComments =
36+ case listWithComments of
37+ [] ->
38+ Result.ok []
39+
40+ D.Comment msg : D.Whatever (A.A region a) : rest ->
41+ let
42+ entry =
43+ A.A (region, Just msg) a
44+ in
45+ fmap (entry:) (collapseComments rest)
46+
47+ D.Comment (A.A region _) : D.Comment _ : _ ->
48+ Result.throw region Error.CommentOnComment
49+
50+ [D.Comment (A.A region _)] ->
51+ Result.throw region Error.CommentOnNothing
52+
53+ D.Whatever (A.A region a) : rest ->
54+ let
55+ entry =
56+ A.A (region, Nothing) a
57+ in
58+ fmap (entry:) (collapseComments rest)
59+
60+
61+
62+-- EXTRACT DEFINES
63+
2564
65+data StructuredSource =
66+ Src
67+ { _decls :: [Commented D.Source']
68+ , _cmds :: Maybe [Commented Source.Effect]
69+ , _subs :: Maybe [Commented Source.Effect]
70+ }
2671
27−declarations
28− :: [D.SourceDecl]
29− -> Result.Result wrn Error.Error [D.ValidDecl]
72+
73+extractEffects :: [Commented D.SourceOrDefine] -> Result.Result wrn Error.Error StructuredSource
74+extractEffects commentedDecls =
75+ case commentedDecls of
76+ [] ->
77+ Result.ok (Src [] Nothing Nothing)
78+
79+ A.A ann (D.Source decl) : rest ->
80+ do restSrc <- extractEffects rest
81+ return $ restSrc { _decls = A.A ann decl : _decls restSrc }
82+
83+ A.A (region, _) (D.Define name commentOrEffects) : rest ->
84+ do restSrc <- extractEffects rest
85+ case name of
86+ "commands" ->
87+ case _cmds restSrc of
88+ Nothing ->
89+ do effects <- collapseComments commentOrEffects
90+ Result.ok $ restSrc { _cmds = Just effects }
91+
92+ Just _ ->
93+ Result.throw region (Error.DefineDuplicate name)
94+
95+ "subscriptions" ->
96+ case _subs restSrc of
97+ Nothing ->
98+ do effects <- collapseComments commentOrEffects
99+ Result.ok $ restSrc { _subs = Just effects }
100+
101+ Just _ ->
102+ Result.throw region (Error.DefineDuplicate name)
103+
104+ _ ->
105+ Result.throw region (Error.DefineUnknown name)
106+
107+
108+
109+-- VALIDATE STRUCTURED SOURCE
110+
111+
112+declarations :: [D.Source] -> Result.Result wrn Error.Error [D.Valid]
30113declarations sourceDecls =
31− do validDecls <- validateDecls Nothing sourceDecls
114+ do (Src decls cmds subs) <-
115+ extractEffects =<< collapseComments sourceDecls
116+
117+ validDecls <-
118+ validateDecls decls
119+
120+ validCmds <-
121+ validateEffects (Maybe.fromMaybe [] cmds)
122+
123+ validSubs <-
124+ validateEffects (Maybe.fromMaybe [] subs)
125+
32126 (\_ _ -> validDecls)
33127 <$> declDuplicates validDecls
34128 <*> T.traverse checkDecl validDecls
35129
36130
131+
132+-- VALIDATE DECLARATIONS
133+
134+
37135validateDecls
38− :: Maybe String
39− -> [D.SourceDecl]
40− -> Result.Result wrn Error.Error [D.ValidDecl]
41−validateDecls maybeComment sourceDecls =
42− case sourceDecls of
136+ :: [Commented D.Source']
137+ -> Result.Result wrn Error.Error [D.Valid]
138+validateDecls commentedDecls =
139+ case commentedDecls of
43140 [] ->
44− return []
141+ Result.ok []
45142
46− sourceDecl : decls ->
47− case sourceDecl of
48− D.Comment comment ->
49− validateDecls (Just comment) decls
143+ A.A (region, maybeComment) decl : rest ->
144+ let
145+ addRest validDecl =
146+ let
147+ entry =
148+ A.A (region, fmap A.drop maybeComment) validDecl
149+ in
150+ fmap (entry:) (validateDecls rest)
151+ in
152+ case decl of
153+ D.Union name tvars ctors ->
154+ addRest (D.Union name tvars ctors)
50155
51− D.Decl decl ->
52− validateDeclsHelp maybeComment decl decls
156+ D.Alias name tvars alias ->
157+ addRest (D.Alias name tvars alias)
158+
159+ D.Fixity assoc prec op ->
160+ addRest (D.Fixity assoc prec op)
161+
162+ D.Def def ->
163+ validateDeclsHelp maybeComment def rest
53164
54165
55166validateDeclsHelp
56− :: Maybe String
57− -> A.Located D.SourceDecl'
58− -> [D.SourceDecl]
59− -> Result.Result wrn Error.Error [D.ValidDecl]
60−validateDeclsHelp comment (A.A region decl) decls =
61− let addRest validDecl =
62− (:) (A.A (region, comment) validDecl)
63− <$> validateDecls Nothing decls
167+ :: Maybe (A.Located String)
168+ -> Source.Def
169+ -> [Commented D.Source']
170+ -> Result.Result wrn Error.Error [D.Valid]
171+validateDeclsHelp maybeComment (A.A region def) decls =
172+ let
173+ makeDef pat expr maybeType =
174+ D.Def (Valid.Definition pat expr maybeType)
175+
176+ ann =
177+ (region, fmap A.drop maybeComment)
64178 in
65− case decl of
66− D.Datatype name tvars ctors ->
67− addRest (D.Datatype name tvars ctors)
179+ case def of
180+ Source.Definition pat expr ->
181+ (:)
182+ <$> validateDef makeDef ann pat expr Nothing
183+ <*> validateDecls decls
184+
185+ Source.Annotation name tipe ->
186+ case decls of
187+ A.A (_, Just (A.A commentRegion _)) _ : _ ->
188+ Result.throw commentRegion (Error.CommentAfterAnnotation name)
68189
69− D.TypeAlias name tvars alias ->
70− addRest (D.TypeAlias name tvars alias)
190+ A.A _ (D.Def (A.A _ (Source.Definition pat expr))) : rest
191+ | Pattern.isVar name pat ->
192+ (:)
193+ <$> validateDef makeDef ann pat expr (Just tipe)
194+ <*> validateDecls rest
71195
72− D.Fixity assoc prec op ->
73− addRest (D.Fixity assoc prec op)
196+ _ ->
197+ Result.throw region (Error.TypeWithoutDefinition name)
74198
75− D.Definition def ->
76− defHelp comment def decls
77199
78200
201+-- VALIDATE EFFECTS
79202
80−-- VALIDATE DEFINITIONS IN DECLARATIONS
81203
204+validateEffects
205+ :: [Commented Source.Effect]
206+ -> Result.Result wrn Error.Error [A.Commented Valid.Effect]
207+validateEffects effects =
208+ case effects of
209+ [] ->
210+ Result.ok []
82211
83−defHelp
84− :: Maybe String
85− -> Source.Def
86− -> [D.SourceDecl]
87− -> Result.Result wrn Error.Error [D.ValidDecl]
88−defHelp comment (A.A region def) decls =
89− let addRest def' rest =
90− (:) (A.A (region, comment) (D.Definition def'))
91− <$> validateDecls Nothing rest
92− in
93− case def of
94− Source.Definition pat expr ->
95− do expr' <- expression expr
96− let def' = Valid.Definition pat expr' Nothing
97− checkDefinition def'
98− addRest def' decls
99−
100− Source.TypeAnnotation name tipe ->
101− case decls of
102− D.Decl (A.A _ (D.Definition (A.A _
103− (Source.Definition pat@(A.A _ (Pattern.Var name')) expr)))) : rest
104− | name == name' ->
105− do expr' <- expression expr
106− let def' = Valid.Definition pat expr' (Just tipe)
107− checkDefinition def'
108− addRest def' rest
212+ A.A (region, maybeComment) effect : rest ->
213+ validateEffectsHelp (region, fmap A.drop maybeComment) effect rest
109214
110− _ ->
111− Result.throw region (Error.TypeWithoutDefinition name)
215+
216+validateEffectsHelp
217+ :: (R.Region, Maybe String)
218+ -> Source.Effect
219+ -> [Commented Source.Effect]
220+ -> Result.Result wrn Error.Error [A.Commented Valid.Effect]
221+validateEffectsHelp ann effect remainingEffects =
222+ case effect of
223+ Source.With _ _ ->
224+ Result.throw (fst ann) (error "TODO")
225+
226+ Source.Def pat expr ->
227+ (:)
228+ <$> validateDef Valid.Def ann pat expr Nothing
229+ <*> validateEffects remainingEffects
230+
231+ Source.Type name tipe ->
232+ case remainingEffects of
233+ A.A (_, Just (A.A commentRegion _)) _ : _ ->
234+ Result.throw commentRegion (Error.CommentAfterAnnotation name)
235+
236+ A.A _ (Source.Def pat expr) : rest
237+ | Pattern.isVar name pat ->
238+ (:)
239+ <$> validateDef Valid.Def ann pat expr (Just tipe)
240+ <*> validateEffects rest
241+
242+ _ ->
243+ Result.throw (fst ann) (Error.TypeWithoutDefinition name)
112244
113245
114246
@@ -127,29 +259,40 @@ definitionsHelp :: [Source.Def] -> Result.Result wrn Error.Error [Valid.Def]
127259definitionsHelp sourceDefs =
128260 case sourceDefs of
129261 [] ->
130− return []
131−
132− A.A _ (Source.Definition pat expr) : rest ->
133− do expr' <- expression expr
134− let def = Valid.Definition pat expr' Nothing
135− checkDefinition def
136− (:) def <$> definitionsHelp rest
137−
138− A.A region (Source.TypeAnnotation name tipe) : rest ->
139− case rest of
140− A.A _ (Source.Definition pat@(A.A _ (Pattern.Var name')) expr) : rest'
141− | name == name' ->
142− do expr' <- expression expr
143− let def = Valid.Definition pat expr' (Just tipe)
144− checkDefinition def
145− (:) def <$> definitionsHelp rest'
146−
147− _ ->
148− Result.throw region (Error.TypeWithoutDefinition name)
149−
150−
151−checkDefinition :: Valid.Def -> Result.Result wrn Error.Error ()
152−checkDefinition (Valid.Definition pattern body _) =
262+ return []
263+
264+ A.A region (Source.Definition pat expr) : rest ->
265+ (:)
266+ <$> fmap A.drop (validateDef Valid.Definition region pat expr Nothing)
267+ <*> definitionsHelp rest
268+
269+ A.A r1 (Source.Annotation name tipe) : rest ->
270+ case rest of
271+ A.A r2 (Source.Definition pat expr) : rest'
272+ | Pattern.isVar name pat ->
273+ (:)
274+ <$> fmap A.drop (validateDef Valid.Definition (R.merge r1 r2) pat expr (Just tipe))
275+ <*> definitionsHelp rest'
276+
277+ _ ->
278+ Result.throw r1 (Error.TypeWithoutDefinition name)
279+
280+
281+validateDef
282+ :: (Pattern.Raw -> Valid.Expr -> Maybe Type.Raw -> def)
283+ -> annotation
284+ -> Pattern.Raw
285+ -> Source.Expr
286+ -> Maybe Type.Raw
287+ -> Result.Result wrn Error.Error (A.Annotated annotation def)
288+validateDef makeDef annotation pat expr maybeType =
289+ do validExpr <- expression expr
290+ validateDefPattern pat validExpr
291+ return $ A.A annotation (makeDef pat validExpr maybeType)
292+
293+
294+validateDefPattern :: Pattern.Raw -> Valid.Expr -> Result.Result wrn Error.Error ()
295+validateDefPattern pattern body =
153296 case fst (Expr.collectLambdas body) of
154297 [] ->
155298 return ()
@@ -265,7 +408,7 @@ both (expr1, expr2) =
265408-- VALIDATE PATTERNS
266409
267410
268−validatePattern :: Pattern.RawPattern -> Result.Result wrn Error.Error Pattern.RawPattern
411+validatePattern :: Pattern.Raw -> Result.Result wrn Error.Error Pattern.Raw
269412validatePattern pattern =
270413 do detectDuplicates Error.BadPattern (Pattern.boundVars pattern)
271414 return pattern
@@ -297,15 +440,13 @@ detectDuplicates tag names =
297440 F.traverse_ check (makeGroups names)
298441
299442
300−defDuplicates
301− :: [Pattern.RawPattern]
302− -> Result.Result wrn Error.Error ()
443+defDuplicates :: [Pattern.Raw] -> Result.Result wrn Error.Error ()
303444defDuplicates patterns =
304445 concatMap Pattern.boundVars patterns
305446 |> detectDuplicates Error.DuplicateDefinition
306447
307448
308−declDuplicates :: [D.ValidDecl] -> Result.Result wrn Error.Error ()
449+declDuplicates :: [D.Valid] -> Result.Result wrn Error.Error ()
309450declDuplicates decls =
310451 let (valueLists, typeLists) = unzip (map extractValues decls)
311452 in
@@ -314,25 +455,25 @@ declDuplicates decls =
314455 <*> detectDuplicates Error.DuplicateTypeDeclaration (concat typeLists)
315456
316457
317−extractValues :: D.ValidDecl -> ([A.Located String], [A.Located String])
458+extractValues :: D.Valid -> ([A.Located String], [A.Located String])
318459extractValues (A.A (region, _) decl) =
319460 case decl of
320− D.Definition (Valid.Definition pattern _ _) ->
461+ D.Def (Valid.Definition pattern _ _) ->
321462 ( Pattern.boundVars pattern
322463 , []
323464 )
324465
325− D.Datatype name _ ctors ->
466+ D.Union name _ ctors ->
326467 ( map (A.A region . fst) ctors
327468 , [A.A region name]
328469 )
329470
330− D.TypeAlias name _ (A.A _ (Type.RRecord _ _)) ->
471+ D.Alias name _ (A.A _ (Type.RRecord _ _)) ->
331472 ( [A.A region name]
332473 , [A.A region name]
333474 )
334475
335− D.TypeAlias name _ _ ->
476+ D.Alias name _ _ ->
336477 ( []
337478 , [A.A region name]
338479 )
@@ -347,13 +488,13 @@ extractValues (A.A (region, _) decl) =
347488-- UNBOUND TYPE VARIABLES
348489
349490
350−checkDecl :: D.ValidDecl -> Result.Result wrn Error.Error ()
491+checkDecl :: D.Valid -> Result.Result wrn Error.Error ()
351492checkDecl (A.A (region,_) decl) =
352493 case decl of
353− D.Definition _ ->
494+ D.Def _ ->
354495 return ()
355496
356− D.Datatype name boundVars ctors ->
497+ D.Union name boundVars ctors ->
357498 case diff boundVars (concatMap freeVars (concatMap snd ctors)) of
358499 (_, []) ->
359500 return ()
@@ -362,7 +503,7 @@ checkDecl (A.A (region,_) decl) =
362503 Result.throw region
363504 (Error.UnboundTypeVarsInUnion name boundVars unbound)
364505
365− D.TypeAlias name boundVars tipe ->
506+ D.Alias name boundVars tipe ->
366507 case diff boundVars (freeVars tipe) of
367508 ([], []) ->
368509 return ()
@@ -400,20 +541,20 @@ diff left right =
400541
401542freeVars :: Type.Raw -> [A.Located String]
402543freeVars (A.A region tipe) =
403− case tipe of
404− Type.RLambda t1 t2 ->
405− freeVars t1 ++ freeVars t2
544+ case tipe of
545+ Type.RLambda t1 t2 ->
546+ freeVars t1 ++ freeVars t2
406547
407− Type.RVar x ->
408− [A.A region x]
548+ Type.RVar x ->
549+ [A.A region x]
409550
410− Type.RType _ ->
411− []
551+ Type.RType _ ->
552+ []
412553
413− Type.RApp t ts ->
414− concatMap freeVars (t:ts)
554+ Type.RApp t ts ->
555+ concatMap freeVars (t:ts)
415556
416− Type.RRecord fields ext ->
417− maybe [] freeVars ext
418− ++ concatMap (freeVars . snd) fields
557+ Type.RRecord fields ext ->
558+ maybe [] freeVars ext
559+ ++ concatMap (freeVars . snd) fields
419560