on fa8ade2 help sign in
elk/src/Parse/Pattern.hs
113 lines 2.5 kB history raw
1module Parse.Pattern (term, expr) where
3import qualified Data.List as List
4import Text.Parsec ((<|>), (<?>), char, choice, optionMaybe, try)
6import qualified AST.Literal as L
7import qualified AST.Pattern as P
8import qualified AST.Variable as Var
9import Parse.Helpers
10import qualified Parse.Literal as Literal
11import qualified Reporting.Annotation as A
12import qualified Reporting.Region as R
15basic :: IParser P.Raw
16basic =
17 addLocation $
18 choice
19 [ char '_' >> return P.Anything
20 , P.Var <$> lowVar
21 , chunksToPatterns <$> dotSep1 capVar
22 , P.Literal <$> Literal.literal
23 ]
24 where
25 chunksToPatterns chunks =
26 case List.intercalate "." chunks of
27 "True" ->
28 P.Literal (L.Boolean True)
30 "False" ->
31 P.Literal (L.Boolean False)
33 name ->
34 P.Data (Var.Raw name) []
37asPattern :: IParser P.Raw -> IParser P.Raw
38asPattern patternParser =
39 do pattern <- patternParser
41 let (A.A (R.Region start _) _) = pattern
43 maybeAlias <- optionMaybe asAlias
45 case maybeAlias of
46 Just alias ->
47 do end <- getMyPosition
48 return (A.at start end (P.Alias alias pattern))
50 Nothing ->
51 return pattern
52 where
53 asAlias =
54 do try (whitespace >> reserved "as")
55 whitespace
56 lowVar
59record :: IParser P.Raw
60record =
61 addLocation
62 (P.Record <$> brackets (commaSep1 lowVar))
65tuple :: IParser P.Raw
66tuple =
67 do (start, patterns, end) <-
68 located (parens (commaSep expr))
70 case patterns of
71 [pattern] ->
72 return pattern
74 _ ->
75 return (A.at start end (P.tuple patterns))
78list :: IParser P.Raw
79list =
80 braces $
81 do (_, patterns, end) <- located (commaSep expr)
82 return (P.list end patterns)
85term :: IParser P.Raw
86term =
87 choice [ record, tuple, list, basic ]
88 <?> "a pattern"
91patternConstructor :: IParser P.Raw
92patternConstructor =
93 addLocation $
94 do name <- List.intercalate "." <$> dotSep1 capVar
95 case name of
96 "True" ->
97 return $ P.Literal (L.Boolean True)
99 "False" ->
100 return $ P.Literal (L.Boolean False)
102 _ ->
103 P.Data (Var.Raw name) <$> spacePrefix term
106expr :: IParser P.Raw
107expr =
108 asPattern subPattern <?> "a pattern"
109 where
110 subPattern =
111 do patterns <- consSep1 (patternConstructor <|> term)
112 end <- getMyPosition
113 return (P.consMany end patterns)