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 statement = (:[]) <$> foreignDef <|> (:[]) <$> datatype <|> def "datatype or variable definition" freshDef = commitIf (freshLine >> (letter <|> char '_')) $ do freshLine statement "another datatype or variable definition" 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 parseProgram source = case parse program "" source of Right result -> Right result Left err -> Left $ "Parse error at " ++ show err