on fa264dd help sign in
elk/src/Parse/Module.hs
88 lines 2.7 kB history raw
1module Parse.Module (header, headerAndImports, getModuleName) where
3import Control.Applicative ((<$>), (<*>))
4import Data.List (intercalate)
5import Text.Parsec hiding (newline, spaces)
7import Parse.Helpers
8import qualified AST.Module as Module
9import 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 = do
18 optional freshLine
19 (names, _) <- header
20 return (intercalate "." names)
22headerAndImports :: IParser Module.HeaderAndImports
23headerAndImports =
24 do optional freshLine
25 (names, exports) <-
26 option (["Main"], Var.openListing) (header `followedBy` freshLine)
27 imports' <- commitToImports <|> return []
28 return $ Module.HeaderAndImports names exports imports'
29 where
30 commitToImports =
31 do try (lookAhead $ reserved "import")
32 imports `followedBy` freshLine
34header :: IParser ([String], Var.Listing Var.Value)
35header = do
36 try (reserved "module")
37 whitespace
38 names <- dotSep1 capVar <?> "name of module"
39 whitespace
40 exports <- option Var.openListing (listing value)
41 whitespace <?> "reserved word 'where'"
42 reserved "where"
43 return (names, exports)
45imports :: IParser [(Module.Name, Module.ImportMethod)]
46imports = option [] ((:) <$> import' <*> many (try (freshLine >> import')))
48import' :: IParser (Module.Name, Module.ImportMethod)
49import' =
50 do reserved "import"
51 whitespace
52 names <- dotSep1 capVar
53 (,) names <$> option (Module.As (intercalate "." names)) method
54 where
55 method :: IParser Module.ImportMethod
56 method = as' <|> importing'
58 as' :: IParser Module.ImportMethod
59 as' = do
60 try (whitespace >> reserved "as")
61 whitespace
62 Module.As <$> capVar <?> "alias for module"
64 importing' :: IParser Module.ImportMethod
65 importing' = Module.Open <$> listing value
67listing :: IParser a -> IParser (Var.Listing a)
68listing item =
69 do try (whitespace >> char '(')
70 whitespace
71 listing <- choice [ const Var.openListing <$> string ".."
72 , Var.Listing <$> commaSep1 item <*> return False
73 ] <?> "listing of values (x,y,z)"
74 whitespace
75 char ')'
76 return listing
78value :: IParser Var.Value
79value = val <|> tipe
80 where
81 val = Var.Value <$> (lowVar <|> parens symOp)
83 tipe = do
84 name <- capVar
85 maybeCtors <- optionMaybe (listing capVar)
86 case maybeCtors of
87 Nothing -> return (Var.Alias name)
88 Just ctors -> return (Var.ADT name ctors)