on da476ff help sign in
elk/src/Parse/Module.hs
96 lines 2.6 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
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, _) <- header
21 return (intercalate "." names)
24headerAndImports :: IParser Module.HeaderAndImports
25headerAndImports =
26 do optional freshLine
27 (names, exports) <-
28 option (["Main"], Var.openListing) (header `followedBy` freshLine)
29 imports' <- imports
30 return $ Module.HeaderAndImports names exports imports'
33header :: IParser ([String], Var.Listing Var.Value)
34header =
35 do try (reserved "module")
36 whitespace
37 names <- dotSep1 capVar <?> "name of module"
38 whitespace
39 exports <- option Var.openListing (listing value)
40 whitespace <?> "reserved word 'where'"
41 reserved "where"
42 return (names, exports)
45imports :: IParser [(Module.Name, Module.ImportMethod)]
46imports =
47 many (import' `followedBy` freshLine)
50import' :: IParser (Module.Name, Module.ImportMethod)
51import' =
52 do try (reserved "import")
53 whitespace
54 names <- dotSep1 capVar
55 (,) names <$> option (Module.As (intercalate "." names)) method
56 where
57 method :: IParser Module.ImportMethod
58 method = as' <|> importing'
60 as' :: IParser Module.ImportMethod
61 as' = do
62 try (whitespace >> reserved "as")
63 whitespace
64 Module.As <$> capVar <?> "alias for module"
66 importing' :: IParser Module.ImportMethod
67 importing' = Module.Open <$> listing value
70listing :: IParser a -> IParser (Var.Listing a)
71listing item =
72 do try (whitespace >> char '(')
73 whitespace
74 listing <-
75 choice
76 [ const Var.openListing <$> string ".."
77 , Var.Listing <$> commaSep1 item <*> return False
78 ] <?> "listing of values (x,y,z)"
79 whitespace
80 char ')'
81 return listing
84value :: IParser Var.Value
85value =
86 val <|> tipe
87 where
88 val =
89 Var.Value <$> (lowVar <|> parens symOp)
91 tipe =
92 do name <- capVar
93 maybeCtors <- optionMaybe (listing capVar)
94 case maybeCtors of
95 Nothing -> return (Var.Alias name)
96 Just ctors -> return (Var.Union name ctors)