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