diff --git a/covenant.cabal b/covenant.cabal index a883e26..d35087a 100644 --- a/covenant.cabal +++ b/covenant.cabal @@ -85,6 +85,7 @@ library Control.Monad.HashCons Covenant.ASG Covenant.Constant + Covenant.Ledger Covenant.Prim other-modules: diff --git a/src/Covenant/ASG.hs b/src/Covenant/ASG.hs index e246eff..90ac9a7 100644 --- a/src/Covenant/ASG.hs +++ b/src/Covenant/ASG.hs @@ -24,7 +24,7 @@ module Covenant.ASG Bound, Ref (..), PrimCall (..), - ASGNode (Lit, Lam, Prim, App, Let), + ASGNode (Lit, Lam, Prim, App, Let, LedgerAccess, LedgerDestruct), Scope, ASG, ASGNeighbourhood, @@ -43,6 +43,8 @@ module Covenant.ASG app, lam, letBind, + ledgerAccess, + ledgerDestruct, -- ** Compile compileASG, @@ -91,7 +93,15 @@ import Covenant.Internal.ASG viewASGZipper, ) import Covenant.Internal.ASGNode - ( ASGNode (AppInternal, LamInternal, LetInternal, LitInternal, PrimInternal), + ( ASGNode + ( AppInternal, + LamInternal, + LedgerAccessInternal, + LedgerDestructInternal, + LetInternal, + LitInternal, + PrimInternal + ), Arg (Arg), Bound (Bound), Id, @@ -99,10 +109,13 @@ import Covenant.Internal.ASGNode Ref (ABound, AnArg, AnId), pattern App, pattern Lam, + pattern LedgerAccess, + pattern LedgerDestruct, pattern Let, pattern Lit, pattern Prim, ) +import Covenant.Ledger (LedgerAccessor, LedgerDestructor) import Data.Kind (Type) import Data.Monoid (Endo (Endo)) import Data.Proxy (Proxy (Proxy)) @@ -243,6 +256,31 @@ letBind Scope r f = do res <- f Scope refTo . LetInternal r $ res +-- | Construct a ledger type accessor. +-- +-- @since 1.0.0 +ledgerAccess :: + forall (m :: Type -> Type). + (MonadHashCons Id ASGNode m) => + LedgerAccessor -> + Ref -> + m Id +ledgerAccess acc = refTo . LedgerAccessInternal acc + +-- | Construct a ledger sum type destructor. The first 'Ref' must be a +-- function suitable for destructuring the second 'Ref', though we do not +-- currently check this. +-- +-- @since 1.0.0 +ledgerDestruct :: + forall (m :: Type -> Type). + (MonadHashCons Id ASGNode m) => + LedgerDestructor -> + Ref -> + Ref -> + m Id +ledgerDestruct d rFun = refTo . LedgerDestructInternal d rFun + -- | The possible moves in the 'ASGZipper' wrapper monad. These need to be -- wrapped in 'ASGMoves' to make them usable with the update monad -- implementation: see 'moveASGView' for a helper avoiding this. diff --git a/src/Covenant/Internal/ASGNode.hs b/src/Covenant/Internal/ASGNode.hs index bd2a0ee..e645fc2 100644 --- a/src/Covenant/Internal/ASGNode.hs +++ b/src/Covenant/Internal/ASGNode.hs @@ -12,11 +12,14 @@ module Covenant.Internal.ASGNode pattern Lam, pattern Let, pattern App, + pattern LedgerAccess, + pattern LedgerDestruct, childIds, ) where import Covenant.Constant (AConstant) +import Covenant.Ledger (LedgerAccessor, LedgerDestructor) import Covenant.Prim (OneArgFunc, SixArgFunc, ThreeArgFunc, TwoArgFunc) import Data.Maybe (mapMaybe) import Data.Word (Word64) @@ -124,6 +127,8 @@ data ASGNode | LamInternal Ref | LetInternal Ref Ref | AppInternal Ref Ref + | LedgerAccessInternal LedgerAccessor Ref + | LedgerDestructInternal LedgerDestructor Ref Ref deriving stock ( -- | @since 1.0.0 Eq, @@ -165,7 +170,20 @@ pattern Let rBind rBody <- LetInternal rBind rBody pattern App :: Ref -> Ref -> ASGNode pattern App rFun rArg <- AppInternal rFun rArg -{-# COMPLETE Lit, Prim, Lam, Let, App #-} +-- | An accessor for a ledger type. +-- +-- @since 1.0.0 +pattern LedgerAccess :: LedgerAccessor -> Ref -> ASGNode +pattern LedgerAccess acc rArg <- LedgerAccessInternal acc rArg + +-- | A destructor for a ledger sum. The first 'Ref' is for a destructor +-- function, while the second is the argument to be destructured. +-- +-- @since 1.0.0 +pattern LedgerDestruct :: LedgerDestructor -> Ref -> Ref -> ASGNode +pattern LedgerDestruct d rDest rArg <- LedgerDestructInternal d rDest rArg + +{-# COMPLETE Lit, Prim, Lam, Let, App, LedgerAccess, LedgerDestruct #-} -- | @since 1.0.0 childIds :: ASGNode -> [Id] @@ -179,6 +197,8 @@ childIds = \case LamInternal r1 -> mapMaybe refToId [r1] LetInternal r1 r2 -> mapMaybe refToId [r1, r2] AppInternal r1 r2 -> mapMaybe refToId [r1, r2] + LedgerAccessInternal _ r1 -> mapMaybe refToId [r1] + LedgerDestructInternal _ r1 r2 -> mapMaybe refToId [r1, r2] -- Helpers diff --git a/src/Covenant/Ledger.hs b/src/Covenant/Ledger.hs new file mode 100644 index 0000000..36b7de5 --- /dev/null +++ b/src/Covenant/Ledger.hs @@ -0,0 +1,45 @@ +module Covenant.Ledger + ( LedgerAccessor (..), + LedgerDestructor (..), + ) +where + +import Data.Text (Text) + +-- | A way of accessing a ledger type's field(s). +-- +-- @since 1.0.0 +data LedgerAccessor + = -- | For a type with a single field and a single variant, accesses that field. + LedgerUnwrap + | -- For a type with a single variant and multiple named fields, accesses the field named. + LedgerField Text + deriving stock + ( -- | @since 1.0.0 + Eq, + -- | @since 1.0.0 + Ord, + -- | @since 1.0.0 + Show + ) + +-- | A destructor for a sum type from the ledger. +-- +-- @since 1.0.0 +data LedgerDestructor + = DestructorDRep + | DestructorDelegatee + | DestructorTxCert + | DestructorVoter + | DestructorVote + | DestructorGovernanceAction + | DestructorScriptPurpose + | DestructorScriptInfo + deriving stock + ( -- | @since 1.0.0 + Eq, + -- | @since 1.0.0 + Ord, + -- | @since 1.0.0 + Show + )