ddc-core-0.3.1.1: DDC/Core/Exp/Base.hs
module DDC.Core.Exp.Base where
import DDC.Core.DaCon
import DDC.Type.Exp
import DDC.Type.Sum ()
-- Values ---------------------------------------------------------------------
-- | Well-typed expressions produce `Data` values when evaluated,
-- and their types aways have kind '*' (Data)
data Exp a n
-- | 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 !(Type n)
-- | Witness can appear as the argument of an application.
| XWitness !(Witness n)
deriving (Eq, Show)
deriving instance Eq n => Eq (DaCon n)
-- | 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)
-- | Weaken the closure of an expression.
-- The closures of these expressions are added to the closure
-- of the body.
| CastWeakenClosure ![Exp a n]
-- | Purify the effect (action) of an expression.
| CastPurify !(Witness n)
-- | Forget about the closure (sharing) of an expression.
| CastForget !(Witness n)
deriving (Eq, Show)
-- | Possibly recursive bindings.
data Lets a n
-- | Non-recursive expression binding.
= LLet !(LetMode n) !(Bind n) !(Exp a n)
-- | Recursive binding of lambda abstractions.
| LRec ![(Bind n, Exp a n)]
-- | Bind a local region variable,
-- and witnesses to its properties.
| LLetRegions ![Bind n] ![Bind n]
-- | Holds a region handle during evaluation.
| LWithRegion !(Bound n)
deriving (Eq, Show)
-- | Describes how a let binding should be evaluated.
data LetMode n
-- | Evaluate binding before substituting the result.
= LetStrict
-- | Use lazy evaluation.
-- The witness shows that the head region of the bound expression
-- can contain thunks (is lazy), or Nothing if there is no head region.
| LetLazy !(Maybe (Witness n))
deriving (Eq, Show)
-- | Case alternatives.
data Alt a n
= AAlt !(Pat n) !(Exp a n)
deriving (Eq, Show)
-- | Pattern matching.
data Pat n
-- | The default pattern always succeeds.
= PDefault
-- | Match a data constructor and bind its arguments.
| PData !(DaCon n) ![Bind n]
deriving (Eq, Show)
-- Witness --------------------------------------------------------------------
-- | When a witness exists in the program it guarantees that a
-- certain property of the program is true.
data Witness n
-- | Witness variable.
= WVar !(Bound n)
-- | Witness constructor.
| WCon !(WiCon n)
-- | Witness application.
| WApp !(Witness n) !(Witness n)
-- | Joining of witnesses.
| WJoin !(Witness n) !(Witness n)
-- | Type can appear as the argument of an application.
| WType !(Type n)
deriving (Eq, Show)
-- | Witness constructors.
data WiCon n
-- | Witness constructors baked into the language.
= WiConBuiltin !WbCon
-- | Witness constructors defined in the environment.
-- In the interpreter we use this to hold runtime capabilities.
-- The attached type must be closed.
| WiConBound !(Bound n) !(Type n)
deriving (Eq, Show)
-- | Built-in witness constructors.
--
-- These are used to convert a runtime capability into a witness that
-- the corresponding property is true.
data WbCon
-- | (axiom) The pure effect is pure.
--
-- @pure :: Pure !0@
= WbConPure
-- | (axiom) The empty closure is empty.
--
-- @empty :: Empty $0@
| WbConEmpty
-- | Convert a capability guaranteeing that a region is in the global
-- heap, into a witness that a closure using this region is empty.
-- This lets us rely on the garbage collector to reclaim objects
-- in the region. It is needed when we suspend the evaluation of
-- expressions that have a region in their closure, because the
-- type of the returned thunk may not reveal that it references
-- objects in that region.
--
-- @use :: [r : %]. Global r => Empty (Use r)@
| WbConUse
-- | Convert a capability guaranteeing the constancy of a region, into
-- a witness that a read from that region is pure.
-- This lets us suspend applications that read constant objects,
-- because it doesn't matter if the read is delayed, we'll always
-- get the same result.
--
-- @read :: [r : %]. Const r => Pure (Read r)@
| WbConRead
-- | Convert a capability guaranteeing the constancy of a region, into
-- a witness that allocation into that region is pure.
-- This lets us increase the sharing of constant objects,
-- because we can't tell constant objects of the same value apart.
--
-- @alloc :: [r : %]. Const r => Pure (Alloc r)@
| WbConAlloc
deriving (Eq, Show)