@@ -1,100 +1,151 @@
1{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
1{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
2+{-# LANGUAGE OverloadedStrings #-}
2module Parse.Declaration where
3module Parse.Declaration where
4−import Text.Parsec ( (<?>), choice, digit, optionMaybe, string, try )
5+import Data.Text (Text)
6import qualified AST.Declaration as Decl
7import qualified AST.Declaration as Decl
7−import qualified Parse.Binop as Binop
8+import qualified AST.Type as Type
8import qualified Parse.Expression as Expr
9import qualified Parse.Expression as Expr
9import Parse.Helpers as Help
10import Parse.Helpers as Help
10import qualified Parse.Type as Type
11import qualified Parse.Type as Type
12+import qualified Reporting.Annotation as A
13+import qualified Reporting.Region as R
14−declaration :: IParser Decl.Source
20+declaration :: SParser Decl.Source
15declaration =
21declaration =
16− commentOr $ addLocation $
22+ do start <- getPosition
18− [ typeDecl
25+ , typeDecl start
19− , infixDecl
26+ , infixDecl start
20− , portDecl
27+ , portDecl start
21− , definition
28+ , defDecl start
25−commentOr :: IParser a -> IParser (Decl.CommentOr a)
32+
26−commentOr parser =
33+-- DOC COMMENTS
28− [ Decl.Comment <$> addLocation Help.docComment
29− , Decl.Whatever <$> parser
36+docDecl :: R.Position -> SParser Decl.Source
38+ do comment <- docComment
41+ return ( Decl.Comment (A.at start end comment), end, space )
34-- TYPE ANNOTATIONS and DEFINITIONS
44-- TYPE ANNOTATIONS and DEFINITIONS
37−definition :: IParser Decl.Raw
47+defDecl :: R.Position -> SParser Decl.Source
38−definition =
48+defDecl start =
39− do def <- Expr.def <?> "a definition or type annotation"
49+ do (def, end, space) <- Expr.definition
40− return $ Decl.Def def
50+ let decl = A.at start end (Decl.Def def)
51+ return ( Decl.Whatever decl, end, space )
44-- TYPE ALIAS and UNION TYPES
55-- TYPE ALIAS and UNION TYPES
47−typeDecl :: IParser Decl.Raw
58+typeDecl :: R.Position -> SParser Decl.Source
48−typeDecl =
59+typeDecl start =
49− do try (reserved "type") <?> "a type declaration"
60+ do keyword "type"
51− isAlias <- optionMaybe (string "alias" >> forcedWS)
62+ oneOf
52−
63+ [ do keyword "alias"
65+ (name, args) <- nameArgsEquals
66+ (tipe, end, space) <- Type.expression
67+ let decl = A.at start end (Decl.Alias (Decl.Type name args tipe))
68+ return ( Decl.Whatever decl, end, space )
69+ , do (name, args) <- nameArgsEquals
70+ (firstCtor, firstEnd, firstSpace) <- Type.unionConstructor
71+ (ctors, end, space) <- chompConstructors [firstCtor] firstEnd firstSpace
72+ let decl = A.at start end (Decl.Union (Decl.Type name args ctors))
73+ return ( Decl.Whatever decl, end, space )
77+nameArgsEquals :: Parser (Text, [Text])
53− name <- capVar
79+ do name <- capVar
54− args <- spacePrefix lowVar
80+ spaces
81+ nameArgsEqualsHelp name []
84+nameArgsEqualsHelp :: Text -> [Text] -> Parser (Text, [Text])
85+nameArgsEqualsHelp name args =
89+ nameArgsEqualsHelp name (arg:args)
55− padded equals
90+ , do equals
92+ return ( name, reverse args )
59− do tipe <- Type.expr <?> "a type"
60− return $ Decl.Alias (Decl.Type name args tipe)
62− Nothing ->
96+chompConstructors :: [(Text, [Type.Raw])] -> R.Position -> Space -> SParser [(Text, [Type.Raw])]
63− do tcs <- pipeSep1 Type.constructor <?> "a constructor for a union type"
97+chompConstructors ctors end space =
64− return $ Decl.Union (Decl.Type name args tcs)
98+ oneOf
99+ [ do checkSpaces space
102+ (ctor, newEnd, newSpace) <- Type.unionConstructor
103+ chompConstructors (ctor:ctors) newEnd newSpace
104+ , return ( reverse ctors, end, space )
71−infixDecl :: IParser Decl.Raw
112+infixDecl :: R.Position -> SParser Decl.Source
72−infixDecl =
113+infixDecl start =
73− expecting "an infix declaration" $
114+ oneOf
74− do assoc <-
115+ [ do keyword "infixl"
75− choice
116+ infixDeclHelp start Decl.L
76− [ try (reserved "infixl") >> return Decl.L
117+ , do keyword "infixr"
77− , try (reserved "infixr") >> return Decl.R
118+ infixDeclHelp start Decl.R
78− , try (reserved "infix") >> return Decl.N
119+ , do keyword "infix"
120+ infixDeclHelp start Decl.N
124+infixDeclHelp :: R.Position -> Decl.Assoc -> SParser Decl.Source
125+infixDeclHelp start assoc =
81 n <- digit
127 n <- digit
83− op <- Binop.infixOp
129+ op <- infixOp
84− return $ Decl.Fixity (Decl.Infix op assoc (read [n]))
132+ let decl = A.at start end (Decl.Fixity (Decl.Infix op assoc n))
133+ return ( Decl.Whatever decl, end, space )
88-- FOREIGN
137-- FOREIGN
91−portDecl :: IParser Decl.Raw
140+portDecl :: R.Position -> SParser Decl.Source
92−portDecl =
141+portDecl start =
93− expecting "a port declaration" $
94− do try (reserved "port")
142+ do keyword "port"
96− name <- Help.lowVar
144+ name <- lowVar
97− padded hasType
146+ hasType
98− tipe <- Type.expr
148+ (tipe, end, space) <- Type.expression
99− return $ Decl.Port name tipe
149+ let decl = A.at start end (Decl.Port name tipe)
150+ return ( Decl.Whatever decl, end, space )