liquidhaskell-0.8.0.2: src/Language/Haskell/Liquid/GHC/Resugar.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE UndecidableInstances #-}
-- | This module contains functions for "resugaring" low-level GHC `CoreExpr`
-- into high-level patterns, that can receive special case handling in
-- different phases (e.g. ANF, Constraint Generation, etc.)
module Language.Haskell.Liquid.GHC.Resugar (
-- * High-level Source Patterns
Pattern (..)
-- * Lift a CoreExpr into a Pattern
, lift
-- * Lower a pattern back into a CoreExpr
, 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 Debug.Trace
--------------------------------------------------------------------------------
-- | Data type for high-level patterns -----------------------------------------
--------------------------------------------------------------------------------
data Pattern
= PatBind
{ patE1 :: !CoreExpr
, patX :: !Var
, patE2 :: !CoreExpr
, patM :: !Type
, patDct :: !CoreExpr
, patTyA :: !Type
, patTyB :: !Type
, patFF :: !Var
} -- ^ e1 >>= \x -> e2
| PatReturn -- return @ m @ t @ $dT @ e
{ patE :: !CoreExpr -- ^ e
, patM :: !Type -- ^ m
, patDct :: !CoreExpr -- ^ $dT
, patTy :: !Type -- ^ t
, patRet :: !Var -- ^ "return"
}
| PatProject -- (case xe as x of C [x1,...,xn] -> xi) : ty
{ patXE :: !Var -- ^ xe
, patX :: !Var -- ^ x
, patTy :: !Type -- ^ ty
, patCtor :: !DataCon -- ^ C
, patBinds :: ![Var] -- ^ [x1,...,xn]
, patIdx :: !Int -- ^ i :: NatLT {len patBinds}
}
| PatSelfBind -- let x = e in x
{ patX :: !Var -- ^ x
, patE :: !CoreExpr -- ^ e
}
| PatSelfRecBind -- letrec x = e in x
{ patX :: !Var -- ^ x
, patE :: !CoreExpr -- ^ e
}
_mbId :: CoreExpr -> Maybe Var
_mbId (Var x) = Just x
_mbId (Tick _ e) = _mbId e
_mbId _ = Nothing
--------------------------------------------------------------------------------
-- | Lift expressions into High-level patterns ---------------------------------
--------------------------------------------------------------------------------
lift :: CoreExpr -> Maybe Pattern
--------------------------------------------------------------------------------
lift e = exprArgs e (collectArgs e)
exprArgs :: CoreExpr -> (CoreExpr, [CoreExpr]) -> Maybe Pattern
exprArgs _e (Var op, [Type m, d, Type a, Type b, e1, Lam x e2])
| op `is` PN.bindMName
= Just (PatBind e1 x e2 m d a b op)
exprArgs _e (Var op, [Type m, d, Type t, e])
| op `is` PN.returnMName
= Just (PatReturn e m d t op)
exprArgs (Case (Var xe) x t [(DataAlt c, ys, Var y)]) _
| Just i <- y `L.elemIndex` ys
= Just (PatProject xe x t c ys i)
{- TEMPORARILY DISBLED
exprArgs (Let (NonRec x e) e') _
| Just y <- _mbId e', x == y
= Just (PatSelfBind x e)
exprArgs (Let (Rec [(x, e)]) e') _
| Just y <- _mbId e', x == y
= Just (PatSelfRecBind x e)
-}
exprArgs _ _
= Nothing
is :: Var -> Name -> Bool
is v n = n == getName v
--------------------------------------------------------------------------------
-- | Lower patterns back into expressions --------------------------------------
--------------------------------------------------------------------------------
lower :: Pattern -> CoreExpr
--------------------------------------------------------------------------------
lower (PatBind e1 x e2 m d a b op)
= MkCore.mkCoreApps (Var op) [Type m, d, Type a, Type b, e1, Lam x e2]
lower (PatReturn e m d t op)
= MkCore.mkCoreApps (Var op) [Type m, d, Type t, e]
lower (PatProject xe x t c ys i)
= Case (Var xe) x t [(DataAlt c, ys, Var yi)] where yi = ys !! i
lower (PatSelfBind x e)
= Let (NonRec x e) (Var x)
lower (PatSelfRecBind x e)
= Let (Rec [(x, e)]) (Var x)