{-# LANGUAGE FlexibleInstances #-}
module Language.Lambda.Untyped (
  evalText,
  runEvalText,
  execEvalText,
  unsafeExecEvalText,
  defaultUniques,

  module Language.Lambda.Untyped.Expression,
  module Language.Lambda.Untyped.Eval,
  module Language.Lambda.Untyped.Parser,
  module Language.Lambda.Untyped.State
  ) where

import Control.Monad.Except
import Data.Either
import RIO
import qualified RIO.Text as Text

import Language.Lambda.Shared.Errors
import Language.Lambda.Shared.UniqueSupply (defaultUniques)
import Language.Lambda.Untyped.Eval
import Language.Lambda.Untyped.Expression
import Language.Lambda.Untyped.Parser
import Language.Lambda.Untyped.State

evalText :: Text -> Eval Text (LambdaExpr Text)
evalText :: Text -> Eval Text (LambdaExpr Text)
evalText = (ParseError -> Eval Text (LambdaExpr Text))
-> (LambdaExpr Text -> Eval Text (LambdaExpr Text))
-> Either ParseError (LambdaExpr Text)
-> Eval Text (LambdaExpr Text)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ParseError -> Eval Text (LambdaExpr Text)
forall a.
ParseError -> StateT (EvalState Text) (Except LambdaException) a
throwParseError LambdaExpr Text -> Eval Text (LambdaExpr Text)
evalExpr' (Either ParseError (LambdaExpr Text)
 -> Eval Text (LambdaExpr Text))
-> (Text -> Either ParseError (LambdaExpr Text))
-> Text
-> Eval Text (LambdaExpr Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either ParseError (LambdaExpr Text)
parseExpr
  where throwParseError :: ParseError -> StateT (EvalState Text) (Except LambdaException) a
throwParseError = LambdaException
-> StateT (EvalState Text) (Except LambdaException) a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LambdaException
 -> StateT (EvalState Text) (Except LambdaException) a)
-> (ParseError -> LambdaException)
-> ParseError
-> StateT (EvalState Text) (Except LambdaException) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> LambdaException
ParseError (Text -> LambdaException)
-> (ParseError -> Text) -> ParseError -> LambdaException
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
Text.pack (String -> Text) -> (ParseError -> String) -> ParseError -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseError -> String
forall a. Show a => a -> String
show
        evalExpr' :: LambdaExpr Text -> Eval Text (LambdaExpr Text)
evalExpr' = LambdaExpr Text -> Eval Text (LambdaExpr Text)
forall name.
(Pretty name, Ord name) =>
LambdaExpr name -> Eval name (LambdaExpr name)
evalExpr

runEvalText
  :: Text
  -> Globals Text
  -> Either LambdaException (LambdaExpr Text, EvalState Text)
runEvalText :: Text
-> Globals Text
-> Either LambdaException (LambdaExpr Text, EvalState Text)
runEvalText Text
input Globals Text
globals' = Eval Text (LambdaExpr Text)
-> EvalState Text
-> Either LambdaException (LambdaExpr Text, EvalState Text)
forall name result.
Eval name result
-> EvalState name
-> Either LambdaException (result, EvalState name)
runEval (Text -> Eval Text (LambdaExpr Text)
evalText Text
input) (Globals Text -> EvalState Text
mkState Globals Text
globals')

execEvalText
  :: Text
  -> Globals Text
  -> Either LambdaException (LambdaExpr Text)
execEvalText :: Text -> Globals Text -> Either LambdaException (LambdaExpr Text)
execEvalText Text
input Globals Text
globals' = Eval Text (LambdaExpr Text)
-> EvalState Text -> Either LambdaException (LambdaExpr Text)
forall name result.
Eval name result -> EvalState name -> Either LambdaException result
execEval (Text -> Eval Text (LambdaExpr Text)
evalText Text
input) (Globals Text -> EvalState Text
mkState Globals Text
globals')

unsafeExecEvalText
  :: Text
  -> Globals Text
  -> LambdaExpr Text
unsafeExecEvalText :: Text -> Globals Text -> LambdaExpr Text
unsafeExecEvalText Text
input Globals Text
globals'
  = Eval Text (LambdaExpr Text) -> EvalState Text -> LambdaExpr Text
forall name result. Eval name result -> EvalState name -> result
unsafeExecEval (Text -> Eval Text (LambdaExpr Text)
evalText Text
input) (Globals Text -> EvalState Text
mkState Globals Text
globals')

mkState :: Globals Text -> EvalState Text
mkState :: Globals Text -> EvalState Text
mkState = (Globals Text -> [Text] -> EvalState Text)
-> [Text] -> Globals Text -> EvalState Text
forall a b c. (a -> b -> c) -> b -> a -> c
flip Globals Text -> [Text] -> EvalState Text
forall name. Globals name -> [name] -> EvalState name
EvalState [Text]
defaultUniques