1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Validate (Result, validate) where
5import Control.Applicative (liftA2)
6import Control.Monad (forM_)
7import qualified Data.Map as Map
10import qualified AST.Expression.Source as Src
11import qualified AST.Expression.Valid as Valid
12import qualified AST.Pattern as Pattern
13import qualified AST.Type as Type
14import qualified Elm.Name as N
15import qualified Reporting.Annotation as A
16import qualified Reporting.Error.Syntax as Error
17import qualified Reporting.Region as R
18import qualified Reporting.Result as Result
26type Result warning a =
27 Result.Result () warning Error.Error a
30validate :: Src.Module [Src.Decl] -> Result w Valid.Module
31validate (Src.Module name srcEffects overview exports imports srcDecls) =
32 do (Stuff decls unions aliases binops ports docs) <- validateDecls srcDecls
33 effects <- validateEffects srcEffects ports
34 return $ Valid.Module name overview docs exports imports decls unions aliases binops effects
38-- VALIDATE DECLARATIONS
43 { _decls :: [Valid.Decl]
44 , _unions :: [Valid.Union]
45 , _aliases :: [Valid.Alias]
46 , _binops :: [Valid.Binop]
47 , _ports :: [Valid.Port]
48 , _docs :: Map.Map N.Name Text
52validateDecls :: [Src.Decl] -> Result w Stuff
54 vsdHelp decls (Stuff [] [] [] [] [] Map.empty)
57vsdHelp :: [Src.Decl] -> Stuff -> Result w Stuff
63 A.A _ decl : otherDecls ->
65 Src.Union name tvars ctors ->
66 do let union = Valid.Union name tvars ctors
67 vsdHelp otherDecls $ stuff { _unions = union : _unions stuff }
69 Src.Alias name tvars tipe ->
70 do let alias = Valid.Alias name tvars tipe
71 vsdHelp otherDecls $ stuff { _aliases = alias : _aliases stuff }
73 Src.Binop op assoc prec val ->
74 do let binop = Valid.Binop op assoc prec val
75 vsdHelp otherDecls $ stuff { _binops = binop : _binops stuff }
78 do let port_ = Valid.Port name tipe
79 vsdHelp otherDecls $ stuff { _ports = port_ : _ports stuff }
82 validateDocs docs otherDecls stuff
84 Src.Annotation (A.A _ name) tipe ->
85 validateAnnotation name tipe otherDecls stuff
87 Src.Definition name args body ->
88 do validBody <- expression body
89 let validDecl = Valid.Decl name args validBody Nothing
90 vsdHelp otherDecls $ stuff { _decls = validDecl : _decls stuff }
97validateDocs :: Text -> [Src.Decl] -> Stuff -> Result w Stuff
98validateDocs docs decls stuff =
101 error "TODO no docs on nothing"
104 do name <- getNameForDocs decl
105 vsdHelp decls $ stuff { _docs = Map.insert name docs (_docs stuff) }
108getNameForDocs :: Src.Decl_ -> Result w N.Name
111 Src.Union (A.A _ name) _ _ ->
114 Src.Alias (A.A _ name) _ _ ->
118 error "TODO no docs on binop"
121 error "TODO no docs on ports"
124 error "TODO no docs on docs"
126 Src.Annotation (A.A _ name) _ ->
129 Src.Definition (A.A _ name) _ _ ->
134-- VALIDATE ANNOTATION
137validateAnnotation :: N.Name -> Type.Raw -> [Src.Decl] -> Stuff -> Result w Stuff
138validateAnnotation annotationName tipe decls stuff =
141 error "TODO no attotations on nothing"
143 A.A _ decl : otherDecls ->
145 Src.Definition name@(A.A _ definitionName) args body ->
146 if annotationName == definitionName then
147 do validBody <- expression body
148 let validDecl = Valid.Decl name args validBody (Just tipe)
149 vsdHelp otherDecls $ stuff { _decls = validDecl : _decls stuff }
152 error "TODO annotation does not match following definition"
155 error "TODO annotation needs to be on a definition"
159-- VALIDATE EXPRESSIONS
162expression :: Src.Expr -> Result w Valid.Expr
163expression (A.A region sourceExpression) =
165 case sourceExpression of
166 Src.Var prefix name ->
167 pure (Valid.Var prefix name)
169 Src.Lambda pattern body ->
170 Valid.Lambda pattern <$> expression body
176 Valid.Negate <$> expression expr
178 Src.Binops ops lastExpr ->
180 <$> traverse (\(expr,op) -> (,) <$> expression expr <*> pure op) ops
181 <*> expression lastExpr
183 Src.Case expr branches ->
186 <*> traverse (traverse expression) branches
189 pure (Valid.Literal lit)
192 Valid.List <$> traverse expression exprs
194 Src.Call func args ->
197 <*> traverse expression args
199 Src.If branches finally ->
201 <$> traverse both branches
202 <*> expression finally
204 Src.Accessor field ->
205 pure (Valid.Accessor field)
207 Src.Access record field ->
209 <$> expression record
212 Src.Update record fields ->
213 Valid.Update record <$> traverse (traverse expression) fields
216 Valid.Record <$> traverse (traverse expression) fields
225 <*> traverse expression cs
232 Src.GLShader uid src gltipe ->
233 pure (Valid.GLShader uid src gltipe)
236both :: (Src.Expr, Src.Expr) -> Result w (Valid.Expr, Valid.Expr)
238 liftA2 (,) (expression a) (expression b)
242-- VALIDATE DEFINITIONS
245definitions :: [A.Located Src.Def] -> Result w [Valid.Def]
246definitions sourceDefs =
251 A.A region (Src.Destruct pattern expr) : otherDefs ->
253 <$> validateDestruct region pattern expr
254 <*> definitions otherDefs
256 A.A region (Src.Define name args expr) : otherDefs ->
258 <$> validateDefinition region name args expr Nothing
259 <*> definitions otherDefs
261 A.A annRegion (Src.Annotate annotationName tipe) : otherDefs ->
263 A.A defRegion (Src.Define name args expr) : otherOtherDefs | name == annotationName ->
265 <$> validateDefinition (R.merge annRegion defRegion) name args expr (Just tipe)
266 <*> definitions otherOtherDefs
269 Result.throw annRegion (Error.TypeWithoutDefinition annotationName)
272validateDefinition :: R.Region -> Text -> [Pattern.Raw] -> Src.Expr -> Maybe Type.Raw -> Result w Valid.Def
273validateDefinition region name args expr maybeType =
274 do validExpr <- expression expr
275 return $ Valid.Define region name args validExpr maybeType
278validateDestruct :: R.Region -> Pattern.Raw -> Src.Expr -> Result w Valid.Def
279validateDestruct region pattern expr =
280 Valid.Destruct region pattern <$> expression expr
287validateEffects :: Src.Effects -> [Valid.Port] -> Result w Valid.Effects
288validateEffects effects ports =
292 return Valid.NoEffects
295 return (Valid.Ports ports)
297 Src.Effects _ manager ->
301 return (Valid.Cmd cmd)
304 return (Valid.Sub sub)
307 return (Valid.Fx cmd sub)
310noPorts :: [Valid.Port] -> Result w ()
312 forM_ ports $ \(Valid.Port (A.A region name) _) ->
313 Result.throw region (Error.UnexpectedPort name)
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