diff options
author | Péter Diviánszky <divipp@gmail.com> | 2016-04-21 17:22:50 +0200 |
---|---|---|
committer | Péter Diviánszky <divipp@gmail.com> | 2016-04-21 17:22:50 +0200 |
commit | 1a09bf30b7ade5a2d91fa10681efbe4d88c4092a (patch) | |
tree | be5c8a0e956e4cb6c45d3a8b7cc4054c0b8f7cdd /src | |
parent | d2883a298f604722ddbe0a11c7bd4035740b0e02 (diff) |
cleanup in pattern match compilation
Diffstat (limited to 'src')
-rw-r--r-- | src/LambdaCube/Compiler/Parser.hs | 119 |
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 | |||
272 | instance Rearrange a => Rearrange [a] where | 272 | instance Rearrange a => Rearrange [a] where |
273 | rearrange l f = map $ rearrange l f | 273 | rearrange l f = map $ rearrange l f |
274 | 274 | ||
275 | instance (Rearrange a, Rearrange b) => Rearrange (Either a b) where | ||
276 | rearrange l f = rearrange l f +++ rearrange l f | ||
277 | |||
278 | instance (Rearrange a, Rearrange b) => Rearrange (a, b) where | ||
279 | rearrange l f = rearrange l f *** rearrange l f | ||
280 | |||
275 | instance Rearrange SExp where | 281 | instance 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) | |||
528 | getList _ = Nothing | 534 | getList _ = Nothing |
529 | 535 | ||
530 | patLam :: (SExp -> SExp) -> DesugarInfo -> (Visibility, SExp) -> Pat -> SExp -> SExp | 536 | patLam :: (SExp -> SExp) -> DesugarInfo -> (Visibility, SExp) -> Pat -> SExp -> SExp |
531 | patLam f ge (v, t) p e = SLam v t $ compileGuardTree f f ge $ compilePatts [(p, 0)] $ Right e | 537 | patLam 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 | |||
543 | newtype ParPat = ParPat [Pat] | 549 | newtype ParPat = ParPat [Pat] |
544 | deriving Show | 550 | deriving Show |
545 | 551 | ||
546 | pattern PWildcard si = PVar (si, "") | 552 | pattern PWildcard = ParPat [] |
547 | pattern PCon n pp <- PCon_ _ n pp | 553 | pattern 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 |
549 | pattern ViewPat e pp <- ViewPat_ _ e pp | 555 | pattern ViewPat e pp <- ViewPat_ _ e pp |
@@ -620,7 +626,7 @@ instance SetSourceInfo Pat where | |||
620 | 626 | ||
621 | parsePat p = appRange $ flip setSI <$> parsePat_ p | 627 | parsePat p = appRange $ flip setSI <$> parsePat_ p |
622 | 628 | ||
623 | parsePat_ :: Prec -> BodyParser Pat | 629 | parsePat_ :: Prec -> BodyParser Pat -- TODO: ParPat |
624 | parsePat_ = \case | 630 | parsePat_ = \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? |
715 | data GuardTree | 720 | data 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 | ||
722 | type GuardTrees = Lets GuardTree | 726 | type GuardTrees = Lets GuardTree |
@@ -730,8 +734,7 @@ instance Monoid GuardTrees where | |||
730 | 734 | ||
731 | mapGT :: (Int -> ParPat -> ParPat) -> (Int -> SExp -> SExp) -> Int -> GuardTree -> GuardTree | 735 | mapGT :: (Int -> ParPat -> ParPat) -> (Int -> SExp -> SExp) -> Int -> GuardTree -> GuardTree |
732 | mapGT f h k = \case | 736 | mapGT 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) | |||
740 | instance Rearrange GuardTree where | 743 | instance 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 | 746 | guardNode :: Pat -> SExp -> GuardTrees -> GuardTrees |
744 | compilePatts :: [(Pat, Int)] -> Either [(SExp, SExp)] SExp -> GuardTrees | 747 | guardNode (PVar sn) e gt = lLet e gt |
745 | compilePatts ps gu = cp [] ps | 748 | guardNode (PParens p) e gt = guardNode p e gt |
749 | guardNode (ViewPat f p) e gt = guardNode' p (f `SAppV` e) gt | ||
750 | guardNode (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) | 757 | guardNode' (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 | 762 | sums = 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 | 764 | compilePatts :: [Pat] -> Either [(SExp, SExp)] SExp -> GuardTrees |
772 | vs = map (fromMaybe 1) vs_ | 765 | compilePatts 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 | ||
776 | compileGuardTree :: (SExp -> SExp) -> (SExp -> SExp) -> DesugarInfo -> GuardTrees -> SExp | 773 | compileGuardTree :: (SExp -> SExp) -> (SExp -> SExp) -> DesugarInfo -> GuardTrees -> SExp |
777 | compileGuardTree ulend lend adts = guardTreeToCases | 774 | compileGuardTree 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 | |||
831 | compileGuardTrees ulend adts = compileGuardTree ulend SRHS adts . mconcat | 809 | compileGuardTrees ulend adts = compileGuardTree ulend SRHS adts . mconcat |
832 | 810 | ||
833 | compileGuardTrees' ge = foldr1 (SAppV2 $ SBuiltin "parEval" `SAppV` Wildcard SType) . map (compileGuardTrees id ge . (:[])) | 811 | compileGuardTrees' ge = foldr1 (SAppV2 $ SBuiltin "parEval" `SAppV` Wildcard SType) . map (compileGuardTrees id ge . (:[])) |
834 | 812 | ||
835 | compileCase ge x cs | 813 | compileCase 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 |