perga/lib/Program.hs

53 lines
1.7 KiB
Haskell
Raw Normal View History

module Program where
import Check
import Control.Monad.Except
import qualified Data.Map.Strict as M
import Elaborator
import Errors
import Eval (Env, checkBeta)
import qualified Eval
import Expr (Expr)
import qualified Expr
import IR
import Parser (parseProgram)
import Preprocessor (runPreprocessor)
insertDef :: Text -> Expr -> Expr -> Env -> Env
insertDef name ty body = M.insert name (Eval.Def ty body)
handleDef :: IRDef -> StateT Env Result ()
handleDef (Axiom name ty) = do
env <- get
2024-12-01 18:06:03 -08:00
_ <- liftEither $ checkType env $ elaborate ty
modify $ insertDef name (elaborate ty) (Expr.Axiom name)
handleDef (Def name Nothing irBody) = do
env <- get
2024-12-01 18:06:03 -08:00
ty <- liftEither $ checkType env body
modify $ insertDef name ty body
where
body = elaborate irBody
handleDef (Def name (Just irTy) irBody) = do
env <- get
2024-12-01 18:06:03 -08:00
ty' <- liftEither $ checkType env body
_ <- liftEither $ checkType env ty
2024-12-01 18:06:03 -08:00
liftEither $ checkBeta env ty ty' body
modify $ insertDef name ty' body
where
body = elaborate irBody
ty = elaborate irTy
2024-12-04 17:46:50 -08:00
handleDef (Variable name ty) = undefined
handleDef (Section name contents) = undefined
evalDef :: Env -> IRDef -> Result Env
evalDef = flip (execStateT . handleDef)
2024-12-01 18:06:03 -08:00
handleProgram :: Env -> IRProgram -> Result Env
handleProgram env = flip execStateT env . mapM_ handleDef
2024-12-01 18:06:03 -08:00
handleAndParseProgram :: Env -> String -> Text -> Either String Env
handleAndParseProgram env filename input = (first toString . handleProgram env) =<< parseProgram filename input
2024-12-01 18:06:03 -08:00
handleAndParseFile :: Env -> String -> ExceptT String IO Env
handleAndParseFile env filename = toString `withExceptT` runPreprocessor filename >>= hoistEither . handleAndParseProgram env filename