-- | 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
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 :: 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 -> ScopedRenameT m (Term name uni fun ann))
-> ScopedRenameT 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 -> ScopedRenameT m (Term name uni fun ann))
 -> ScopedRenameT m (Term name uni fun ann))
-> (name -> ScopedRenameT m (Term name uni fun ann))
-> ScopedRenameT 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)
-> ScopedRenameT m (Term name uni fun ann)
-> ScopedRenameT m (Term name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann -> ScopedRenameT 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)
-> ScopedRenameT 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 -> ScopedRenameT 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)
-> ScopedRenameT m (Term name uni fun ann)
-> ScopedRenameT m (Term name uni fun ann)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Term name uni fun ann -> ScopedRenameT 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 -> ScopedRenameT m (Term name uni fun ann)
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
-> ScopedRenameT 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)
-> ScopedRenameT m (Term name uni fun ann)
-> ScopedRenameT m (Term name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann -> ScopedRenameT 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)
-> ScopedRenameT m (Term name uni fun ann)
-> ScopedRenameT m (Term name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann -> ScopedRenameT 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 con :: Term name uni fun ann
con@Constant{}             = Term name uni fun ann -> ScopedRenameT m (Term name uni fun ann)
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 -> ScopedRenameT m (Term name uni fun ann)
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 :: Program name uni fun ann
-> ScopedRenameT m (Program name uni fun ann)
renameProgramM (Program ann
ann Version ann
ver Term name uni fun ann
term) = ann
-> Version ann -> Term name uni fun ann -> Program name uni fun ann
forall name (uni :: * -> *) fun ann.
ann
-> Version ann -> Term name uni fun ann -> Program name uni fun ann
Program ann
ann Version ann
ver (Term name uni fun ann -> Program name uni fun ann)
-> RenameT ScopedRenaming m (Term name uni fun ann)
-> ScopedRenameT 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