9dd5dff279
Also change the constructors for the Pattern ADT
61 lines
1.7 KiB
Haskell
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"
|