@@ -1,6 +1,4 @@
2−-- Parsers for module definitions and declarations
1+-- | Parsers for module definitions and declarations
4module Language.PureScript.Parser.Declarations
2module Language.PureScript.Parser.Declarations
5 ( parseDeclaration
3 ( parseDeclaration
6 , parseModule
4 , parseModule
@@ -15,53 +13,29 @@ module Language.PureScript.Parser.Declarations
15 , toPositionedError
13 , toPositionedError
18−import Prelude hiding (lex)
16+import Prelude hiding (lex)
20−import Data.Functor (($>))
21−import Data.Maybe (fromMaybe)
22−import Data.Text (Text)
24−import Control.Applicative
18+import Control.Applicative
25−import Control.Arrow ((+++))
19+import Control.Arrow ((+++))
26−import Control.Monad.Error.Class (MonadError(..))
20+import Control.Monad.Error.Class (MonadError(..))
27−import Control.Parallel.Strategies (withStrategy, parList, rseq)
21+import Control.Parallel.Strategies (withStrategy, parList, rseq)
28−
22+import Data.Functor (($>))
23+import Data.Maybe (fromMaybe)
24+import Data.Text (Text)
29−import Language.PureScript.AST
25+import Language.PureScript.AST
30−import Language.PureScript.Comments
31−import Language.PureScript.Environment
26+import Language.PureScript.Environment
32−import Language.PureScript.Errors
27+import Language.PureScript.Errors
33−import Language.PureScript.Kinds
28+import Language.PureScript.Kinds
34−import Language.PureScript.Names
29+import Language.PureScript.Names
30+import Language.PureScript.Parser.Common
31+import Language.PureScript.Parser.Kinds
32+import Language.PureScript.Parser.Lexer
35−import Language.PureScript.Types
33+import Language.PureScript.Parser.Types
36−import Language.PureScript.PSString (PSString, mkString)
34+import Language.PureScript.PSString (PSString, mkString)
37−import Language.PureScript.Parser.Common
38−import Language.PureScript.Parser.Kinds
39−import Language.PureScript.Parser.Lexer
40−import Language.PureScript.Parser.Types
35+import Language.PureScript.Types
42−import qualified Language.PureScript.Parser.Common as C
43import qualified Text.Parsec as P
36import qualified Text.Parsec as P
44import qualified Text.Parsec.Expr as P
37import qualified Text.Parsec.Expr as P
47−-- Read source position information
50− :: (SourceSpan -> [Comment] -> a -> a)
51− -> P.Parsec [PositionedToken] u a
52− -> P.Parsec [PositionedToken] u a
53−withSourceSpan f p = do
54− start <- P.getPosition
55− comments <- C.readComments
59− let end' = case input of
60− pt:_ -> ptPrevEndPos pt
62− let sp = SourceSpan (P.sourceName start) (C.toSourcePos start) (C.toSourcePos $ fromMaybe end end')
63− return $ f sp comments x
65kindedIdent :: TokenParser (Text, Maybe Kind)
39kindedIdent :: TokenParser (Text, Maybe Kind)
66kindedIdent = (, Nothing) <$> identifier
40kindedIdent = (, Nothing) <$> identifier
67 <|> parens ((,) <$> identifier <*> (Just <$> (indented *> doubleColon *> indented *> parseKind)))
41 <|> parens ((,) <$> identifier <*> (Just <$> (indented *> doubleColon *> indented *> parseKind)))
@@ -91,7 +65,7 @@ parseValueDeclaration :: TokenParser Declaration
91parseValueDeclaration = do
65parseValueDeclaration = do
92 name <- parseIdent
66 name <- parseIdent
93 binders <- P.many parseBinderNoParens
67 binders <- P.many parseBinderNoParens
94− value <- Left <$> (C.indented *>
68+ value <- Left <$> (indented *>
95 P.many1 ((,) <$> parseGuard
69 P.many1 ((,) <$> parseGuard
96 <*> (indented *> equals *> parseValueWithWhereClause)
70 <*> (indented *> equals *> parseValueWithWhereClause)
@@ -100,13 +74,13 @@ parseValueDeclaration = do
101 parseValueWithWhereClause :: TokenParser Expr
75 parseValueWithWhereClause :: TokenParser Expr
102 parseValueWithWhereClause = do
76 parseValueWithWhereClause = do
103− C.indented
77+ indented
104 value <- parseValue
78 value <- parseValue
105 whereClause <- P.optionMaybe $ do
79 whereClause <- P.optionMaybe $ do
106− C.indented
80+ indented
107 reserved "where"
81 reserved "where"
108− C.indented
82+ indented
109− C.mark $ P.many1 (C.same *> parseLocalDeclaration)
83+ mark $ P.many1 (same *> parseLocalDeclaration)
110 return $ maybe value (`Let` value) whereClause
84 return $ maybe value (`Let` value) whereClause
112parseExternDeclaration :: TokenParser Declaration
86parseExternDeclaration :: TokenParser Declaration
@@ -237,9 +211,7 @@ parseDerivingInstanceDeclaration = do
237positioned :: TokenParser Declaration -> TokenParser Declaration
211positioned :: TokenParser Declaration -> TokenParser Declaration
238positioned = withSourceSpan PositionedDeclaration
212positioned = withSourceSpan PositionedDeclaration
241−-- Parse a single declaration
214+-- | Parse a single declaration
243parseDeclaration :: TokenParser Declaration
215parseDeclaration :: TokenParser Declaration
244parseDeclaration = positioned (P.choice
216parseDeclaration = positioned (P.choice
245 [ parseDataDeclaration
217 [ parseDataDeclaration
@@ -259,12 +231,10 @@ parseLocalDeclaration = positioned (P.choice
259 , parseValueDeclaration
231 , parseValueDeclaration
260 ] P.<?> "local declaration")
232 ] P.<?> "local declaration")
263−-- Parse a module header and a collection of declarations
234+-- | Parse a module header and a collection of declarations
265parseModule :: TokenParser Module
235parseModule :: TokenParser Module
266parseModule = do
236parseModule = do
267− comments <- C.readComments
237+ comments <- readComments
268 start <- P.getPosition
238 start <- P.getPosition
269 reserved "module"
239 reserved "module"
@@ -280,7 +250,7 @@ parseModule = do
280 return (imports ++ decls)
250 return (imports ++ decls)
281 _ <- P.eof
251 _ <- P.eof
282 end <- P.getPosition
252 end <- P.getPosition
283− let ss = SourceSpan (P.sourceName start) (C.toSourcePos start) (C.toSourcePos end)
253+ let ss = SourceSpan (P.sourceName start) (toSourcePos start) (toSourcePos end)
284 return $ Module ss comments name decls exports
254 return $ Module ss comments name decls exports
286-- | Parse a collection of modules in parallel
256-- | Parse a collection of modules in parallel
@@ -301,7 +271,6 @@ parseModulesFromFiles toFilePath input =
301 inParallel :: [Either P.ParseError (k, a)] -> [Either P.ParseError (k, a)]
271 inParallel :: [Either P.ParseError (k, a)] -> [Either P.ParseError (k, a)]
302 inParallel = withStrategy (parList rseq)
272 inParallel = withStrategy (parList rseq)
305-- | Parses a single module with FilePath for eventual parsing errors
274-- | Parses a single module with FilePath for eventual parsing errors
306parseModuleFromFile
275parseModuleFromFile
307 :: (k -> FilePath)
276 :: (k -> FilePath)
@@ -313,12 +282,12 @@ parseModuleFromFile toFilePath (k, content) = do
313 m <- runTokenParser filename parseModule ts
282 m <- runTokenParser filename parseModule ts
314 pure (k, m)
283 pure (k, m)
316−-- | Converts a @ParseError@ into a @PositionedError@
285+-- | Converts a 'ParseError' into a 'PositionedError'
317toPositionedError :: P.ParseError -> ErrorMessage
286toPositionedError :: P.ParseError -> ErrorMessage
318toPositionedError perr = ErrorMessage [ PositionedError (SourceSpan name start end) ] (ErrorParsingModule perr)
287toPositionedError perr = ErrorMessage [ PositionedError (SourceSpan name start end) ] (ErrorParsingModule perr)
320 name = (P.sourceName . P.errorPos) perr
289 name = (P.sourceName . P.errorPos) perr
321− start = (C.toSourcePos . P.errorPos) perr
290+ start = (toSourcePos . P.errorPos) perr
322 end = start
291 end = start
324booleanLiteral :: TokenParser Bool
293booleanLiteral :: TokenParser Bool
@@ -345,18 +314,18 @@ parseObjectLiteral p = ObjectLiteral <$> braces (commaSep p)
345parseIdentifierAndValue :: TokenParser (PSString, Expr)
314parseIdentifierAndValue :: TokenParser (PSString, Expr)
346parseIdentifierAndValue =
315parseIdentifierAndValue =
348− name <- C.indented *> lname
317+ name <- indented *> lname
349 b <- P.option (Var $ Qualified Nothing (Ident name)) rest
318 b <- P.option (Var $ Qualified Nothing (Ident name)) rest
350 return (mkString name, b)
319 return (mkString name, b)
351− <|> (,) <$> (C.indented *> stringLiteral) <*> rest
320+ <|> (,) <$> (indented *> stringLiteral) <*> rest
353− rest = C.indented *> colon *> C.indented *> parseValue
322+ rest = indented *> colon *> indented *> parseValue
355parseAbs :: TokenParser Expr
324parseAbs :: TokenParser Expr
356parseAbs = do
325parseAbs = do
357 symbol' "\\"
326 symbol' "\\"
358− args <- P.many1 (C.indented *> (Abs <$> (Left <$> C.parseIdent <|> Right <$> parseBinderNoParens)))
327+ args <- P.many1 (indented *> (Abs <$> (Left <$> parseIdent <|> Right <$> parseBinderNoParens)))
359− C.indented *> rarrow
328+ indented *> rarrow
360 value <- parseValue
329 value <- parseValue
361 return $ toFunction args value
330 return $ toFunction args value
@@ -364,18 +333,18 @@ parseAbs = do
364 toFunction args value = foldr ($) value args
333 toFunction args value = foldr ($) value args
366parseVar :: TokenParser Expr
335parseVar :: TokenParser Expr
367−parseVar = Var <$> C.parseQualified C.parseIdent
336+parseVar = Var <$> parseQualified parseIdent
369parseConstructor :: TokenParser Expr
338parseConstructor :: TokenParser Expr
370−parseConstructor = Constructor <$> C.parseQualified C.dataConstructorName
339+parseConstructor = Constructor <$> parseQualified dataConstructorName
372parseCase :: TokenParser Expr
341parseCase :: TokenParser Expr
373−parseCase = Case <$> P.between (reserved "case") (C.indented *> reserved "of") (commaSep1 parseValue)
342+parseCase = Case <$> P.between (reserved "case") (indented *> reserved "of") (commaSep1 parseValue)
374− <*> (C.indented *> C.mark (P.many1 (C.same *> C.mark parseCaseAlternative)))
343+ <*> (indented *> mark (P.many1 (same *> mark parseCaseAlternative)))
376parseCaseAlternative :: TokenParser CaseAlternative
345parseCaseAlternative :: TokenParser CaseAlternative
377parseCaseAlternative = CaseAlternative <$> commaSep1 parseBinder
346parseCaseAlternative = CaseAlternative <$> commaSep1 parseBinder
378− <*> (Left <$> (C.indented *>
347+ <*> (Left <$> (indented *>
379 P.many1 ((,) <$> parseGuard
348 P.many1 ((,) <$> parseGuard
380 <*> (indented *> rarrow *> parseValue)
349 <*> (indented *> rarrow *> parseValue)
@@ -383,16 +352,16 @@ parseCaseAlternative = CaseAlternative <$> commaSep1 parseBinder
383 P.<?> "case alternative"
352 P.<?> "case alternative"
385parseIfThenElse :: TokenParser Expr
354parseIfThenElse :: TokenParser Expr
386−parseIfThenElse = IfThenElse <$> (P.try (reserved "if") *> C.indented *> parseValue)
355+parseIfThenElse = IfThenElse <$> (P.try (reserved "if") *> indented *> parseValue)
387− <*> (C.indented *> reserved "then" *> C.indented *> parseValue)
356+ <*> (indented *> reserved "then" *> indented *> parseValue)
388− <*> (C.indented *> reserved "else" *> C.indented *> parseValue)
357+ <*> (indented *> reserved "else" *> indented *> parseValue)
390parseLet :: TokenParser Expr
359parseLet :: TokenParser Expr
391parseLet = do
360parseLet = do
392 reserved "let"
361 reserved "let"
393− C.indented
362+ indented
394− ds <- C.mark $ P.many1 (C.same *> parseLocalDeclaration)
363+ ds <- mark $ P.many1 (same *> parseLocalDeclaration)
395− C.indented
364+ indented
396 reserved "in"
365 reserved "in"
397 result <- parseValue
366 result <- parseValue
398 return $ Let ds result
367 return $ Let ds result
@@ -418,9 +387,7 @@ parseValueAtom = withSourceSpan PositionedValue $ P.choice
418 , parseHole
387 , parseHole
422−-- Parse an expression in backticks or an operator
390+-- | Parse an expression in backticks or an operator
424parseInfixExpr :: TokenParser Expr
391parseInfixExpr :: TokenParser Expr
425parseInfixExpr
392parseInfixExpr
426 = P.between tick tick parseValue
393 = P.between tick tick parseValue
@@ -432,25 +399,25 @@ parseHole = Hole <$> holeLit
432parsePropertyUpdate :: TokenParser (PSString, Expr)
399parsePropertyUpdate :: TokenParser (PSString, Expr)
433parsePropertyUpdate = do
400parsePropertyUpdate = do
434 name <- parseLabel
401 name <- parseLabel
435− _ <- C.indented *> equals
402+ _ <- indented *> equals
436− value <- C.indented *> parseValue
403+ value <- indented *> parseValue
437 return (name, value)
404 return (name, value)
439parseAccessor :: Expr -> TokenParser Expr
406parseAccessor :: Expr -> TokenParser Expr
440parseAccessor (Constructor _) = P.unexpected "constructor"
407parseAccessor (Constructor _) = P.unexpected "constructor"
441−parseAccessor obj = P.try $ Accessor <$> (C.indented *> dot *> C.indented *> parseLabel) <*> pure obj
408+parseAccessor obj = P.try $ Accessor <$> (indented *> dot *> indented *> parseLabel) <*> pure obj
443parseDo :: TokenParser Expr
410parseDo :: TokenParser Expr
444parseDo = do
411parseDo = do
445 reserved "do"
412 reserved "do"
446− C.indented
413+ indented
447− Do <$> C.mark (P.many1 (C.same *> C.mark parseDoNotationElement))
414+ Do <$> mark (P.many1 (same *> mark parseDoNotationElement))
449parseDoNotationLet :: TokenParser DoNotationElement
416parseDoNotationLet :: TokenParser DoNotationElement
450−parseDoNotationLet = DoNotationLet <$> (reserved "let" *> C.indented *> C.mark (P.many1 (C.same *> parseLocalDeclaration)))
417+parseDoNotationLet = DoNotationLet <$> (reserved "let" *> indented *> mark (P.many1 (same *> parseLocalDeclaration)))
452parseDoNotationBind :: TokenParser DoNotationElement
419parseDoNotationBind :: TokenParser DoNotationElement
453−parseDoNotationBind = DoNotationBind <$> P.try (parseBinder <* C.indented <* larrow) <*> parseValue
420+parseDoNotationBind = DoNotationBind <$> P.try (parseBinder <* indented <* larrow) <*> parseValue
455parseDoNotationElement :: TokenParser DoNotationElement
422parseDoNotationElement :: TokenParser DoNotationElement
456parseDoNotationElement = P.choice
423parseDoNotationElement = P.choice
@@ -461,33 +428,31 @@ parseDoNotationElement = P.choice
462-- | Expressions including indexers and record updates
429-- | Expressions including indexers and record updates
463indexersAndAccessors :: TokenParser Expr
430indexersAndAccessors :: TokenParser Expr
464−indexersAndAccessors = C.buildPostfixParser postfixTable parseValueAtom
431+indexersAndAccessors = buildPostfixParser postfixTable parseValueAtom
466 postfixTable = [ parseAccessor
433 postfixTable = [ parseAccessor
467 , P.try . parseUpdaterBody
434 , P.try . parseUpdaterBody
470−-- |
437+-- | Parse an expression
473parseValue :: TokenParser Expr
438parseValue :: TokenParser Expr
474parseValue = withSourceSpan PositionedValue
439parseValue = withSourceSpan PositionedValue
475 (P.buildExpressionParser operators
440 (P.buildExpressionParser operators
476− . C.buildPostfixParser postfixTable
441+ . buildPostfixParser postfixTable
477 $ indexersAndAccessors) P.<?> "expression"
442 $ indexersAndAccessors) P.<?> "expression"
479− postfixTable = [ \v -> P.try (flip App <$> (C.indented *> indexersAndAccessors)) <*> pure v
444+ postfixTable = [ \v -> P.try (flip App <$> (indented *> indexersAndAccessors)) <*> pure v
480− , \v -> flip (TypedValue True) <$> (C.indented *> doubleColon *> parsePolyType) <*> pure v
445+ , \v -> flip (TypedValue True) <$> (indented *> doubleColon *> parsePolyType) <*> pure v
482− operators = [ [ P.Prefix (C.indented *> symbol' "-" *> return UnaryMinus)
447+ operators = [ [ P.Prefix (indented *> symbol' "-" *> return UnaryMinus)
484− , [ P.Infix (P.try (C.indented *> parseInfixExpr P.<?> "infix expression") >>= \ident ->
449+ , [ P.Infix (P.try (indented *> parseInfixExpr P.<?> "infix expression") >>= \ident ->
485 return (BinaryNoParens ident)) P.AssocRight
450 return (BinaryNoParens ident)) P.AssocRight
489parseUpdaterBody :: Expr -> TokenParser Expr
454parseUpdaterBody :: Expr -> TokenParser Expr
490−parseUpdaterBody v = ObjectUpdate v <$> (C.indented *> braces (commaSep1 (C.indented *> parsePropertyUpdate)))
455+parseUpdaterBody v = ObjectUpdate v <$> (indented *> braces (commaSep1 (indented *> parsePropertyUpdate)))
492parseAnonymousArgument :: TokenParser Expr
457parseAnonymousArgument :: TokenParser Expr
493parseAnonymousArgument = underscore *> pure AnonymousArgument
458parseAnonymousArgument = underscore *> pure AnonymousArgument
@@ -501,21 +466,21 @@ parseNumberLiteral = LiteralBinder . NumericLiteral <$> (sign <*> number)
501 <|> return id
466 <|> return id
503parseNullaryConstructorBinder :: TokenParser Binder
468parseNullaryConstructorBinder :: TokenParser Binder
504−parseNullaryConstructorBinder = ConstructorBinder <$> C.parseQualified C.dataConstructorName <*> pure []
469+parseNullaryConstructorBinder = ConstructorBinder <$> parseQualified dataConstructorName <*> pure []
506parseConstructorBinder :: TokenParser Binder
471parseConstructorBinder :: TokenParser Binder
507−parseConstructorBinder = ConstructorBinder <$> C.parseQualified C.dataConstructorName <*> many (C.indented *> parseBinderNoParens)
472+parseConstructorBinder = ConstructorBinder <$> parseQualified dataConstructorName <*> many (indented *> parseBinderNoParens)
509parseObjectBinder:: TokenParser Binder
474parseObjectBinder:: TokenParser Binder
510−parseObjectBinder = LiteralBinder <$> parseObjectLiteral (C.indented *> parseIdentifierAndBinder)
475+parseObjectBinder = LiteralBinder <$> parseObjectLiteral (indented *> parseIdentifierAndBinder)
512parseArrayBinder :: TokenParser Binder
477parseArrayBinder :: TokenParser Binder
513−parseArrayBinder = LiteralBinder <$> parseArrayLiteral (C.indented *> parseBinder)
478+parseArrayBinder = LiteralBinder <$> parseArrayLiteral (indented *> parseBinder)
515parseVarOrNamedBinder :: TokenParser Binder
480parseVarOrNamedBinder :: TokenParser Binder
516parseVarOrNamedBinder = do
481parseVarOrNamedBinder = do
517− name <- C.parseIdent
482+ name <- parseIdent
518− let parseNamedBinder = NamedBinder name <$> (at *> C.indented *> parseBinderAtom)
483+ let parseNamedBinder = NamedBinder name <$> (at *> indented *> parseBinderNoParens)
519 parseNamedBinder <|> return (VarBinder name)
484 parseNamedBinder <|> return (VarBinder name)
521parseNullBinder :: TokenParser Binder
486parseNullBinder :: TokenParser Binder
@@ -528,11 +493,9 @@ parseIdentifierAndBinder =
528 return (mkString name, b)
493 return (mkString name, b)
529 <|> (,) <$> stringLiteral <*> rest
494 <|> (,) <$> stringLiteral <*> rest
531− rest = C.indented *> colon *> C.indented *> parseBinder
496+ rest = indented *> colon *> indented *> parseBinder
534−-- Parse a binder
498+-- | Parse a binder
536parseBinder :: TokenParser Binder
499parseBinder :: TokenParser Binder
537parseBinder =
500parseBinder =
538 withSourceSpan
501 withSourceSpan
@@ -543,7 +506,7 @@ parseBinder =
545 operators =
508 operators =
546− [ [ P.Infix (P.try (C.indented *> parseOpBinder P.<?> "binder operator") >>= \op ->
509+ [ [ P.Infix (P.try (indented *> parseOpBinder P.<?> "binder operator") >>= \op ->
547 return (BinaryNoParensBinder op)) P.AssocRight
510 return (BinaryNoParensBinder op)) P.AssocRight
@@ -569,9 +532,7 @@ parseBinderAtom = P.choice
569 , ParensInBinder <$> parens parseBinder
532 , ParensInBinder <$> parens parseBinder
570 ] P.<?> "binder"
533 ] P.<?> "binder"
573−-- Parse a binder as it would appear in a top level declaration
535+-- | Parse a binder as it would appear in a top level declaration
575parseBinderNoParens :: TokenParser Binder
536parseBinderNoParens :: TokenParser Binder
576parseBinderNoParens = P.choice
537parseBinderNoParens = P.choice
577 [ parseNullBinder
538 [ parseNullBinder
@@ -586,8 +547,6 @@ parseBinderNoParens = P.choice
586 , ParensInBinder <$> parens parseBinder
547 , ParensInBinder <$> parens parseBinder
587 ] P.<?> "binder"
548 ] P.<?> "binder"
590−-- Parse a guard
550+-- | Parse a guard
592parseGuard :: TokenParser Guard
551parseGuard :: TokenParser Guard
593−parseGuard = pipe *> C.indented *> parseValue
552+parseGuard = pipe *> indented *> parseValue