Elm-0.13: compiler/Parse/Module.hs
module Parse.Module (moduleDef, getModuleName, imports) where
import Control.Applicative ((<$>), (<*>))
import Data.List (intercalate)
import Text.Parsec hiding (newline,spaces)
import Parse.Helpers
import AST.Module (ImportMethod(..))
import AST.Variable (Listing(..), Value(..), openListing)
getModuleName :: String -> Maybe String
getModuleName source =
case iParse getModuleName source of
Right name -> Just name
Left _ -> Nothing
where
getModuleName = do
optional freshLine
(names, _) <- moduleDef
return (intercalate "." names)
moduleDef :: IParser ([String], Listing Value)
moduleDef = do
try (reserved "module")
whitespace
names <- dotSep1 capVar <?> "name of module"
whitespace
exports <- option (Listing [] True) (listing value)
whitespace <?> "reserved word 'where'"
reserved "where"
return (names, exports)
imports :: IParser [(String, ImportMethod)]
imports = option [] ((:) <$> import' <*> many (try (freshLine >> import')))
import' :: IParser (String, ImportMethod)
import' =
do reserved "import"
whitespace
name <- intercalate "." <$> dotSep1 capVar
(,) name <$> option (As name) method
where
method :: IParser ImportMethod
method = as' <|> importing'
as' :: IParser ImportMethod
as' = do
try (whitespace >> reserved "as")
whitespace
As <$> capVar <?> "alias for module"
importing' :: IParser ImportMethod
importing' = Open <$> listing value
listing :: IParser a -> IParser (Listing a)
listing item =
do try (whitespace >> char '(')
whitespace
listing <- choice [ const openListing <$> string ".."
, Listing <$> commaSep1 item <*> return False
] <?> "listing of values (x,y,z)"
whitespace
char ')'
return listing
value :: IParser Value
value = val <|> tipe
where
val = Value <$> (lowVar <|> parens symOp)
tipe = do
name <- capVar
maybeCtors <- optionMaybe (listing capVar)
case maybeCtors of
Nothing -> return (Alias name)
Just ctors -> return (ADT name ctors)