ddc-source-tetra-0.4.1.1: DDC/Source/Tetra/Exp/Base.hs
module DDC.Source.Tetra.Exp.Base
( module DDC.Type.Exp
-- * Expressions
, Exp (..)
, Lets (..)
, Alt (..)
, Pat (..)
, Cast (..)
-- * Witnesses
, Witness (..)
-- * Data Constructors
, DaCon (..)
-- * Witness Constructors
, WiCon (..)
, WbCon (..))
where
import DDC.Type.Exp
import DDC.Type.Sum ()
import Control.DeepSeq
import DDC.Core.Exp
( Witness (..)
, WiCon (..)
, WbCon (..)
, Pat (..)
, DaCon (..))
-- | Well-typed expressions have types of kind `Data`.
data Exp a n
---------------------------------------------------
-- Core Language Constructs.
-- These are also in the core language, and after desugaring only
-- these constructs are used.
--
-- | Value variable or primitive operation.
= XVar !a !(Bound n)
-- | Data constructor or literal.
| XCon !a !(DaCon n)
-- | Type abstraction (level-1).
| XLAM !a !(Bind n) !(Exp a n)
-- | Value and Witness abstraction (level-0).
| XLam !a !(Bind n) !(Exp a n)
-- | Application.
| XApp !a !(Exp a n) !(Exp a n)
-- | Possibly recursive bindings.
| XLet !a !(Lets a n) !(Exp a n)
-- | Case branching.
| XCase !a !(Exp a n) ![Alt a n]
-- | Type cast.
| XCast !a !(Cast a n) !(Exp a n)
-- | Type can appear as the argument of an application.
| XType !a !(Type n)
-- | Witness can appear as the argument of an application.
| XWitness !a !(Witness a n)
---------------------------------------------------
-- Sugar Constructs.
-- These constructs are eliminated by the desugarer.
--
-- | Some expressions and infix operators that need to be resolved into
-- proper function applications.
| XDefix !a [Exp a n]
-- | Use of a naked infix operator, like in 1 + 2.
-- INVARIANT: only appears in the list of an XDefix node.
| XInfixOp !a String
-- | Use of an infix operator as a plain variable, like in (+) 1 2.
-- INVARIANT: only appears in the list of an XDefix node.
| XInfixVar !a String
deriving (Show, Eq)
-- | Possibly recursive bindings.
data Lets a n
-- | Non-recursive let-binding.
= LLet !(Bind n) !(Exp a n)
-- | Recursive let bindings.
| LRec ![(Bind n, Exp a n)]
-- | Bind a local region variable,
-- and witnesses to its properties.
| LPrivate ![Bind n] !(Maybe (Type n)) ![Bind n]
deriving (Show, Eq)
-- | Case alternatives.
data Alt a n
= AAlt !(Pat n) !(Exp a n)
deriving (Show, Eq)
-- | Type casts.
data Cast a n
-- | Weaken the effect of an expression.
-- The given effect is added to the effect
-- of the body.
= CastWeakenEffect !(Effect n)
-- | Purify the effect (action) of an expression.
| CastPurify !(Witness a n)
-- | Box a computation,
-- capturing its effects in the S computation type.
| CastBox
-- | Run a computation,
-- releasing its effects into the environment.
| CastRun
deriving (Show, Eq)
-- NFData ---------------------------------------------------------------------
instance (NFData a, NFData n) => NFData (Exp a n) where
rnf xx
= case xx of
XVar a u -> rnf a `seq` rnf u
XCon a dc -> rnf a `seq` rnf dc
XLAM a b x -> rnf a `seq` rnf b `seq` rnf x
XLam a b x -> rnf a `seq` rnf b `seq` rnf x
XApp a x1 x2 -> rnf a `seq` rnf x1 `seq` rnf x2
XLet a lts x -> rnf a `seq` rnf lts `seq` rnf x
XCase a x alts -> rnf a `seq` rnf x `seq` rnf alts
XCast a c x -> rnf a `seq` rnf c `seq` rnf x
XType a t -> rnf a `seq` rnf t
XWitness a w -> rnf a `seq` rnf w
XDefix a xs -> rnf a `seq` rnf xs
XInfixOp a s -> rnf a `seq` rnf s
XInfixVar a s -> rnf a `seq` rnf s
instance (NFData a, NFData n) => NFData (Cast a n) where
rnf cc
= case cc of
CastWeakenEffect e -> rnf e
CastPurify w -> rnf w
CastBox -> ()
CastRun -> ()
instance (NFData a, NFData n) => NFData (Lets a n) where
rnf lts
= case lts of
LLet b x -> rnf b `seq` rnf x
LRec bxs -> rnf bxs
LPrivate bs1 mR bs2 -> rnf bs1 `seq` rnf mR `seq` rnf bs2
instance (NFData a, NFData n) => NFData (Alt a n) where
rnf aa
= case aa of
AAlt w x -> rnf w `seq` rnf x