@@ -1,4 +1,3 @@
2module Generate.Cases (caseToMatch, Match (..), Clause (..), matchSubst) where
1module Generate.Cases (caseToMatch, Match (..), Clause (..), matchSubst) where
4import Control.Arrow (first)
3import Control.Arrow (first)
@@ -8,6 +7,7 @@ import Data.Maybe (fromMaybe)
9import Unique
8import Unique
10import SourceSyntax.Location
9import SourceSyntax.Location
10+import SourceSyntax.Literal
11import SourceSyntax.Pattern
11import SourceSyntax.Pattern
12import SourceSyntax.Expression
12import SourceSyntax.Expression
13import Transform.Substitute
13import Transform.Substitute
@@ -28,7 +28,7 @@ data Match t v
28 deriving Show
28 deriving Show
30data Clause t v =
30data Clause t v =
31− Clause String [String] (Match t v)
31+ Clause (Either String Literal) [String] (Match t v)
32 deriving Show
32 deriving Show
34matchSubst :: [(String,String)] -> Match t v -> Match t v
34matchSubst :: [(String,String)] -> Match t v -> Match t v
@@ -43,8 +43,11 @@ matchSubst pairs (Match n cs m) =
43 clauseSubst (Clause c vs m) =
43 clauseSubst (Clause c vs m) =
44 Clause c (map varSubst vs) (matchSubst pairs m)
44 Clause c (map varSubst vs) (matchSubst pairs m)
46−isCon (PData _ _ : _, _) = True
46+isCon (p:ps, _) =
47−isCon _ = False
50+ _ -> False
49isVar p = not (isCon p)
52isVar p = not (isCon p)
@@ -58,36 +61,63 @@ match vs cs def
58 | all isCon cs = matchCon vs cs def
61 | all isCon cs = matchCon vs cs def
59 | otherwise = matchMix vs cs def
62 | otherwise = matchMix vs cs def
61−matchVar :: [String] -> [([Pattern],LExpr t v)] -> Match t v -> Unique (Match t v)
64+matchVar :: [String] -> [([Pattern],LExpr t v)] -> Match t v
65+ -> Unique (Match t v)
62matchVar (v:vs) cs def = match vs (map subVar cs) def
66matchVar (v:vs) cs def = match vs (map subVar cs) def
64− subVar (p:ps, ce@(L t s e)) =
68+ subVar (p:ps, ce@(L t s e)) = (ps, L t s $ subOnePattern p)
66 loc = L t s
70 loc = L t s
71+ subOnePattern pattern =
67− subOnePattern (PVar x) = subst x (Var v) e
73+ PVar x -> subst x (Var v) e
68− subOnePattern (PAlias x p) =
69− subst x (Var v) e
74+ PAlias x p -> subst x (Var v) e
70− subOnePattern PAnything = e
75+ PAnything -> e
71− subOnePattern (PRecord fs) =
76+ PRecord fs ->
72− foldr (\x -> subst x (Access (loc (Var v)) x)) e fs
77+ foldr (\x -> subst x (Access (loc (Var v)) x)) e fs
74− (ps, L t s $ subOnePattern p)
76−matchCon :: [String] -> [([Pattern],LExpr t v)] -> Match t v -> Unique (Match t v)
79+matchCon :: [String] -> [([Pattern],LExpr t v)] -> Match t v
80+ -> Unique (Match t v)
77matchCon (v:vs) cs def = (flip (Match v) def) `liftM` mapM toClause css
81matchCon (v:vs) cs def = (flip (Match v) def) `liftM` mapM toClause css
78− where css = groupBy (withName (==)) $ sortBy (withName compare) cs
83+ css = groupBy eq (sortBy cmp cs)
85+ cmp (p1:_,_) (p2:_,_) =
79− withName f (PData n1 _:_,_) (PData n2 _:_,_) = f n1 n2
87+ (PData n1 _, PData n2 _) -> compare n1 n2
80− toClause cs = let (PData name _ : _ , _) = head cs in
88+ _ -> compare p1 p2
81− matchClause name (v:vs) cs Break
89+
90+ eq (p1:_,_) (p2:_,_) =
92+ (PData n1 _, PData n2 _) -> n1 == n2
83−matchClause :: String -> [String] -> [([Pattern],LExpr t v)] -> Match t v -> Unique (Clause t v)
95+ toClause cs =
97+ (PData name _ : _, _) -> matchClause (Left name) (v:vs) cs Break
98+ (PLiteral lit : _, _) -> matchClause (Right lit) (v:vs) cs Break
100+matchClause :: Either String Literal
102+ -> [([Pattern],LExpr t v)]
104+ -> Unique (Clause t v)
84matchClause c (v:vs) cs def =
105matchClause c (v:vs) cs def =
85 do vs' <- getVars
106 do vs' <- getVars
86 Clause c vs' `liftM` match (vs' ++ vs) (map flatten cs) def
107 Clause c vs' `liftM` match (vs' ++ vs) (map flatten cs) def
87− where flatten (PData _ ps' : ps, e) = (ps' ++ ps, e)
110+ flatten (p:ps, e) =
112+ PData _ ps' -> (ps' ++ ps, e)
113+ PLiteral _ -> (ps, e)
88− getVars = let (PData _ ps : _, _) = head cs in
115+ getVars =
89− mapM (\_ -> newVar) ps
117+ (PData _ ps : _, _) -> mapM (\_ -> newVar) ps
118+ (PLiteral _ : _, _) -> return []
91−matchMix :: [String] -> [([Pattern],LExpr t v)] -> Match t v -> Unique (Match t v)
120+matchMix :: [String] -> [([Pattern],LExpr t v)] -> Match t v
121+ -> Unique (Match t v)
92matchMix vs cs def = foldM (flip $ match vs) def (reverse css)
122matchMix vs cs def = foldM (flip $ match vs) def (reverse css)
93 where css = groupBy (\p1 p2 -> isCon p1 == isCon p2) cs
123 where css = groupBy (\p1 p2 -> isCon p1 == isCon p2) cs