packages feed

lambda-calculator-3.1.0.0: src/Language/Lambda/SystemF.hs

module Language.Lambda.SystemF (
  evalText,
  typecheckText,
  runEvalText,
  runTypecheckText,
  execEvalText,
  execTypecheckText,
  unsafeExecEvalText,
  unsafeExecTypecheckText,
  defaultUniques,
  defaultTyUniques,
  mkState,

  module Language.Lambda.SystemF.Expression,
  module Language.Lambda.SystemF.Parser,
  module Language.Lambda.SystemF.State
  ) where

import Language.Lambda.Shared.Errors
import Language.Lambda.Shared.UniqueSupply (defaultUniques, defaultTyUniques)
import Language.Lambda.SystemF.Eval (evalExpr)
import Language.Lambda.SystemF.Expression
import Language.Lambda.SystemF.Parser
import Language.Lambda.SystemF.State
import Language.Lambda.SystemF.TypeCheck

import Control.Monad.Except
import RIO
import qualified RIO.Text as Text
import qualified RIO.Map as Map

evalText
  :: Text
  -> Typecheck Text (TypedExpr Text)
evalText = either throwParseError processExpr . parseExpr
    where throwParseError = throwError . ParseError . Text.pack . show

typecheckText
  :: Text
  -> Typecheck Text (Ty Text)
typecheckText = either throwParseError typecheck . parseExpr
    where throwParseError = throwError . ParseError . Text.pack . show

runEvalText
  :: Text
  -> Globals Text
  -> Either LambdaException (TypedExpr Text, TypecheckState Text)
runEvalText input globals' = runTypecheck (evalText input) (mkState globals')

runTypecheckText
  :: Text
  -> Globals Text
  -> Either LambdaException (Ty Text, TypecheckState Text)
runTypecheckText input globals'
  = runTypecheck (typecheckText input) (mkState globals')

execEvalText
  :: Text
  -> Globals Text
  -> Either LambdaException (TypedExpr Text)
execEvalText input globals'
  = execTypecheck (evalText input) (mkState globals')

execTypecheckText
  :: Text
  -> Globals Text
  -> Either LambdaException (Ty Text)
execTypecheckText input globals'
  = execTypecheck (typecheckText input) (mkState globals')

unsafeExecEvalText
  :: Text
  -> Globals Text
  -> TypedExpr Text
unsafeExecEvalText input globals'
  = unsafeExecTypecheck (evalText input) (mkState globals')

unsafeExecTypecheckText
  :: Text
  -> Globals Text
  -> Ty Text
unsafeExecTypecheckText input globals'
  = unsafeExecTypecheck (typecheckText input) (mkState globals')

mkState :: Globals Text -> TypecheckState Text
mkState globals' = TypecheckState globals' defaultUniques defaultTyUniques

processExpr :: SystemFExpr Text -> Typecheck Text (TypedExpr Text)
processExpr (Let n expr) = tcAndEval expr >>= addBinding n
processExpr expr = tcAndEval expr

tcAndEval :: SystemFExpr Text -> Typecheck Text (TypedExpr Text)
tcAndEval expr = do
  ty <- typecheck expr
  reduced <- evalExpr expr

  pure $ TypedExpr reduced ty

addBinding :: Text -> TypedExpr Text -> Typecheck Text (TypedExpr Text)
addBinding name expr = modifyGlobals (Map.insert name expr) >> pure expr