on ff98144 help sign in
elk/src/Parse/Pattern.hs
112 lines 2.6 kB history raw
1module Parse.Pattern (term, expr) where
3import Control.Applicative ((<$>))
4import Data.Char (isUpper)
5import qualified Data.List as List
6import Text.Parsec ((<|>), (<?>), char, choice, optionMaybe, try)
8import qualified AST.Literal as L
9import qualified AST.Pattern as P
10import qualified AST.Variable as Var
11import Parse.Helpers
12import qualified Parse.Literal as Literal
13import qualified Reporting.Annotation as A
14import qualified Reporting.Region as R
17basic :: IParser P.RawPattern
18basic =
19 addLocation $
20 choice
21 [ char '_' >> return P.Anything
22 , stringToPattern <$> var
23 , P.Literal <$> Literal.literal
24 ]
25 where
26 stringToPattern str =
27 case str of
28 "True" ->
29 P.Literal (L.Boolean True)
31 "False" ->
32 P.Literal (L.Boolean False)
34 c:_ | isUpper c ->
35 P.Data (Var.Raw str) []
37 _ ->
38 P.Var str
41asPattern :: IParser P.RawPattern -> IParser P.RawPattern
42asPattern patternParser =
43 do pattern <- patternParser
45 let (A.A (R.Region start _) _) = pattern
47 maybeAlias <- optionMaybe asAlias
49 case maybeAlias of
50 Just alias ->
51 do end <- getMyPosition
52 return (A.at start end (P.Alias alias pattern))
54 Nothing ->
55 return pattern
56 where
57 asAlias =
58 do try (whitespace >> reserved "as")
59 whitespace
60 lowVar
63record :: IParser P.RawPattern
64record =
65 addLocation
66 (P.Record <$> brackets (commaSep1 lowVar))
69tuple :: IParser P.RawPattern
70tuple =
71 do (start, patterns, end) <-
72 located (parens (commaSep expr))
74 case patterns of
75 [pattern] ->
76 return pattern
78 _ ->
79 return (A.at start end (P.tuple patterns))
82list :: IParser P.RawPattern
83list =
84 braces $
85 do (_, patterns, end) <- located (commaSep expr)
86 return (P.list end patterns)
89term :: IParser P.RawPattern
90term =
91 choice [ record, tuple, list, basic ]
92 <?> "a pattern"
95patternConstructor :: IParser P.RawPattern
96patternConstructor =
97 addLocation $
98 do v <- List.intercalate "." <$> dotSep1 capVar
99 case v of
100 "True" -> return $ P.Literal (L.Boolean True)
101 "False" -> return $ P.Literal (L.Boolean False)
102 _ -> P.Data (Var.Raw v) <$> spacePrefix term
105expr :: IParser P.RawPattern
106expr =
107 asPattern subPattern <?> "a pattern"
108 where
109 subPattern =
110 do patterns <- consSep1 (patternConstructor <|> term)
111 end <- getMyPosition
112 return (P.consMany end patterns)