on 54dfb21 help sign in
elk/src/Parse/Declaration.hs
90 lines 2.2 kB history raw
1{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
2module Parse.Declaration where
4import Text.Parsec ( (<|>), (<?>), choice, digit, optionMaybe, string, try )
6import qualified AST.Declaration as D
7import qualified Parse.Expression as Expr
8import Parse.Helpers as Help
9import qualified Parse.Type as Type
12declaration :: IParser D.SourceDecl
13declaration =
14 choice
15 [ D.Comment <$> Help.docComment
16 , D.Decl <$> addLocation (typeDecl <|> infixDecl <|> port <|> definition)
17 ]
20-- TYPE ANNOTATIONS and DEFINITIONS
22definition :: IParser D.SourceDecl'
23definition =
24 D.Definition
25 <$> (Expr.typeAnnotation <|> Expr.definition)
26 <?> "a value definition"
29-- TYPE ALIAS and UNION TYPES
31typeDecl :: IParser D.SourceDecl'
32typeDecl =
33 do try (reserved "type") <?> "a type declaration"
34 forcedWS
35 isAlias <- optionMaybe (string "alias" >> forcedWS)
37 name <- capVar
38 args <- spacePrefix lowVar
39 padded equals
41 case isAlias of
42 Just _ ->
43 do tipe <- Type.expr <?> "a type"
44 return (D.TypeAlias name args tipe)
46 Nothing ->
47 do tcs <- pipeSep1 Type.constructor <?> "a constructor for a union type"
48 return $ D.Datatype name args tcs
51-- INFIX
53infixDecl :: IParser D.SourceDecl'
54infixDecl =
55 expecting "an infix declaration" $
56 do assoc <-
57 choice
58 [ try (reserved "infixl") >> return D.L
59 , try (reserved "infixr") >> return D.R
60 , try (reserved "infix") >> return D.N
61 ]
62 forcedWS
63 n <- digit
64 forcedWS
65 D.Fixity assoc (read [n]) <$> anyOp
68-- PORT
70port :: IParser D.SourceDecl'
71port =
72 expecting "a port declaration" $
73 do try (reserved "port")
74 whitespace
75 name <- lowVar
76 whitespace
77 choice [ portAnnotation name, portDefinition name ]
78 where
79 portAnnotation name =
80 do try hasType
81 whitespace
82 tipe <- Type.expr <?> "a type"
83 return (D.Port (D.PortAnnotation name tipe))
85 portDefinition name =
86 do try equals
87 whitespace
88 expr <- Expr.expr
89 return (D.Port (D.PortDefinition name expr))