{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Language.Haskell.Liquid.GHC.Resugar (
Pattern (..)
, lift
, lower
) where
import DataCon (DataCon)
import CoreSyn
import Type
import qualified MkCore
import qualified PrelNames as PN
import Name (Name, getName)
import qualified Data.List as L
import qualified Language.Haskell.Liquid.GHC.Misc as GM
import qualified Language.Fixpoint.Types as F
import qualified Text.PrettyPrint.HughesPJ as PJ
data Pattern
= PatBind
{ Pattern -> CoreExpr
patE1 :: !CoreExpr
, Pattern -> Var
patX :: !Var
, Pattern -> CoreExpr
patE2 :: !CoreExpr
, Pattern -> Type
patM :: !Type
, Pattern -> CoreExpr
patDct :: !CoreExpr
, Pattern -> Type
patTyA :: !Type
, Pattern -> Type
patTyB :: !Type
, Pattern -> Var
patFF :: !Var
}
| PatReturn
{ Pattern -> CoreExpr
patE :: !CoreExpr
, patM :: !Type
, patDct :: !CoreExpr
, Pattern -> Type
patTy :: !Type
, Pattern -> Var
patRet :: !Var
}
| PatProject
{ Pattern -> Var
patXE :: !Var
, patX :: !Var
, patTy :: !Type
, Pattern -> DataCon
patCtor :: !DataCon
, Pattern -> [Var]
patBinds :: ![Var]
, Pattern -> Int
patIdx :: !Int
}
| PatSelfBind
{ patX :: !Var
, patE :: !CoreExpr
}
| PatSelfRecBind
{ patX :: !Var
, patE :: !CoreExpr
}
instance F.PPrint Pattern where
pprintTidy :: Tidy -> Pattern -> Doc
pprintTidy = Tidy -> Pattern -> Doc
ppPat
ppPat :: F.Tidy -> Pattern -> PJ.Doc
ppPat :: Tidy -> Pattern -> Doc
ppPat Tidy
k (PatReturn CoreExpr
e Type
m CoreExpr
d Type
t Var
rv) =
Doc
"PatReturn: "
Doc -> Doc -> Doc
PJ.$+$
Tidy -> [(Doc, Doc)] -> Doc
forall k v. (PPrint k, PPrint v) => Tidy -> [(k, v)] -> Doc
F.pprintKVs Tidy
k
[ (Doc
"rv" :: PJ.Doc, Var -> Doc
forall a. Outputable a => a -> Doc
GM.pprDoc Var
rv)
, (Doc
"e " :: PJ.Doc, CoreExpr -> Doc
forall a. Outputable a => a -> Doc
GM.pprDoc CoreExpr
e)
, (Doc
"m " :: PJ.Doc, Type -> Doc
forall a. Outputable a => a -> Doc
GM.pprDoc Type
m)
, (Doc
"$d" :: PJ.Doc, CoreExpr -> Doc
forall a. Outputable a => a -> Doc
GM.pprDoc CoreExpr
d)
, (Doc
"t " :: PJ.Doc, Type -> Doc
forall a. Outputable a => a -> Doc
GM.pprDoc Type
t)
]
ppPat Tidy
_ Pattern
_ = Doc
"TODO: PATTERN"
_mbId :: CoreExpr -> Maybe Var
_mbId :: CoreExpr -> Maybe Var
_mbId (Var Var
x) = Var -> Maybe Var
forall a. a -> Maybe a
Just Var
x
_mbId (Tick Tickish Var
_ CoreExpr
e) = CoreExpr -> Maybe Var
_mbId CoreExpr
e
_mbId CoreExpr
_ = Maybe Var
forall a. Maybe a
Nothing
lift :: CoreExpr -> Maybe Pattern
lift :: CoreExpr -> Maybe Pattern
lift CoreExpr
e = CoreExpr -> (CoreExpr, [CoreExpr]) -> Maybe Pattern
exprArgs CoreExpr
e (CoreExpr -> (CoreExpr, [CoreExpr])
forall b. Expr b -> (Expr b, [Expr b])
collectArgs CoreExpr
e)
exprArgs :: CoreExpr -> (CoreExpr, [CoreExpr]) -> Maybe Pattern
exprArgs :: CoreExpr -> (CoreExpr, [CoreExpr]) -> Maybe Pattern
exprArgs CoreExpr
_e (Var Var
op, [Type Type
m, CoreExpr
d, Type Type
a, Type Type
b, CoreExpr
e1, Lam Var
x CoreExpr
e2])
| Var
op Var -> Name -> Bool
`is` Name
PN.bindMName
= Pattern -> Maybe Pattern
forall a. a -> Maybe a
Just (CoreExpr
-> Var
-> CoreExpr
-> Type
-> CoreExpr
-> Type
-> Type
-> Var
-> Pattern
PatBind CoreExpr
e1 Var
x CoreExpr
e2 Type
m CoreExpr
d Type
a Type
b Var
op)
exprArgs (Case (Var Var
xe) Var
x Type
t [(DataAlt DataCon
c, [Var]
ys, Var Var
y)]) (CoreExpr, [CoreExpr])
_
| Just Int
i <- Var
y Var -> [Var] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
`L.elemIndex` [Var]
ys
= Pattern -> Maybe Pattern
forall a. a -> Maybe a
Just (Var -> Var -> Type -> DataCon -> [Var] -> Int -> Pattern
PatProject Var
xe Var
x Type
t DataCon
c [Var]
ys Int
i)
exprArgs CoreExpr
_ (CoreExpr, [CoreExpr])
_
= Maybe Pattern
forall a. Maybe a
Nothing
is :: Var -> Name -> Bool
is :: Var -> Name -> Bool
is Var
v Name
n = Name
n Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Var -> Name
forall a. NamedThing a => a -> Name
getName Var
v
lower :: Pattern -> CoreExpr
lower :: Pattern -> CoreExpr
lower (PatBind CoreExpr
e1 Var
x CoreExpr
e2 Type
m CoreExpr
d Type
a Type
b Var
op)
= CoreExpr -> [CoreExpr] -> CoreExpr
MkCore.mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var Var
op) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
m, CoreExpr
d, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
a, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
b, CoreExpr
e1, Var -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam Var
x CoreExpr
e2]
lower (PatReturn CoreExpr
e Type
m CoreExpr
d Type
t Var
op)
= CoreExpr -> [CoreExpr] -> CoreExpr
MkCore.mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var Var
op) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
m, CoreExpr
d, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
t, CoreExpr
e]
lower (PatProject Var
xe Var
x Type
t DataCon
c [Var]
ys Int
i)
= CoreExpr -> Var -> Type -> [Alt Var] -> CoreExpr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case (Var -> CoreExpr
forall b. Var -> Expr b
Var Var
xe) Var
x Type
t [(DataCon -> AltCon
DataAlt DataCon
c, [Var]
ys, Var -> CoreExpr
forall b. Var -> Expr b
Var Var
yi)] where yi :: Var
yi = [Var]
ys [Var] -> Int -> Var
forall a. [a] -> Int -> a
!! Int
i
lower (PatSelfBind Var
x CoreExpr
e)
= Bind Var -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let (Var -> CoreExpr -> Bind Var
forall b. b -> Expr b -> Bind b
NonRec Var
x CoreExpr
e) (Var -> CoreExpr
forall b. Var -> Expr b
Var Var
x)
lower (PatSelfRecBind Var
x CoreExpr
e)
= Bind Var -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let ([(Var, CoreExpr)] -> Bind Var
forall b. [(b, Expr b)] -> Bind b
Rec [(Var
x, CoreExpr
e)]) (Var -> CoreExpr
forall b. Var -> Expr b
Var Var
x)