on 9cda2b2 help sign in
elk/src/AST/Pattern.hs
79 lines 2.3 kB history raw
1{-# OPTIONS_GHC -Wall #-}
2module AST.Pattern where
4import qualified AST.Helpers as Help
5import AST.PrettyPrint
6import Text.PrettyPrint as PP
7import qualified Data.Set as Set
9import qualified AST.Variable as Var
10import AST.Literal as Literal
12data Pattern var
13 = Data var [Pattern var]
14 | Record [String]
15 | Alias String (Pattern var)
16 | Var String
17 | Anything
18 | Literal Literal.Literal
19 deriving (Eq, Ord, Show)
21type RawPattern = Pattern Var.Raw
22type CanonicalPattern = Pattern Var.Canonical
24cons :: RawPattern -> RawPattern -> RawPattern
25cons h t = Data (Var.Raw "::") [h,t]
27nil :: RawPattern
28nil = Data (Var.Raw "[]") []
30list :: [RawPattern] -> RawPattern
31list = foldr cons nil
33tuple :: [RawPattern] -> RawPattern
34tuple es = Data (Var.Raw ("_Tuple" ++ show (length es))) es
36boundVarList :: Pattern var -> [String]
37boundVarList = Set.toList . boundVars
39boundVars :: Pattern var -> Set.Set String
40boundVars pattern =
41 case pattern of
42 Var x -> Set.singleton x
43 Alias x p -> Set.insert x (boundVars p)
44 Data _ ps -> Set.unions (map boundVars ps)
45 Record fields -> Set.fromList fields
46 Anything -> Set.empty
47 Literal _ -> Set.empty
50instance Var.ToString var => Pretty (Pattern var) where
51 pretty pattern =
52 case pattern of
53 Var x -> variable x
54 Literal lit -> pretty lit
55 Record fs -> PP.braces (commaCat $ map variable fs)
56 Alias x p -> prettyParens p <+> PP.text "as" <+> variable x
57 Anything -> PP.text "_"
58 Data name [hd,tl] | Var.toString name == "::" ->
59 parensIf isCons (pretty hd) <+> PP.text "::" <+> pretty tl
60 where
61 isCons = case hd of
62 Data ctor _ -> Var.toString ctor == "::"
63 _ -> False
65 Data name ps
66 | Help.isTuple name' -> PP.parens . commaCat $ map pretty ps
67 | otherwise -> hsep (PP.text name' : map prettyParens ps)
68 where
69 name' = Var.toString name
71prettyParens :: Var.ToString var => Pattern var -> Doc
72prettyParens pattern =
73 parensIf needsThem (pretty pattern)
74 where
75 needsThem =
76 case pattern of
77 Data name (_:_) | not (Help.isTuple (Var.toString name)) -> True
78 Alias _ _ -> True
79 _ -> False