a type theory with equality based on setoids
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.5 KiB

  1. {-# LANGUAGE FlexibleContexts #-}
  2. {-# LANGUAGE DerivingVia #-}
  3. module Elaboration.Monad where
  4. import Control.Monad.Except
  5. import Control.Monad.Reader
  6. import Control.Applicative
  7. import qualified Data.HashMap.Strict as HashMap
  8. import qualified Data.Sequence as Seq
  9. import Data.HashMap.Strict (HashMap)
  10. import Data.Text (Text)
  11. import Syntax
  12. import Value
  13. data ElabState =
  14. ElabState
  15. { elabEnv :: {-# UNPACK #-} !Env
  16. , elabLevel :: {-# UNPACK #-} !Level
  17. , elabSwitches :: {-# UNPACK #-} !Int
  18. , elabNames :: HashMap Text (Level, VTy)
  19. , elabConstrs :: HashMap Text VTy
  20. , elabBound :: [BoundDef]
  21. , elabSourcePos :: ((Int, Int), (Int, Int))
  22. }
  23. deriving (Eq)
  24. emptyElabState :: ElabState
  25. emptyElabState = ElabState emptyEnv (Lvl 0) 0 mempty mempty [] ((0, 0), (0, 0))
  26. getNames :: MonadReader ElabState m => m [Text]
  27. getNames = asks (map go . elabBound) where
  28. go (BDBound n) = n
  29. go (BDDefined n) = n
  30. data ElabError
  31. = NotInScope Text
  32. | NotFunction [Text] Term
  33. | NotEqual [Text] Term Term
  34. | CantSolveMeta [Text] Term Term
  35. deriving (Show)
  36. data ProgError
  37. = ProgError { peErr :: ElabError
  38. , peSL :: !Int
  39. , peSC :: !Int
  40. , peEL :: !Int
  41. , peEC :: !Int
  42. }
  43. deriving (Show)
  44. newtype ElabM a
  45. = ElabM { runElab :: ElabState -> IO (Either [ProgError] a) }
  46. deriving
  47. ( Functor
  48. , Applicative
  49. , Monad
  50. , Alternative
  51. , MonadPlus
  52. , MonadReader ElabState
  53. , MonadError [ProgError]
  54. , MonadIO
  55. )
  56. via ReaderT ElabState (ExceptT [ProgError] IO)
  57. typeError :: ElabError -> ElabM a
  58. typeError err = do
  59. (s, e) <- asks elabSourcePos
  60. throwError [uncurry (uncurry (ProgError err) s) e]
  61. assumeLocal :: Text -> VTy -> ElabM a -> ElabM a
  62. assumeLocal name tipe = local go where
  63. go r =
  64. r { elabLevel = succ (elabLevel r)
  65. , elabNames = HashMap.insert name (elabLevel r, tipe) (elabNames r)
  66. , elabEnv = (elabEnv r) {
  67. locals = VGlued (HVar (Bound (unLvl (elabLevel r)))) mempty Nothing
  68. Seq.<| locals (elabEnv r)
  69. }
  70. , elabBound = BDBound name:elabBound r
  71. }
  72. defineLocal :: Text -> VTy -> Value -> ElabM a -> ElabM a
  73. defineLocal name tipe val = local go where
  74. go r =
  75. r { elabLevel = succ (elabLevel r)
  76. , elabNames = HashMap.insert name (elabLevel r, tipe) (elabNames r)
  77. , elabEnv = (elabEnv r) {
  78. locals = val Seq.<| locals (elabEnv r)
  79. }
  80. , elabBound = BDDefined name:elabBound r
  81. }