{-# LANGUAGE ImpredicativeTypes #-}

module Plutarch.Evaluate (
  E.evalScript,
  E.evalScriptHuge,
  E.evalScript',
  E.EvalError,
  evalTerm,
) where

import Plutarch.Internal.Evaluate qualified as E

import Data.Text (Text)
import Plutarch.Internal (ClosedTerm, Config, RawTerm (RCompiled), Term (..), TermResult (TermResult), compile)
import Plutarch.Script (Script (Script))
import PlutusCore.Evaluation.Machine.ExBudget (ExBudget)
import UntypedPlutusCore qualified as UPLC

-- | Compile and evaluate term.
evalTerm ::
  Config ->
  ClosedTerm a ->
  Either Text (Either E.EvalError (ClosedTerm a), ExBudget, [Text])
evalTerm :: forall (a :: PType).
Config
-> ClosedTerm a
-> Either Text (Either EvalError (ClosedTerm a), ExBudget, [Text])
evalTerm Config
config ClosedTerm a
term =
  case forall (a :: PType). Config -> ClosedTerm a -> Either Text Script
compile Config
config ClosedTerm a
term of
    Right Script
script ->
      let (Either EvalError Script
s, ExBudget
b, [Text]
t) = Script -> (Either EvalError Script, ExBudget, [Text])
E.evalScriptHuge Script
script
       in forall a b. b -> Either a b
Right (forall (a :: PType). Script -> ClosedTerm a
fromScript forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Either EvalError Script
s, ExBudget
b, [Text]
t)
    Left Text
a -> forall a b. a -> Either a b
Left Text
a
  where
    fromScript :: Script -> ClosedTerm a
    fromScript :: forall (a :: PType). Script -> ClosedTerm a
fromScript (Script Program DeBruijn DefaultUni DefaultFun ()
script) =
      forall (s :: S) (a :: PType).
(Word64 -> TermMonad TermResult) -> Term s a
Term forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ RawTerm -> [HoistedTerm] -> TermResult
TermResult (UTerm -> RawTerm
RCompiled forall a b. (a -> b) -> a -> b
$ forall name (uni :: Type -> Type) fun ann.
Program name uni fun ann -> Term name uni fun ann
UPLC._progTerm Program DeBruijn DefaultUni DefaultFun ()
script) []