on ea343fc help sign in
elk/src/Parse/Module.hs
106 lines 2.9 kB history raw
1module Parse.Module (moduleDecl, header, getModuleName) where
3import Control.Applicative ((<$>), (<*>))
4import Text.Parsec hiding (newline, spaces)
6import Parse.Helpers
7import qualified AST.Module as Module
8import qualified AST.Variable as Var
9import Reporting.Annotation as A
12getModuleName :: String -> Maybe String
13getModuleName source =
14 case iParse getModuleName source of
15 Right name -> Just name
16 Left _ -> Nothing
17 where
18 getModuleName =
19 do optional freshLine
20 (names, _) <- moduleDecl
21 return (Module.nameToString names)
24header :: IParser (Module.Header [Module.UserImport])
25header =
26 do optional freshLine
27 (names, exports) <-
28 option (["Main"], Var.openListing) (moduleDecl `followedBy` freshLine)
29 imports' <- imports
30 return (Module.Header names exports imports')
33moduleDecl :: IParser ([String], Var.Listing (A.Located Var.Value))
34moduleDecl =
35 expecting "a module declaration" $
36 do try (reserved "module")
37 whitespace
38 names <- dotSep1 capVar <?> "the name of this module"
39 whitespace
40 exports <- option Var.openListing (listing (addLocation value))
41 whitespace
42 reserved "where"
43 return (names, exports)
46imports :: IParser [Module.UserImport]
47imports =
48 many (import' `followedBy` freshLine)
51import' :: IParser Module.UserImport
52import' =
53 expecting "an import" $
54 addLocation $
55 do try (reserved "import")
56 whitespace
57 names <- dotSep1 capVar
58 (,) names <$> method (Module.nameToString names)
59 where
60 method :: String -> IParser Module.ImportMethod
61 method defaultAlias =
62 Module.ImportMethod
63 <$> option (Just defaultAlias) (Just <$> as' defaultAlias)
64 <*> option Var.closedListing exposing
66 as' :: String -> IParser String
67 as' moduleName =
68 do try (whitespace >> reserved "as")
69 whitespace
70 capVar <?> ("an alias for module '" ++ moduleName ++ "'")
72 exposing :: IParser (Var.Listing Var.Value)
73 exposing =
74 do try (whitespace >> reserved "exposing")
75 whitespace
76 listing value
79listing :: IParser a -> IParser (Var.Listing a)
80listing item =
81 expecting "a listing of values to expose, like (..)" $
82 do try (whitespace >> char '(')
83 whitespace
84 listing <-
85 choice
86 [ const Var.openListing <$> string ".."
87 , Var.Listing <$> commaSep1 item <*> return False
88 ]
89 whitespace
90 char ')'
91 return listing
94value :: IParser Var.Value
95value =
96 val <|> tipe <?> "a value to expose"
97 where
98 val =
99 Var.Value <$> (lowVar <|> parens symOp)
101 tipe =
102 do name <- capVar
103 maybeCtors <- optionMaybe (listing capVar)
104 case maybeCtors of
105 Nothing -> return (Var.Alias name)
106 Just ctors -> return (Var.Union name ctors)