-- | The internal module of the renamer that defines the actual algorithms,
-- but not the user-facing API.

module UntypedPlutusCore.Rename.Internal
    ( module Export
    , renameTermM
    , renameProgramM
    ) where

import UntypedPlutusCore.Core

import PlutusCore.Core (HasUniques)
import PlutusCore.Name.Unique
import PlutusCore.Quote
import PlutusCore.Rename.Monad as Export


-- | Rename a 'Term' in the 'RenameM' monad.
renameTermM
    :: (HasUniques (Term name uni fun ann), MonadQuote m)
    => Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
renameTermM :: forall name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term name uni fun ann), MonadQuote m) =>
Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
renameTermM (LamAbs ann
ann name
name Term name uni fun ann
body)  =
     name
-> (name -> RenameT ScopedRenaming m (Term name uni fun ann))
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall ren unique name (m :: * -> *) c.
(HasRenaming ren unique, HasUnique name unique, MonadQuote m,
 MonadReader ren m) =>
name -> (name -> m c) -> m c
withFreshenedName name
name ((name -> RenameT ScopedRenaming m (Term name uni fun ann))
 -> RenameT ScopedRenaming m (Term name uni fun ann))
-> (name -> RenameT ScopedRenaming m (Term name uni fun ann))
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall a b. (a -> b) -> a -> b
$ \name
nameFr -> ann -> name -> Term name uni fun ann -> Term name uni fun ann
forall name (uni :: * -> *) fun ann.
ann -> name -> Term name uni fun ann -> Term name uni fun ann
LamAbs ann
ann name
nameFr (Term name uni fun ann -> Term name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term name uni fun ann), MonadQuote m) =>
Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
renameTermM Term name uni fun ann
body
renameTermM (Apply ann
ann Term name uni fun ann
fun Term name uni fun ann
arg)        = ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply ann
ann (Term name uni fun ann
 -> Term name uni fun ann -> Term name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
-> RenameT
     ScopedRenaming m (Term name uni fun ann -> Term name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term name uni fun ann), MonadQuote m) =>
Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
renameTermM Term name uni fun ann
fun RenameT
  ScopedRenaming m (Term name uni fun ann -> Term name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall a b.
RenameT ScopedRenaming m (a -> b)
-> RenameT ScopedRenaming m a -> RenameT ScopedRenaming m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term name uni fun ann), MonadQuote m) =>
Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
renameTermM Term name uni fun ann
arg
renameTermM err :: Term name uni fun ann
err@Error{}                = Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall a. a -> RenameT ScopedRenaming m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Term name uni fun ann
err
renameTermM (Var ann
ann name
name)             = ann -> name -> Term name uni fun ann
forall name (uni :: * -> *) fun ann.
ann -> name -> Term name uni fun ann
Var ann
ann (name -> Term name uni fun ann)
-> RenameT ScopedRenaming m name
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> name -> RenameT ScopedRenaming m name
forall ren unique name (m :: * -> *).
(HasRenaming ren unique, HasUnique name unique,
 MonadReader ren m) =>
name -> m name
renameNameM name
name
renameTermM (Delay ann
ann Term name uni fun ann
term)           = ann -> Term name uni fun ann -> Term name uni fun ann
forall name (uni :: * -> *) fun ann.
ann -> Term name uni fun ann -> Term name uni fun ann
Delay ann
ann (Term name uni fun ann -> Term name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term name uni fun ann), MonadQuote m) =>
Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
renameTermM Term name uni fun ann
term
renameTermM (Force ann
ann Term name uni fun ann
term)           = ann -> Term name uni fun ann -> Term name uni fun ann
forall name (uni :: * -> *) fun ann.
ann -> Term name uni fun ann -> Term name uni fun ann
Force ann
ann (Term name uni fun ann -> Term name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term name uni fun ann), MonadQuote m) =>
Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
renameTermM Term name uni fun ann
term
renameTermM (Constr ann
ann Word64
i [Term name uni fun ann]
es)          = ann -> Word64 -> [Term name uni fun ann] -> Term name uni fun ann
forall name (uni :: * -> *) fun ann.
ann -> Word64 -> [Term name uni fun ann] -> Term name uni fun ann
Constr ann
ann Word64
i ([Term name uni fun ann] -> Term name uni fun ann)
-> RenameT ScopedRenaming m [Term name uni fun ann]
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Term name uni fun ann
 -> RenameT ScopedRenaming m (Term name uni fun ann))
-> [Term name uni fun ann]
-> RenameT ScopedRenaming m [Term name uni fun ann]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term name uni fun ann), MonadQuote m) =>
Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
renameTermM [Term name uni fun ann]
es
renameTermM (Case ann
ann Term name uni fun ann
arg Vector (Term name uni fun ann)
cs)          = ann
-> Term name uni fun ann
-> Vector (Term name uni fun ann)
-> Term name uni fun ann
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Vector (Term name uni fun ann)
-> Term name uni fun ann
Case ann
ann (Term name uni fun ann
 -> Vector (Term name uni fun ann) -> Term name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
-> RenameT
     ScopedRenaming
     m
     (Vector (Term name uni fun ann) -> Term name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term name uni fun ann), MonadQuote m) =>
Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
renameTermM Term name uni fun ann
arg RenameT
  ScopedRenaming
  m
  (Vector (Term name uni fun ann) -> Term name uni fun ann)
-> RenameT ScopedRenaming m (Vector (Term name uni fun ann))
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall a b.
RenameT ScopedRenaming m (a -> b)
-> RenameT ScopedRenaming m a -> RenameT ScopedRenaming m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Term name uni fun ann
 -> RenameT ScopedRenaming m (Term name uni fun ann))
-> Vector (Term name uni fun ann)
-> RenameT ScopedRenaming m (Vector (Term name uni fun ann))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Vector a -> f (Vector b)
traverse Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term name uni fun ann), MonadQuote m) =>
Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
renameTermM Vector (Term name uni fun ann)
cs
renameTermM con :: Term name uni fun ann
con@Constant{}             = Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall a. a -> RenameT ScopedRenaming m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Term name uni fun ann
con
renameTermM bi :: Term name uni fun ann
bi@Builtin{}               = Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall a. a -> RenameT ScopedRenaming m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Term name uni fun ann
bi

-- | Rename a 'Program' in the 'RenameM' monad.
renameProgramM
    :: (HasUniques (Program name uni fun ann), MonadQuote m)
    => Program name uni fun ann -> ScopedRenameT m (Program name uni fun ann)
renameProgramM :: forall name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Program name uni fun ann), MonadQuote m) =>
Program name uni fun ann
-> ScopedRenameT m (Program name uni fun ann)
renameProgramM (Program ann
ann Version
ver Term name uni fun ann
term) = ann -> Version -> Term name uni fun ann -> Program name uni fun ann
forall name (uni :: * -> *) fun ann.
ann -> Version -> Term name uni fun ann -> Program name uni fun ann
Program ann
ann Version
ver (Term name uni fun ann -> Program name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
-> RenameT ScopedRenaming m (Program name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann
-> RenameT ScopedRenaming m (Term name uni fun ann)
forall name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term name uni fun ann), MonadQuote m) =>
Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
renameTermM Term name uni fun ann
term