on 2aa7dcd help sign in
elk/src/Parse/Module.hs
102 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
11getModuleName :: String -> Maybe String
12getModuleName source =
13 case iParse getModuleName source of
14 Right name -> Just name
15 Left _ -> Nothing
16 where
17 getModuleName =
18 do optional freshLine
19 (names, _) <- moduleDecl
20 return (Module.nameToString names)
23header :: IParser (Module.Header [Module.UserImport])
24header =
25 do optional freshLine
26 (names, exports) <-
27 option (["Main"], Var.openListing) (moduleDecl `followedBy` freshLine)
28 imports' <- imports
29 return (Module.Header names exports imports')
32moduleDecl :: IParser ([String], Var.Listing Var.Value)
33moduleDecl =
34 do try (reserved "module")
35 whitespace
36 names <- dotSep1 capVar <?> "name of module"
37 whitespace
38 exports <- option Var.openListing (listing value)
39 whitespace <?> "reserved word 'where'"
40 reserved "where"
41 return (names, exports)
44imports :: IParser [Module.UserImport]
45imports =
46 many (import' `followedBy` freshLine)
49import' :: IParser Module.UserImport
50import' =
51 addLocation $
52 do try (reserved "import")
53 whitespace
54 names <- dotSep1 capVar
55 (,) names <$> method (Module.nameToString names)
56 where
57 method :: String -> IParser Module.ImportMethod
58 method defaultAlias =
59 Module.ImportMethod
60 <$> option (Just defaultAlias) (Just <$> as')
61 <*> option Var.closedListing exposing
63 as' :: IParser String
64 as' =
65 do try (whitespace >> reserved "as")
66 whitespace
67 capVar <?> "alias for module"
69 exposing :: IParser (Var.Listing Var.Value)
70 exposing =
71 do try (whitespace >> reserved "exposing")
72 whitespace
73 listing value
76listing :: IParser a -> IParser (Var.Listing a)
77listing item =
78 do try (whitespace >> char '(')
79 whitespace
80 listing <-
81 choice
82 [ const Var.openListing <$> string ".."
83 , Var.Listing <$> commaSep1 item <*> return False
84 ] <?> "listing of values (x,y,z)"
85 whitespace
86 char ')'
87 return listing
90value :: IParser Var.Value
91value =
92 val <|> tipe
93 where
94 val =
95 Var.Value <$> (lowVar <|> parens symOp)
97 tipe =
98 do name <- capVar
99 maybeCtors <- optionMaybe (listing capVar)
100 case maybeCtors of
101 Nothing -> return (Var.Alias name)
102 Just ctors -> return (Var.Union name ctors)