elm/compiler/Parse/Pattern.hs
Evan Czaplicki 9dd5dff279 Make AST more general and try to give its phases better names
Also change the constructors for the Pattern ADT
2014-02-10 00:17:33 +01:00

61 lines
1.7 KiB
Haskell

{-# OPTIONS_GHC -W #-}
module Parse.Pattern (term, expr) where
import Control.Applicative ((<$>))
import Data.Char (isUpper)
import qualified Data.List as List
import Text.Parsec hiding (newline,spaces,State)
import Parse.Helpers
import Parse.Literal
import SourceSyntax.Literal
import qualified SourceSyntax.Pattern as P
basic :: IParser P.Pattern
basic = choice
[ char '_' >> return P.Anything
, do v <- var
return $ case v of
"True" -> P.Literal (Boolean True)
"False" -> P.Literal (Boolean False)
c:_ | isUpper c -> P.Data v []
_ -> P.Var v
, P.Literal <$> literal
]
asPattern :: P.Pattern -> IParser P.Pattern
asPattern pattern = do
var <- optionMaybe (try (whitespace >> reserved "as" >> whitespace >> lowVar))
return $ case var of
Just v -> P.Alias v pattern
Nothing -> pattern
record :: IParser P.Pattern
record = P.Record <$> brackets (commaSep1 lowVar)
tuple :: IParser P.Pattern
tuple = do
ps <- parens (commaSep expr)
return $ case ps of
[p] -> p
_ -> P.tuple ps
list :: IParser P.Pattern
list = P.list <$> braces (commaSep expr)
term :: IParser P.Pattern
term =
(choice [ record, tuple, list, basic ]) <?> "pattern"
patternConstructor :: IParser P.Pattern
patternConstructor = do
v <- List.intercalate "." <$> dotSep1 capVar
case v of
"True" -> return $ P.Literal (Boolean True)
"False" -> return $ P.Literal (Boolean False)
_ -> P.Data v <$> spacePrefix term
expr :: IParser P.Pattern
expr = do
patterns <- consSep1 (patternConstructor <|> term)
asPattern (foldr1 P.cons patterns) <?> "pattern"