Elm-0.3.5: src/Parse/Parser.hs
module Parser (parseProgram) where
import Ast
import Control.Applicative ((<$>), (<*>))
import Control.Monad
import Data.Char (isSymbol, isDigit)
import Data.List (foldl')
import Text.Parsec hiding (newline,spaces)
import ParseLib
import ParseExpr
import ParseTypes
import ParseModules
import ParseForeign
freshDef = commitIf (freshLine >> (letter <|> char '_')) $ do
freshLine
datatype <|> def <?> "another datatype or variable definition"
defs1 = do d <- datatype <|> def <?> "at least one datatype or variable definition"
(d:) <$> many freshDef
defs = do
(fss,ess,tss) <- unzip3 <$> defs1
return (concat fss, concat ess, concat `liftM` sequence tss)
program = do
optional freshLine
(names,exports) <- option (["Main"],[]) (moduleDef `followedBy` freshLine)
is <- (do try (lookAhead $ reserved "import")
imports `followedBy` freshLine) <|> return []
jsffi <- foreignDefs `followedBy` freshLine <|> return ([],[])
(vs,es,ts) <- defs
optional freshLine ; optional spaces ; eof
return (Module names exports is (zip vs es) jsffi, zip vs `liftM` ts)
parseProgram source =
case parse program "" source of
Right result -> Right result
Left err -> Left $ "Parse error at " ++ show err