elm/compiler/Parse/Pattern.hs

62 lines
1.7 KiB
Haskell
Raw Normal View History

module Parse.Pattern (term, expr) where
import Control.Applicative ((<$>),(<*>),pure)
import Control.Monad
import Control.Monad.State
import Data.Char (isUpper)
import Data.List (intercalate)
import Text.Parsec hiding (newline,spaces,State)
import Text.Parsec.Indent
import Parse.Helpers
import Parse.Literal
2013-06-14 02:15:40 +00:00
import qualified SourceSyntax.Pattern as Pattern
2013-08-02 23:09:06 +00:00
import SourceSyntax.Everything hiding (tuple)
2013-06-14 02:15:40 +00:00
basic :: IParser Pattern
basic = choice
[ char '_' >> return PAnything
, do v <- var
return $ case v of
"True" -> PLiteral (Boolean True)
"False" -> PLiteral (Boolean False)
c : _ -> if isUpper c then PData v [] else PVar v
, PLiteral <$> literal
]
2013-06-14 02:15:40 +00:00
asPattern :: Pattern -> IParser Pattern
asPattern pattern = do
var <- optionMaybe (try (whitespace >> reserved "as" >> whitespace >> lowVar))
return $ case var of
2013-06-14 02:15:40 +00:00
Just v -> PAlias v pattern
Nothing -> pattern
2013-06-06 09:27:20 +00:00
2013-06-14 02:15:40 +00:00
record :: IParser Pattern
record = PRecord <$> brackets (commaSep1 lowVar)
2013-06-14 02:15:40 +00:00
tuple :: IParser Pattern
tuple = do ps <- parens (commaSep expr)
return $ case ps of { [p] -> p; _ -> Pattern.tuple ps }
2013-06-14 02:15:40 +00:00
list :: IParser Pattern
list = Pattern.list <$> braces (commaSep expr)
2013-06-14 02:15:40 +00:00
term :: IParser Pattern
term =
(choice [ record, tuple, list, basic ]) <?> "pattern"
patternConstructor :: IParser Pattern
patternConstructor = do
v <- intercalate "." <$> dotSep1 capVar
case v of
"True" -> return $ PLiteral (Boolean True)
"False" -> return $ PLiteral (Boolean False)
_ -> PData v <$> spacePrefix term
2013-06-14 02:15:40 +00:00
expr :: IParser Pattern
expr = do
patterns <- consSep1 (patternConstructor <|> term)
asPattern (foldr1 Pattern.cons patterns) <?> "pattern"