git.iko.soy/rowtype-yoga/purescript-native
on 79aaba9 help sign in
63 lines 2.2 kB history raw
1-----------------------------------------------------------------------------
2--
3-- Module : PureScript.Parser.Declarations
4-- Copyright : (c) Phil Freeman 2013
5-- License : MIT
6--
7-- Maintainer : Phil Freeman <paf31@cantab.net>
8-- Stability : experimental
9-- Portability :
10--
11-- |
12--
13-----------------------------------------------------------------------------
15module PureScript.Parser.Declarations (
16 parseDeclaration,
17 parseDeclarations
18) where
20import Data.Char
21import Data.List
22import Data.Function
23import Control.Applicative
24import qualified Text.Parsec as P
25import Control.Arrow (Arrow(..))
27import PureScript.Values
28import PureScript.Types
29import PureScript.Parser.Common
30import PureScript.Declarations
31import PureScript.Parser.Values
32import PureScript.Parser.Types
34parseDataDeclaration :: P.Parsec String () Declaration
35parseDataDeclaration = do
36 reserved "data"
37 name <- properName
38 tyArgs <- many identifier
39 lexeme $ P.char '='
40 ctors <- P.sepBy1 ((,) <$> properName <*> P.optionMaybe parseType) (lexeme $ P.char '|')
41 return $ DataDeclaration $ DataConstructors name tyArgs ctors
43parseTypeDeclaration :: P.Parsec String () Declaration
44parseTypeDeclaration = TypeDeclaration <$> identifier <*> (lexeme (P.string "::") *> parseType)
46parseValueDeclaration :: P.Parsec String () Declaration
47parseValueDeclaration = ValueDeclaration <$> identifier <*> (lexeme (P.char '=') *> parseValue)
49parseExternDeclaration :: P.Parsec String () Declaration
50parseExternDeclaration = ExternDeclaration <$> (reserved "extern" *> (identifier <|> properName)) <*> (lexeme (P.string "::") *> parseType)
52parseDeclaration :: P.Parsec String () Declaration
53parseDeclaration = P.choice $ map P.try
54 [ parseDataDeclaration
55 , parseTypeDeclaration
56 , parseValueDeclaration
57 , parseExternDeclaration ]
59parseDeclarations :: String -> Either P.ParseError [Declaration]
60parseDeclarations = mapM (P.parse (parseDeclaration <* whiteSpace <* P.eof) "Declaration") . splitFileIntoDeclarations
62splitFileIntoDeclarations :: String -> [String]
63splitFileIntoDeclarations = map unlines . filter (not . all isSpace . head) . groupBy ((==) `on` (all isSpace)) . lines