git.iko.soy/rowtype-yoga/purescript-native
on 0c961be help sign in
82 lines 2.8 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.Maybe
23import Data.Function
24import Control.Applicative
25import qualified Text.Parsec as P
26import Control.Arrow (Arrow(..))
28import PureScript.Values
29import PureScript.Types
30import PureScript.Parser.Common
31import PureScript.Declarations
32import PureScript.Parser.Values
33import PureScript.Parser.Types
35parseDataDeclaration :: P.Parsec String () Declaration
36parseDataDeclaration = do
37 reserved "data"
38 name <- properName
39 tyArgs <- many identifier
40 lexeme $ P.char '='
41 ctors <- P.sepBy1 ((,) <$> properName <*> P.optionMaybe parseType) (lexeme $ P.char '|')
42 return $ DataDeclaration name tyArgs ctors
44parseTypeDeclaration :: P.Parsec String () Declaration
45parseTypeDeclaration = TypeDeclaration <$> parseIdent <*> (lexeme (P.string "::") *> parsePolyType)
47parseTypeSynonymDeclaration :: P.Parsec String () Declaration
48parseTypeSynonymDeclaration = TypeSynonymDeclaration <$> (reserved "type" *> properName) <*> many identifier <*> (lexeme (P.char '=') *> parseType)
50parseValueDeclaration :: P.Parsec String () Declaration
51parseValueDeclaration = ValueDeclaration <$> parseIdent <*> (lexeme (P.char '=') *> parseValue)
53parseExternDeclaration :: P.Parsec String () Declaration
54parseExternDeclaration = ExternDeclaration <$> (reserved "extern" *> parseIdent) <*> (lexeme (P.string "::") *> parsePolyType)
56parseDeclaration :: P.Parsec String () Declaration
57parseDeclaration = P.choice $ map P.try
58 [ parseDataDeclaration
59 , parseTypeDeclaration
60 , parseTypeSynonymDeclaration
61 , parseValueDeclaration
62 , parseExternDeclaration ]
64parseDeclarations :: String -> Either P.ParseError [Declaration]
65parseDeclarations = fmap catMaybes . mapM (P.parse (whiteSpace *> (P.optionMaybe parseDeclaration <* whiteSpace) <* P.eof) "Declaration") . splitFileIntoDeclarations
67isIndented :: String -> Bool
68isIndented = any isSpace . take 1
70splitFileIntoDeclarations :: String -> [String]
71splitFileIntoDeclarations = reverse . map (dropWhile isSpace . unlines . reverse) . go [] [] . lines
72 where
73 go [] sss [] = sss
74 go ss sss [] = ss:sss
75 go ss sss (s:rest)
76 | all isSpace s = go ss sss rest
77 | isIndented s = go (s:ss) sss rest
78 | null ss = go [s] sss rest
79 | otherwise = go [s] (ss:sss) rest