on 84bfb4e help sign in
elk/src/Parse/Pattern.hs
111 lines 2.6 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.RawPattern
17basic =
18 addLocation $
19 choice
20 [ char '_' >> return P.Anything
21 , stringToPattern <$> var
22 , P.Literal <$> Literal.literal
23 ]
24 where
25 stringToPattern str =
26 case str of
27 "True" ->
28 P.Literal (L.Boolean True)
30 "False" ->
31 P.Literal (L.Boolean False)
33 c:_ | isUpper c ->
34 P.Data (Var.Raw str) []
36 _ ->
37 P.Var str
40asPattern :: IParser P.RawPattern -> IParser P.RawPattern
41asPattern patternParser =
42 do pattern <- patternParser
44 let (A.A (R.Region start _) _) = pattern
46 maybeAlias <- optionMaybe asAlias
48 case maybeAlias of
49 Just alias ->
50 do end <- getMyPosition
51 return (A.at start end (P.Alias alias pattern))
53 Nothing ->
54 return pattern
55 where
56 asAlias =
57 do try (whitespace >> reserved "as")
58 whitespace
59 lowVar
62record :: IParser P.RawPattern
63record =
64 addLocation
65 (P.Record <$> brackets (commaSep1 lowVar))
68tuple :: IParser P.RawPattern
69tuple =
70 do (start, patterns, end) <-
71 located (parens (commaSep expr))
73 case patterns of
74 [pattern] ->
75 return pattern
77 _ ->
78 return (A.at start end (P.tuple patterns))
81list :: IParser P.RawPattern
82list =
83 braces $
84 do (_, patterns, end) <- located (commaSep expr)
85 return (P.list end patterns)
88term :: IParser P.RawPattern
89term =
90 choice [ record, tuple, list, basic ]
91 <?> "a pattern"
94patternConstructor :: IParser P.RawPattern
95patternConstructor =
96 addLocation $
97 do v <- List.intercalate "." <$> dotSep1 capVar
98 case v of
99 "True" -> return $ P.Literal (L.Boolean True)
100 "False" -> return $ P.Literal (L.Boolean False)
101 _ -> P.Data (Var.Raw v) <$> spacePrefix term
104expr :: IParser P.RawPattern
105expr =
106 asPattern subPattern <?> "a pattern"
107 where
108 subPattern =
109 do patterns <- consSep1 (patternConstructor <|> term)
110 end <- getMyPosition
111 return (P.consMany end patterns)