on 6f75310 help sign in
elk/compiler/Parse/Pattern.hs
61 lines 1.8 kB history raw
2module Parse.Pattern (term, expr) where
4import Control.Applicative ((<$>),(<*>),pure)
5import Control.Monad
6import Control.Monad.State
7import Data.Char (isUpper)
8import Data.List (intercalate)
9import Text.Parsec hiding (newline,spaces,State)
10import Text.Parsec.Indent
12import Parse.Helpers
13import Parse.Literal
14import SourceSyntax.Literal
15import SourceSyntax.Pattern hiding (tuple, list)
16import qualified SourceSyntax.Pattern as Pattern
18basic :: IParser Pattern
19basic = choice
20 [ char '_' >> return PAnything
21 , do v <- var
22 return $ case v of
23 "True" -> PLiteral (Boolean True)
24 "False" -> PLiteral (Boolean False)
25 c : _ -> if isUpper c then PData v [] else PVar v
26 , PLiteral <$> literal
27 ]
29asPattern :: Pattern -> IParser Pattern
30asPattern pattern = do
31 var <- optionMaybe (try (whitespace >> reserved "as" >> whitespace >> lowVar))
32 return $ case var of
33 Just v -> PAlias v pattern
34 Nothing -> pattern
36record :: IParser Pattern
37record = PRecord <$> brackets (commaSep1 lowVar)
39tuple :: IParser Pattern
40tuple = do ps <- parens (commaSep expr)
41 return $ case ps of { [p] -> p; _ -> Pattern.tuple ps }
43list :: IParser Pattern
44list = Pattern.list <$> braces (commaSep expr)
46term :: IParser Pattern
47term =
48 (choice [ record, tuple, list, basic ]) <?> "pattern"
50patternConstructor :: IParser Pattern
51patternConstructor = do
52 v <- intercalate "." <$> dotSep1 capVar
53 case v of
54 "True" -> return $ PLiteral (Boolean True)
55 "False" -> return $ PLiteral (Boolean False)
56 _ -> PData v <$> spacePrefix term
58expr :: IParser Pattern
59expr = do
60 patterns <- consSep1 (patternConstructor <|> term)
61 asPattern (foldr1 Pattern.cons patterns) <?> "pattern"