summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2016-04-21 17:22:50 +0200
committerPéter Diviánszky <divipp@gmail.com>2016-04-21 17:22:50 +0200
commit1a09bf30b7ade5a2d91fa10681efbe4d88c4092a (patch)
treebe5c8a0e956e4cb6c45d3a8b7cc4054c0b8f7cdd /src
parentd2883a298f604722ddbe0a11c7bd4035740b0e02 (diff)
cleanup in pattern match compilation
Diffstat (limited to 'src')
-rw-r--r--src/LambdaCube/Compiler/Parser.hs119
1 files changed, 47 insertions, 72 deletions
diff --git a/src/LambdaCube/Compiler/Parser.hs b/src/LambdaCube/Compiler/Parser.hs
index 917af44b..ef410eaf 100644
--- a/src/LambdaCube/Compiler/Parser.hs
+++ b/src/LambdaCube/Compiler/Parser.hs
@@ -272,6 +272,12 @@ rUp n l = rearrange l $ \k -> if k >= 0 then k + n else k
272instance Rearrange a => Rearrange [a] where 272instance Rearrange a => Rearrange [a] where
273 rearrange l f = map $ rearrange l f 273 rearrange l f = map $ rearrange l f
274 274
275instance (Rearrange a, Rearrange b) => Rearrange (Either a b) where
276 rearrange l f = rearrange l f +++ rearrange l f
277
278instance (Rearrange a, Rearrange b) => Rearrange (a, b) where
279 rearrange l f = rearrange l f *** rearrange l f
280
275instance Rearrange SExp where 281instance Rearrange SExp where
276 rearrange i f = mapS (\_ -> elimVoid) (const . SGlobal) (\sn j i -> SVar sn $ if j < i then j else i + f (j - i)) i 282 rearrange i f = mapS (\_ -> elimVoid) (const . SGlobal) (\sn j i -> SVar sn $ if j < i then j else i + f (j - i)) i
277 283
@@ -498,7 +504,7 @@ parseTerm_ ge = \case
498 exp <- parseTerm PrecLam 504 exp <- parseTerm PrecLam
499 return $ \e -> 505 return $ \e ->
500 SBuiltin "concatMap" 506 SBuiltin "concatMap"
501 `SAppV` SLamV (compileGuardTree id id ge $ compilePatts [(pat, 0)] (Right $ deBruijnify dbs e) `mappend` In (GuardLeaf BNil)) 507 `SAppV` SLamV (compileGuardTree id id ge $ compilePatts [pat] (Right $ deBruijnify dbs e) `mappend` In (GuardLeaf BNil))
502 `SAppV` exp 508 `SAppV` exp
503 509
504 letdecl = mkLets ge <$ reserved "let" <*> (compileFunAlts' =<< valueDef) 510 letdecl = mkLets ge <$ reserved "let" <*> (compileFunAlts' =<< valueDef)
@@ -528,7 +534,7 @@ getList (BCons x (getList -> Just y)) = Just (x:y)
528getList _ = Nothing 534getList _ = Nothing
529 535
530patLam :: (SExp -> SExp) -> DesugarInfo -> (Visibility, SExp) -> Pat -> SExp -> SExp 536patLam :: (SExp -> SExp) -> DesugarInfo -> (Visibility, SExp) -> Pat -> SExp -> SExp
531patLam f ge (v, t) p e = SLam v t $ compileGuardTree f f ge $ compilePatts [(p, 0)] $ Right e 537patLam f ge (v, t) p e = SLam v t $ compileGuardTree f f ge $ compilePatts [p] $ Right e
532 538
533-------------------------------------------------------------------------------- pattern representation 539-------------------------------------------------------------------------------- pattern representation
534 540
@@ -543,7 +549,7 @@ data Pat
543newtype ParPat = ParPat [Pat] 549newtype ParPat = ParPat [Pat]
544 deriving Show 550 deriving Show
545 551
546pattern PWildcard si = PVar (si, "") 552pattern PWildcard = ParPat []
547pattern PCon n pp <- PCon_ _ n pp 553pattern PCon n pp <- PCon_ _ n pp
548 where PCon n pp = PCon_ (fst n <> sourceInfo pp) n pp 554 where PCon n pp = PCon_ (fst n <> sourceInfo pp) n pp
549pattern ViewPat e pp <- ViewPat_ _ e pp 555pattern ViewPat e pp <- ViewPat_ _ e pp
@@ -620,7 +626,7 @@ instance SetSourceInfo Pat where
620 626
621parsePat p = appRange $ flip setSI <$> parsePat_ p 627parsePat p = appRange $ flip setSI <$> parsePat_ p
622 628
623parsePat_ :: Prec -> BodyParser Pat 629parsePat_ :: Prec -> BodyParser Pat -- TODO: ParPat
624parsePat_ = \case 630parsePat_ = \case
625 PrecAnn -> 631 PrecAnn ->
626 patType <$> parsePat PrecOp <*> parseType (Just $ Wildcard SType) 632 patType <$> parsePat PrecOp <*> parseType (Just $ Wildcard SType)
@@ -637,7 +643,7 @@ parsePat_ = \case
637 PrecAtom -> 643 PrecAtom ->
638 mkLit <$> asks namespace <*> try "literal" parseLit 644 mkLit <$> asks namespace <*> try "literal" parseLit
639 <|> flip PCon [] <$> upperCase_ 645 <|> flip PCon [] <$> upperCase_
640 <|> PVar <$> patVar 646 <|> PVar <$> patVar -- TODO: PWildcard
641 <|> char '\'' *> ppa switchNamespace 647 <|> char '\'' *> ppa switchNamespace
642 <|> ppa id 648 <|> ppa id
643 where 649 where
@@ -657,7 +663,6 @@ parsePat_ = \case
657 mkListPat ns ps = foldr (\p ps -> PBuiltin "Cons" [p, ps]) (PBuiltin "Nil" []) ps 663 mkListPat ns ps = foldr (\p ps -> PBuiltin "Cons" [p, ps]) (PBuiltin "Nil" []) ps
658 664
659 --mkTupPat :: [Pat] -> Pat 665 --mkTupPat :: [Pat] -> Pat
660 -- TODO: tup type pattern in type namespace
661 mkTupPat TypeNS [PParens x] = mkTTup [x] 666 mkTupPat TypeNS [PParens x] = mkTTup [x]
662 mkTupPat ns [PParens x] = mkTup [x] 667 mkTupPat ns [PParens x] = mkTup [x]
663 mkTupPat _ [x] = PParens x 668 mkTupPat _ [x] = PParens x
@@ -713,10 +718,9 @@ instance Rearrange a => Rearrange (Lets a) where
713 718
714-- TODO: support type signature? 719-- TODO: support type signature?
715data GuardTree 720data GuardTree
716 = GuardNode SExp SName{-TODO:SIName-} [ParPat] GuardTrees GuardTrees 721 = GuardNode SExp SName{-TODO:SIName-} [SIName] GuardTrees GuardTrees
717 | GuardLeaf SExp 722 | GuardLeaf SExp
718 | GTError 723 | GTError
719-- | GuardLet SExp GuardTree
720 deriving Show 724 deriving Show
721 725
722type GuardTrees = Lets GuardTree 726type GuardTrees = Lets GuardTree
@@ -730,8 +734,7 @@ instance Monoid GuardTrees where
730 734
731mapGT :: (Int -> ParPat -> ParPat) -> (Int -> SExp -> SExp) -> Int -> GuardTree -> GuardTree 735mapGT :: (Int -> ParPat -> ParPat) -> (Int -> SExp -> SExp) -> Int -> GuardTree -> GuardTree
732mapGT f h k = \case 736mapGT f h k = \case
733 GuardNode e c pps gt el -> GuardNode (h k e) c (upPats f k pps) (mapGTs f h (k + patVars pps) gt) (mapGTs f h k el) 737 GuardNode e c pps gt el -> GuardNode (h k e) c pps (mapGTs f h (k + length pps) gt) (mapGTs f h k el)
734-- GuardLet e gt -> GuardLet (h k e) $ mapGT f h (k + 1) gt
735 GuardLeaf e -> GuardLeaf $ h k e 738 GuardLeaf e -> GuardLeaf $ h k e
736 GTError -> GTError 739 GTError -> GTError
737 740
@@ -740,38 +743,32 @@ mapGTs f h = mapLets h (mapGT f h)
740instance Rearrange GuardTree where 743instance Rearrange GuardTree where
741 rearrange l f = mapGT (`rearrange` f) (`rearrange` f) l 744 rearrange l f = mapGT (`rearrange` f) (`rearrange` f) l
742 745
743-- todo: clenup 746guardNode :: Pat -> SExp -> GuardTrees -> GuardTrees
744compilePatts :: [(Pat, Int)] -> Either [(SExp, SExp)] SExp -> GuardTrees 747guardNode (PVar sn) e gt = lLet e gt
745compilePatts ps gu = cp [] ps 748guardNode (PParens p) e gt = guardNode p e gt
749guardNode (ViewPat f p) e gt = guardNode' p (f `SAppV` e) gt
750guardNode (PCon sn ps) e gt = In $ GuardNode e (snd sn) ((\(v, _, _) -> v) <$> ws) gt' mempty
746 where 751 where
747 cp ps' [] = rearrange 0 (f $ reverse ps') $ case gu of 752 n = length ps
748 Right e -> In $ GuardLeaf e 753 ws = [(ns, SVar ns (n-1-i+d), rUp n d p) | (i, p, d) <- zip3 [0..] ps $ sums $ map patVars ps, let ns = dummyName $ "gn" ++ show i]
749 Left gs -> mconcat [In $ GuardNode ge "True" [] (In $ GuardLeaf e) mempty | (ge, e) <- gs] 754 gt' = foldr f (rUp n (patVars ps) gt) ws
750 cp ps' ((p@PVar{}, i): xs) = cp (p: ps') xs 755 f (v, e, p) gt = guardNode' p e gt
751 cp ps' ((p@(PCon (si, n) ps), i): xs) = In $ GuardNode (SVar (si, n) $ i + sum (map (fromMaybe 0 . ff) ps')) n ps (cp (p: ps') xs) mempty 756
752 cp ps' ((PParens p, i): xs) = cp ps' ((p, i): xs) 757guardNode' (ParPat ps) e gt = case ps of
753 cp ps' ((p@(ViewPatSimp f (PCon (si, n) ps)), i): xs) 758 [] -> gt
754 = In $ GuardNode (SAppV f $ SVar (si, n) $ i + sum (map (fromMaybe 0 . ff) ps')) n ps (cp (p: ps') xs) mempty 759 [p] -> guardNode p e gt
755 cp _ p = error $ "cp: " ++ show p 760 -- TODO: ps
756 761
757 m = length ps 762sums = scanl (+) 0
758
759 ff PVar{} = Nothing
760 ff p = Just $ patVars p
761
762 f ps i
763 | i >= s = i - s + m + sum vs'
764 | i < s = case vs_ !! n of
765 Nothing -> m + sum vs' - 1 - n
766 Just _ -> m + sum vs' - 1 - (m + sum (take n vs') + j)
767 where
768 i' = s - 1 - i
769 (n, j) = concat (zipWith (\k j -> zip (repeat j) [0..k-1]) vs [0..]) !! i'
770 763
771 vs_ = map ff ps 764compilePatts :: [Pat] -> Either [(SExp, SExp)] SExp -> GuardTrees
772 vs = map (fromMaybe 1) vs_ 765compilePatts ps gu = foldr f gu' $ zip3 ps [0..] $ sums $ map patVars ps
773 vs' = map (fromMaybe 0) vs_ 766 where
774 s = sum vs 767 n = length ps
768 f (p, i, d) g = guardNode (rUp n d p) (sVar "xcp" $ n-1-i + d) g
769 gu' = case rUp n (patVars ps) gu of
770 Right e -> In $ GuardLeaf e
771 Left gs -> mconcat [guardNode (PBuiltin "True" []) ge (In $ GuardLeaf e) | (ge, e) <- gs]
775 772
776compileGuardTree :: (SExp -> SExp) -> (SExp -> SExp) -> DesugarInfo -> GuardTrees -> SExp 773compileGuardTree :: (SExp -> SExp) -> (SExp -> SExp) -> DesugarInfo -> GuardTrees -> SExp
777compileGuardTree ulend lend adts = guardTreeToCases 774compileGuardTree ulend lend adts = guardTreeToCases
@@ -794,46 +791,27 @@ compileGuardTree ulend lend adts = guardTreeToCases
794 791
795 filterGuardTree' :: SExp -> SName{-constr.-} -> GuardTrees -> GuardTrees 792 filterGuardTree' :: SExp -> SName{-constr.-} -> GuardTrees -> GuardTrees
796 filterGuardTree' f s = \case 793 filterGuardTree' f s = \case
797 In (GuardNode f' s' ps gs el) 794 In (GuardNode f' s' ps gs (filterGuardTree' f s -> el))
798 | f /= f' || s /= s' -> In $ GuardNode f' s' ps (filterGuardTree' (up su f) s gs) (filterGuardTree' f s el) 795 | f /= f' || s /= s' -> In $ GuardNode f' s' ps (filterGuardTree' (up (length ps) f) s gs) el
799 | otherwise -> filterGuardTree' f s el 796 | otherwise -> el
800 where
801 su = patVars ps
802 In x -> In x 797 In x -> In x
803 798
804 filterGuardTree :: SExp -> SName{-constr.-} -> Int -> Int{-number of constr. params-} -> GuardTrees -> GuardTrees 799 filterGuardTree :: SExp -> SName{-constr.-} -> Int -> Int{-number of constr. params-} -> GuardTrees -> GuardTrees
805 filterGuardTree f s k ns = \case 800 filterGuardTree f s k ns = \case
806 In (GuardNode f' s' ps gs el) 801 In (GuardNode f' s' ps gs (filterGuardTree f s k ns -> el))
807 | f /= f' -> In $ GuardNode f' s' ps (filterGuardTree (up su f) s (su + k) ns gs) el' 802 | f /= f' -> In $ GuardNode f' s' ps (filterGuardTree (up su f) s (su + k) ns gs) el
808 | s == s' -> filterGuardTree f s k ns $ guardNodes (zips [k+ns-1, k+ns-2..] ps) gs <> el' 803 | s == s' -> filterGuardTree f s k ns $ foldr lLet gs (replicate su $ sVar "30" $ k+ns-1) <> el
809 | otherwise -> el' 804 | otherwise -> el
810 where 805 where
811 el' = filterGuardTree f s k ns el 806 su = length ps
812 zips is ps = zip (map (sVar "30") $ zipWith (+) is $ sums $ map patVars ps) ps
813 su = patVars ps
814 sums = scanl (+) 0
815 In x -> In x 807 In x -> In x
816 808
817 guardNodes :: [(SExp, ParPat)] -> GuardTrees -> GuardTrees
818 guardNodes [] l = l
819 guardNodes ((v, ParPat ws): vs) e = guardNode' v ws $ guardNodes vs e
820
821 guardNode' :: SExp -> [Pat] -> GuardTrees -> GuardTrees
822 guardNode' v [] e = e
823 guardNode' v [w] e = case w of
824 PVar _ -> {-todo guardNode v (subst x v ws) $ -} varGuardNode 0 v e
825 PParens p -> guardNode' v [p] e
826 ViewPat f (ParPat p) -> guardNode' (f `SAppV` v) p {- -$ guardNode v ws -} e
827 PCon (_, s) ps' -> In $ GuardNode v s ps' {- -$ guardNode v ws -} e mempty
828
829 varGuardNode v (SVar _ e) = rSubst v e
830
831compileGuardTrees ulend adts = compileGuardTree ulend SRHS adts . mconcat 809compileGuardTrees ulend adts = compileGuardTree ulend SRHS adts . mconcat
832 810
833compileGuardTrees' ge = foldr1 (SAppV2 $ SBuiltin "parEval" `SAppV` Wildcard SType) . map (compileGuardTrees id ge . (:[])) 811compileGuardTrees' ge = foldr1 (SAppV2 $ SBuiltin "parEval" `SAppV` Wildcard SType) . map (compileGuardTrees id ge . (:[]))
834 812
835compileCase ge x cs 813compileCase ge x cs
836 = SLamV (compileGuardTree id id ge $ mconcat [compilePatts [(p, 0)] e | (p, e) <- cs]) `SAppV` x 814 = SLamV (compileGuardTree id id ge $ mconcat [compilePatts [p] e | (p, e) <- cs]) `SAppV` x
837 815
838 816
839-------------------------------------------------------------------------------- declaration representation 817-------------------------------------------------------------------------------- declaration representation
@@ -1125,10 +1103,7 @@ compileFunAlts (compilegt :: DesugarInfo -> [GuardTrees] -> SExp) ds xs = dsInfo
1125 | otherwise -> return 1103 | otherwise -> return
1126 [ Let n 1104 [ Let n
1127 (listToMaybe [t | TypeAnn n' t <- ds, n' == n]) 1105 (listToMaybe [t | TypeAnn n' t <- ds, n' == n])
1128 $ foldr (uncurry SLam . fst) (compilegt ge 1106 $ foldr (uncurry SLam . fst) (compilegt ge [compilePatts (map snd vs) gsx | FunAlt _ vs gsx <- fs]) vs
1129 [ compilePatts (zip (map snd vs) $ reverse [0.. num - 1]) gsx
1130 | FunAlt _ vs gsx <- fs
1131 ]) vs
1132 ] 1107 ]
1133 _ -> fail $ "different number of arguments of " ++ snd n ++ " at " ++ ppShow (fst n) 1108 _ -> fail $ "different number of arguments of " ++ snd n ++ " at " ++ ppShow (fst n)
1134 x -> return x 1109 x -> return x