elm/compiler/SourceSyntax/Pattern.hs
Evan Czaplicki 9dd5dff279 Make AST more general and try to give its phases better names
Also change the constructors for the Pattern ADT
2014-02-10 00:17:33 +01:00

69 lines
1.9 KiB
Haskell

{-# OPTIONS_GHC -Wall #-}
module SourceSyntax.Pattern where
import qualified SourceSyntax.Helpers as Help
import SourceSyntax.PrettyPrint
import Text.PrettyPrint as PP
import qualified Data.Set as Set
import SourceSyntax.Literal as Literal
data Pattern
= Data String [Pattern]
| Record [String]
| Alias String Pattern
| Var String
| Anything
| Literal Literal.Literal
deriving (Eq, Ord, Show)
cons :: Pattern -> Pattern -> Pattern
cons h t = Data "::" [h,t]
nil :: Pattern
nil = Data "[]" []
list :: [Pattern] -> Pattern
list = foldr cons nil
tuple :: [Pattern] -> Pattern
tuple es = Data ("_Tuple" ++ show (length es)) es
boundVarList :: Pattern -> [String]
boundVarList = Set.toList . boundVars
boundVars :: Pattern -> Set.Set String
boundVars pattern =
case pattern of
Var x -> Set.singleton x
Alias x p -> Set.insert x (boundVars p)
Data _ ps -> Set.unions (map boundVars ps)
Record fields -> Set.fromList fields
Anything -> Set.empty
Literal _ -> Set.empty
instance Pretty Pattern where
pretty pattern =
case pattern of
Var x -> variable x
Literal lit -> pretty lit
Record fs -> PP.braces (commaCat $ map variable fs)
Alias x p -> prettyParens p <+> PP.text "as" <+> variable x
Anything -> PP.text "_"
Data "::" [hd,tl] -> parensIf isCons (pretty hd) <+> PP.text "::" <+> pretty tl
where isCons = case hd of
Data "::" _ -> True
_ -> False
Data name ps ->
if Help.isTuple name then
PP.parens . commaCat $ map pretty ps
else hsep (PP.text name : map prettyParens ps)
prettyParens :: Pattern -> Doc
prettyParens pattern = parensIf needsThem (pretty pattern)
where
needsThem =
case pattern of
Data name (_:_) | not (Help.isTuple name) -> True
Alias _ _ -> True
_ -> False