@@ -33,6 +33,7 @@ import Language.PureScript.Environment
3333import Language.PureScript.Errors
3434import Language.PureScript.Kinds
3535import Language.PureScript.Names
36+import Language.PureScript.Types
3637import Language.PureScript.Parser.Common
3738import Language.PureScript.Parser.Kinds
3839import Language.PureScript.Parser.Lexer
@@ -75,7 +76,7 @@ parseTypeDeclaration =
7576
7677parseTypeSynonymDeclaration :: TokenParser Declaration
7778parseTypeSynonymDeclaration =
78− TypeSynonymDeclaration <$> (P.try (reserved "type") *> indented *> properName)
79+ TypeSynonymDeclaration <$> (reserved "type" *> indented *> properName)
7980 <*> many (indented *> kindedIdent)
8081 <*> (indented *> equals *> noWildcards parsePolyType)
8182
@@ -101,21 +102,18 @@ parseValueDeclaration = do
101102 return $ maybe value (`Let` value) whereClause
102103
103104parseExternDeclaration :: TokenParser Declaration
104−parseExternDeclaration = P.try (reserved "foreign") *> indented *> reserved "import" *> indented *>
105− (ExternDataDeclaration <$> (P.try (reserved "data") *> indented *> properName)
105+parseExternDeclaration = reserved "foreign" *> indented *> reserved "import" *> indented *>
106+ (ExternDataDeclaration <$> (reserved "data" *> indented *> properName)
106107 <*> (indented *> doubleColon *> parseKind)
107108 <|> (do ident <- parseIdent
108− -- TODO: add a wiki page link with migration info
109− -- TODO: remove this deprecation warning in 0.8
110− _ <- P.optional $ stringLiteral *> featureWasRemoved "Inline foreign string literals are no longer supported."
111109 ty <- indented *> doubleColon *> noWildcards parsePolyType
112110 return $ ExternDeclaration ident ty))
113111
114112parseAssociativity :: TokenParser Associativity
115113parseAssociativity =
116− (P.try (reserved "infixl") >> return Infixl) <|>
117− (P.try (reserved "infixr") >> return Infixr) <|>
118− (P.try (reserved "infix") >> return Infix)
114+ (reserved "infixl" *> return Infixl) <|>
115+ (reserved "infixr" *> return Infixr) <|>
116+ (reserved "infix" *> return Infix)
119117
120118parseFixity :: TokenParser Fixity
121119parseFixity = Fixity <$> parseAssociativity <*> (indented *> natural)
@@ -124,8 +122,9 @@ parseFixityDeclaration :: TokenParser Declaration
124122parseFixityDeclaration = do
125123 fixity <- parseFixity
126124 indented
125+ alias <- P.optionMaybe $ (Ident <$> identifier) <* reserved "as"
127126 name <- symbol
128− return $ FixityDeclaration fixity name
127+ return $ FixityDeclaration fixity name alias
129128
130129parseImportDeclaration :: TokenParser Declaration
131130parseImportDeclaration = do
@@ -152,9 +151,10 @@ parseImportDeclaration' = do
152151 qName <- qualifiedName
153152 return (moduleName', declType, Just qName, True)
154153 qualifyingList expectedType = do
155− idents <- P.optionMaybe $ indented *> parens (commaSep parseDeclarationRef)
156− return $ fromMaybe Implicit (expectedType <$> idents)
157−
154+ declType <- P.optionMaybe
155+ $ P.try (expectedType <$> (indented *> parens (commaSep parseDeclarationRef)))
156+ <|> (const (Implicit True) <$> (indented *> parens (symbol' "..")))
157+ return $ fromMaybe (Implicit False) declType
158158
159159parseDeclarationRef :: TokenParser DeclarationRef
160160parseDeclarationRef =
@@ -172,9 +172,9 @@ parseDeclarationRef =
172172parseTypeClassDeclaration :: TokenParser Declaration
173173parseTypeClassDeclaration = do
174174 reserved "class"
175− implies <- P.option [] $ do
175+ implies <- P.option [] . P.try $ do
176176 indented
177− implies <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many (noWildcards parseTypeAtom)))
177+ implies <- (return <$> parseConstraint) <|> parens (commaSep1 parseConstraint)
178178 lfatArrow
179179 return implies
180180 className <- indented *> properName
@@ -183,13 +183,17 @@ parseTypeClassDeclaration = do
183183 indented *> reserved "where"
184184 indented *> mark (P.many (same *> positioned parseTypeDeclaration))
185185 return $ TypeClassDeclaration className idents implies members
186+ where
187+
188+parseConstraint :: TokenParser Constraint
189+parseConstraint = (,) <$> parseQualified properName <*> P.many (noWildcards parseTypeAtom)
186190
187191parseInstanceDeclaration :: TokenParser (TypeInstanceBody -> Declaration)
188192parseInstanceDeclaration = do
189193 reserved "instance"
190194 name <- parseIdent <* indented <* doubleColon
191− deps <- P.optionMaybe $ do
192− deps <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many (noWildcards parseTypeAtom)))
195+ deps <- P.optionMaybe $ P.try $ do
196+ deps <- (return <$> parseConstraint) <|> parens (commaSep1 parseConstraint)
193197 indented
194198 rfatArrow
195199 return deps
@@ -321,11 +325,12 @@ parseIdentifierAndValue =
321325 <|> (,) <$> (C.indented *> stringLiteral) <*> rest
322326 where
323327 rest = C.indented *> colon *> C.indented *> val
324− val = (Just <$> parseValue) <|> (underscore *> pure Nothing)
328+ val = (underscore *> pure Nothing) <|> (Just <$> parseValue)
325329
326330parseAbs :: TokenParser Expr
327331parseAbs = do
328332 symbol' "\\"
333+ -- TODO: remove this 'try' after operator aliases are finished (0.9)
329334 args <- P.many1 (C.indented *> (Abs <$> (Left <$> P.try C.parseIdent <|> Right <$> parseBinderNoParens)))
330335 C.indented *> rarrow
331336 value <- parseValue
@@ -341,11 +346,11 @@ parseConstructor :: TokenParser Expr
341346parseConstructor = Constructor <$> C.parseQualified C.properName
342347
343348parseCase :: TokenParser Expr
344−parseCase = Case <$> P.between (P.try (reserved "case")) (C.indented *> reserved "of") (return <$> parseValue)
349+parseCase = Case <$> P.between (reserved "case") (C.indented *> reserved "of") (commaSep1 parseValue)
345350 <*> (C.indented *> C.mark (P.many1 (C.same *> C.mark parseCaseAlternative)))
346351
347352parseCaseAlternative :: TokenParser CaseAlternative
348−parseCaseAlternative = CaseAlternative <$> (return <$> parseBinder)
353+parseCaseAlternative = CaseAlternative <$> (commaSep1 parseBinder)
349354 <*> (Left <$> (C.indented *>
350355 P.many1 ((,) <$> parseGuard
351356 <*> (indented *> rarrow *> parseValue)
@@ -370,23 +375,25 @@ parseLet = do
370375
371376parseValueAtom :: TokenParser Expr
372377parseValueAtom = P.choice
373− [ P.try parseNumericLiteral
374− , P.try parseCharLiteral
375− , P.try parseStringLiteral
376− , P.try parseBooleanLiteral
377− , parseArrayLiteral
378− , P.try parseObjectLiteral
379− , P.try parseObjectGetter
380− , parseAbs
381− , P.try parseConstructor
382− , P.try parseVar
383− , parseCase
384− , parseIfThenElse
385− , parseDo
386− , parseLet
387− , P.try $ Parens <$> parens parseValue
388− , parseOperatorSection
389− , P.try parseObjectUpdaterWildcard ]
378+ [ parseNumericLiteral
379+ , parseCharLiteral
380+ , parseStringLiteral
381+ , parseBooleanLiteral
382+ , parseArrayLiteral
383+ , P.try parseObjectLiteral
384+ , P.try parseObjectGetter
385+ , parseAbs
386+ , P.try parseConstructor
387+ , P.try parseVar
388+ , parseCase
389+ , parseIfThenElse
390+ , parseDo
391+ , parseLet
392+ , P.try $ Parens <$> parens parseValue
393+ , parseOperatorSection
394+ -- TODO: combine this with parseObjectGetter
395+ , parseObjectUpdaterWildcard
396+ ]
390397
391398-- |
392399-- Parse an expression in backticks or an operator
@@ -422,13 +429,14 @@ parseDoNotationLet :: TokenParser DoNotationElement
422429parseDoNotationLet = DoNotationLet <$> (reserved "let" *> C.indented *> C.mark (P.many1 (C.same *> parseLocalDeclaration)))
423430
424431parseDoNotationBind :: TokenParser DoNotationElement
425−parseDoNotationBind = DoNotationBind <$> parseBinder <*> (C.indented *> larrow *> parseValue)
432+parseDoNotationBind = DoNotationBind <$> P.try (parseBinder <* C.indented <* larrow) <*> parseValue
426433
427434parseDoNotationElement :: TokenParser DoNotationElement
428435parseDoNotationElement = P.choice
429− [ P.try parseDoNotationBind
436+ [ parseDoNotationBind
430437 , parseDoNotationLet
431− , P.try (DoNotationValue <$> parseValue) ]
438+ , DoNotationValue <$> parseValue
439+ ]
432440
433441parseObjectGetter :: TokenParser Expr
434442parseObjectGetter = ObjectGetter <$> (underscore *> C.indented *> dot *> C.indented *> (lname <|> stringLiteral))
@@ -438,7 +446,8 @@ indexersAndAccessors :: TokenParser Expr
438446indexersAndAccessors = C.buildPostfixParser postfixTable parseValueAtom
439447 where
440448 postfixTable = [ parseAccessor
441− , P.try . parseUpdaterBody . Just ]
449+ , P.try . parseUpdaterBody . Just
450+ ]
442451
443452-- |
444453-- Parse a value
@@ -450,9 +459,9 @@ parseValue = withSourceSpan PositionedValue
450459 $ indexersAndAccessors) P.<?> "expression"
451460 where
452461 postfixTable = [ \v -> P.try (flip App <$> (C.indented *> indexersAndAccessors)) <*> pure v
453− , \v -> flip (TypedValue True) <$> (P.try (C.indented *> doubleColon) *> parsePolyType) <*> pure v
462+ , \v -> flip (TypedValue True) <$> (C.indented *> doubleColon *> parsePolyType) <*> pure v
454463 ]
455− operators = [ [ P.Prefix (P.try (C.indented *> symbol' "-") >> return UnaryMinus)
464+ operators = [ [ P.Prefix (C.indented *> symbol' "-" *> return UnaryMinus)
456465 ]
457466 , [ P.Infix (P.try (C.indented *> parseInfixExpr P.<?> "infix expression") >>= \ident ->
458467 return (BinaryNoParens ident)) P.AssocRight
@@ -482,9 +491,6 @@ parseNumberBinder = NumberBinder <$> (sign <*> number)
482491 <|> (symbol' "+" >> return id)
483492 <|> return id
484493
485−parseVarBinder :: TokenParser Binder
486−parseVarBinder = VarBinder <$> C.parseIdent
487−
488494parseNullaryConstructorBinder :: TokenParser Binder
489495parseNullaryConstructorBinder = ConstructorBinder <$> C.parseQualified C.properName <*> pure []
490496
@@ -497,9 +503,13 @@ parseObjectBinder = ObjectBinder <$> braces (commaSep (C.indented *> parseIdenti
497503parseArrayBinder :: TokenParser Binder
498504parseArrayBinder = squares $ ArrayBinder <$> commaSep (C.indented *> parseBinder)
499505
500−parseNamedBinder :: TokenParser Binder
501−parseNamedBinder = NamedBinder <$> (C.parseIdent <* C.indented <* at)
502− <*> (C.indented *> parseBinder)
506+parseVarOrNamedBinder :: TokenParser Binder
507+parseVarOrNamedBinder = do
508+ -- TODO: once operator aliases are finalized in 0.9, this 'try' won't be needed
509+ -- any more since identifiers in binders won't be 'Op's.
510+ name <- P.try C.parseIdent
511+ let parseNamedBinder = NamedBinder name <$> (at *> C.indented *> parseBinder)
512+ parseNamedBinder <|> return (VarBinder name)
503513
504514parseNullBinder :: TokenParser Binder
505515parseNullBinder = underscore *> return NullBinder
@@ -517,43 +527,41 @@ parseIdentifierAndBinder =
517527-- Parse a binder
518528--
519529parseBinder :: TokenParser Binder
520−parseBinder = withSourceSpan PositionedBinder (P.buildExpressionParser operators (buildPostfixParser postfixTable parseBinderAtom))
530+parseBinder = withSourceSpan PositionedBinder (buildPostfixParser postfixTable parseBinderAtom)
521531 where
522− -- TODO: remove this deprecation warning in 0.8
523− operators = [ [ P.Infix (P.try $ C.indented *> colon *> featureWasRemoved "Cons binders are no longer supported. Consider using purescript-lists or purescript-sequences instead.") P.AssocRight ] ]
524532 -- TODO: parsePolyType when adding support for polymorphic types
525− postfixTable = [ \b -> flip TypedBinder b <$> (P.try (indented *> doubleColon) *> parseType)
533+ postfixTable = [ \b -> flip TypedBinder b <$> (indented *> doubleColon *> parseType)
526534 ]
527535 parseBinderAtom :: TokenParser Binder
528− parseBinderAtom = P.choice (map P.try
536+ parseBinderAtom = P.choice
529537 [ parseNullBinder
530538 , parseCharBinder
531539 , parseStringBinder
532540 , parseBooleanBinder
533541 , parseNumberBinder
534− , parseNamedBinder
535− , parseVarBinder
542+ , parseVarOrNamedBinder
536543 , parseConstructorBinder
537544 , parseObjectBinder
538545 , parseArrayBinder
539− , parens parseBinder ]) P.<?> "binder"
546+ , parens parseBinder
547+ ] P.<?> "binder"
540548
541549-- |
542550-- Parse a binder as it would appear in a top level declaration
543551--
544552parseBinderNoParens :: TokenParser Binder
545−parseBinderNoParens = P.choice (map P.try
546− [ parseNullBinder
547− , parseCharBinder
548− , parseStringBinder
549− , parseBooleanBinder
550− , parseNumberBinder
551− , parseNamedBinder
552− , parseVarBinder
553− , parseNullaryConstructorBinder
554− , parseObjectBinder
555− , parseArrayBinder
556− , parens parseBinder ]) P.<?> "binder"
553+parseBinderNoParens = P.choice
554+ [ parseNullBinder
555+ , parseCharBinder
556+ , parseStringBinder
557+ , parseBooleanBinder
558+ , parseNumberBinder
559+ , parseVarOrNamedBinder
560+ , parseNullaryConstructorBinder
561+ , parseObjectBinder
562+ , parseArrayBinder
563+ , parens parseBinder
564+ ] P.<?> "binder"
557565
558566-- |
559567-- Parse a guard