elm/compiler/Parse/Parser.hs

52 lines
1.7 KiB
Haskell
Raw Normal View History

module Parse.Parser (parseProgram, preParse) where
2012-04-19 06:32:10 +00:00
import Ast
import Control.Applicative ((<$>), (<*>))
import Control.Monad
import Data.Char (isSymbol, isDigit)
import Data.List (foldl',intercalate)
import Text.Parsec hiding (newline,spaces)
import Parse.Library
import Parse.Expr
2012-11-23 04:24:20 +00:00
import Parse.Types
import Parse.Modules
import Parse.Foreign
statement = choice (typeAlias:defs) <|> def <?> "datatype or variable definition"
where defs = map ((:[]) <$>) [ foreignDef, datatype ]
freshDef = commitIf (freshLine >> (letter <|> char '_')) $ do
freshLine
statement <?> "another datatype or variable definition"
2012-04-19 06:32:10 +00:00
defs1 = do d <- statement <?> "at least one datatype or variable definition"
concat <$> (d:) <$> many freshDef
program = do
optional freshLine
(names,exports) <- option (["Main"],[]) (moduleDef `followedBy` freshLine)
is <- (do try (lookAhead $ reserved "import")
imports `followedBy` freshLine) <|> return []
statements <- defs1
optional freshLine ; optional spaces ; eof
return $ Module names exports is statements
2012-04-19 06:32:10 +00:00
parseProgram = setupParser program
preParse :: String -> Either String (String, [String])
preParse = setupParser $ do
optional skip
(,) <$> option "Main" moduleName <*> option [] imprts
where
skip = try (manyTill anyChar (try (string "/**")))
imprts = fmap (map fst) imports `followedBy` freshLine
getName = intercalate "." . fst
moduleName = do optional freshLine
getName <$> moduleDef `followedBy` freshLine
setupParser p source =
case iParse p "" source of
Right result -> Right result
Left err -> Left $ "Parse error at " ++ show err