on d5da02e help sign in
elk/src/Parse/Module.hs
103 lines 2.7 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 do try (reserved "module")
36 whitespace
37 names <- dotSep1 capVar <?> "name of module"
38 whitespace
39 exports <- option Var.openListing (listing (addLocation value))
40 whitespace <?> "reserved word 'where'"
41 reserved "where"
42 return (names, exports)
45imports :: IParser [Module.UserImport]
46imports =
47 many (import' `followedBy` freshLine)
50import' :: IParser Module.UserImport
51import' =
52 addLocation $
53 do try (reserved "import")
54 whitespace
55 names <- dotSep1 capVar
56 (,) names <$> method (Module.nameToString names)
57 where
58 method :: String -> IParser Module.ImportMethod
59 method defaultAlias =
60 Module.ImportMethod
61 <$> option (Just defaultAlias) (Just <$> as')
62 <*> option Var.closedListing exposing
64 as' :: IParser String
65 as' =
66 do try (whitespace >> reserved "as")
67 whitespace
68 capVar <?> "alias for module"
70 exposing :: IParser (Var.Listing Var.Value)
71 exposing =
72 do try (whitespace >> reserved "exposing")
73 whitespace
74 listing value
77listing :: IParser a -> IParser (Var.Listing a)
78listing item =
79 do try (whitespace >> char '(')
80 whitespace
81 listing <-
82 choice
83 [ const Var.openListing <$> string ".."
84 , Var.Listing <$> commaSep1 item <*> return False
85 ] <?> "listing of values (x,y,z)"
86 whitespace
87 char ')'
88 return listing
91value :: IParser Var.Value
92value =
93 val <|> tipe
94 where
95 val =
96 Var.Value <$> (lowVar <|> parens symOp)
98 tipe =
99 do name <- capVar
100 maybeCtors <- optionMaybe (listing capVar)
101 case maybeCtors of
102 Nothing -> return (Var.Alias name)
103 Just ctors -> return (Var.Union name ctors)