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