split up Quox.Typing

This commit is contained in:
rhiannon morris 2023-03-13 21:41:57 +01:00
parent ecd3be8bda
commit f4af1a5a78
5 changed files with 193 additions and 125 deletions

View file

@ -1,36 +1,14 @@
module Quox.Typing
import public Quox.Typing.Context as Typing
import public Quox.Typing.EqMode as Typing
import public Quox.Typing.Error as Typing
import public Quox.Syntax
import public Quox.Definition
import public Quox.Reduce
import public Data.SortedMap
import public Control.Monad.Either
import Derive.Prelude
%hide TT.Name
%default total
%language ElabReflection
%default total
public export
TContext : Type -> Nat -> Nat -> Type
TContext q d = Context (Term q d)
public export
QOutput : Type -> Nat -> Type
QOutput = Context'
public export
record TyContext q d n where
constructor MkTyContext
dctx : DimEq d
tctx : TContext q d n
%name TyContext ctx
namespace TContext
@ -99,105 +77,6 @@ InferResult : DimEq d -> TermLike
InferResult eqs q d n = IfConsistent eqs $ InferResult' q d n
public export
data EqMode = Equal | Sub | Super
%runElab derive "EqMode" [Eq, Ord, Show]
public export
data Error q
= ExpectedTYPE (Term q d n)
| ExpectedPi (Term q d n)
| ExpectedSig (Term q d n)
| ExpectedEnum (Term q d n)
| ExpectedEq (Term q d n)
| BadUniverse Universe Universe
| TagNotIn TagVal (SortedSet TagVal)
| BadCaseQtys (List (QOutput q n))
-- first arg of ClashT is the type
| ClashT EqMode (Term q d n) (Term q d n) (Term q d n)
| ClashTy EqMode (Term q d n) (Term q d n)
| ClashE EqMode (Elim q d n) (Elim q d n)
| ClashU EqMode Universe Universe
| ClashQ q q
| ClashD (Dim d) (Dim d)
| NotInScope Name
| NotType (Term q d n)
| WrongType (Term q d n) (Term q d n) (Term q d n)
-- extra context
| WhileChecking
(TyContext q d n) q
(Term q d n) -- term
(Term q d n) -- type
(Error q)
| WhileCheckingTy
(TyContext q d n)
(Term q d n)
(Maybe Universe)
(Error q)
| WhileInferring
(TyContext q d n) q
(Elim q d n)
(Error q)
| WhileComparingT
(TyContext q d n) EqMode
(Term q d n) -- type
(Term q d n) (Term q d n) -- lhs/rhs
(Error q)
| WhileComparingE
(TyContext q d n) EqMode
(Elim q d n) (Elim q d n)
(Error q)
| WhnfError WhnfError
public export
0 HasErr : Type -> (Type -> Type) -> Type
HasErr q = MonadError (Error q)
export %inline
wrapErr : HasErr q m => (Error q -> Error q) -> m a -> m a
wrapErr f act = catchError act $ throwError . f
export %inline
ucmp : EqMode -> Universe -> Universe -> Bool
ucmp Equal = (==)
ucmp Sub = (<=)
ucmp Super = (>=)
export %inline
flip : EqMode -> EqMode
flip Equal = Equal
flip Sub = Super
flip Super = Sub
parameters {auto _ : HasErr q m}
export %inline
expect : Eq a => (a -> a -> Error q) -> (a -> a -> Bool) -> a -> a -> m ()
expect err cmp x y = unless (x `cmp` y) $ throwError $ err x y
export %inline
expectEqualQ : Eq q => q -> q -> m ()
expectEqualQ = expect ClashQ (==)
export %inline
expectCompatQ : IsQty q => q -> q -> m ()
expectCompatQ = expect ClashQ $ \pi, rh => isYes $ pi `compat` rh
export %inline
expectModeU : EqMode -> Universe -> Universe -> m ()
expectModeU mode = expect (ClashU mode) $ ucmp mode
export %inline
expectEqualD : Dim d -> Dim d -> m ()
expectEqualD = expect ClashD (==)
export
lookupFree' : HasErr q m => Definitions' q g -> Name -> m (Definition' q g)
lookupFree' defs x =

View file

@ -0,0 +1,22 @@
module Quox.Typing.Context
import Quox.Syntax
import Quox.Context
public export
TContext : Type -> Nat -> Nat -> Type
TContext q d = Context (Term q d)
public export
QOutput : Type -> Nat -> Type
QOutput = Context'
public export
record TyContext q d n where
constructor MkTyContext
dctx : DimEq d
tctx : TContext q d n
%name TyContext ctx

View file

@ -0,0 +1,22 @@
module Quox.Typing.EqMode
import Quox.Syntax
import Derive.Prelude
%language ElabReflection
%default total
public export
data EqMode = Equal | Sub | Super
%runElab derive "EqMode" [Eq, Ord, Show]
export %inline
ucmp : EqMode -> Universe -> Universe -> Bool
ucmp Equal = (==)
ucmp Sub = (<=)
ucmp Super = (>=)
export %inline
flip : EqMode -> EqMode
flip Equal = Equal
flip Sub = Super
flip Super = Sub

142
lib/Quox/Typing/Error.idr Normal file
View file

@ -0,0 +1,142 @@
module Quox.Typing.Error
import Quox.Syntax
import Quox.Reduce
import Quox.Typing.Context
import Quox.Typing.EqMode
import Quox.Pretty
import Data.List
import public Control.Monad.Either
public export
data Error q
= ExpectedTYPE (Term q d n)
| ExpectedPi (Term q d n)
| ExpectedSig (Term q d n)
| ExpectedEnum (Term q d n)
| ExpectedEq (Term q d n)
| BadUniverse Universe Universe
| TagNotIn TagVal (SortedSet TagVal)
| BadCaseQtys (List (QOutput q n))
-- first arg of ClashT is the type
| ClashT EqMode (Term q d n) (Term q d n) (Term q d n)
| ClashTy EqMode (Term q d n) (Term q d n)
| ClashE EqMode (Elim q d n) (Elim q d n)
| ClashU EqMode Universe Universe
| ClashQ q q
| ClashD (Dim d) (Dim d)
| NotInScope Name
| NotType (Term q d n)
| WrongType (Term q d n) (Term q d n) (Term q d n)
-- extra context
| WhileChecking
(TyContext q d n) q
(Term q d n) -- term
(Term q d n) -- type
(Error q)
| WhileCheckingTy
(TyContext q d n)
(Term q d n)
(Maybe Universe)
(Error q)
| WhileInferring
(TyContext q d n) q
(Elim q d n)
(Error q)
| WhileComparingT
(TyContext q d n) EqMode
(Term q d n) -- type
(Term q d n) (Term q d n) -- lhs/rhs
(Error q)
| WhileComparingE
(TyContext q d n) EqMode
(Elim q d n) (Elim q d n)
(Error q)
| WhnfError WhnfError
%name Error err
public export
0 HasErr : Type -> (Type -> Type) -> Type
HasErr q = MonadError (Error q)
||| whether the error is surrounded in some context
||| (e.g. "while checking s : A, …")
public export
isErrorContext : Error q -> Bool
isErrorContext (WhileChecking {}) = True
isErrorContext (WhileCheckingTy {}) = True
isErrorContext (WhileInferring {}) = True
isErrorContext (WhileComparingT {}) = True
isErrorContext (WhileComparingE {}) = True
isErrorContext _ = False
||| remove one layer of context
export
peelContext : (e : Error q) -> (0 _ : So (isErrorContext e)) =>
(Error q -> Error q, Error q)
peelContext (WhileChecking ctx x s t err) =
(WhileChecking ctx x s t, err)
peelContext (WhileCheckingTy ctx s k err) =
(WhileCheckingTy ctx s k, err)
peelContext (WhileInferring ctx x e err) =
(WhileInferring ctx x e, err)
peelContext (WhileComparingT ctx x s t r err) =
(WhileComparingT ctx x s t r, err)
peelContext (WhileComparingE ctx x e f err) =
(WhileComparingE ctx x e f, err)
||| separates out all the error context layers
||| (e.g. "while checking s : A, …")
export
explodeContext : Error q -> (List (Error q -> Error q), Error q)
explodeContext err =
case choose $ isErrorContext err of
Left y =>
let (f, inner) = peelContext err
(fs, root) = explodeContext $ assert_smaller err inner in
(f :: fs, root)
Right n => ([], err)
||| leaves the outermost context layer, and the innermost (up to) n, and removes
||| the rest if there are more than n+1 in total
export
trimContext : Nat -> Error q -> Error q
trimContext n err =
case explodeContext err of
([], err) => err
(f :: fs, err) => f $ foldr apply err $ takeEnd n fs
where
takeEnd : Nat -> List a -> List a
takeEnd n = reverse . take n . reverse
export %inline
wrapErr : MonadError e m => (e -> e) -> m a -> m a
wrapErr f act = catchError act $ throwError . f
expect : MonadError e m => (a -> a -> e) -> (a -> a -> Bool) -> a -> a -> m ()
expect err cmp x y = unless (x `cmp` y) $ throwError $ err x y
parameters {auto _ : HasErr q m}
export %inline
expectEqualQ : Eq q => q -> q -> m ()
expectEqualQ = expect ClashQ (==)
export %inline
expectCompatQ : IsQty q => q -> q -> m ()
expectCompatQ = expect ClashQ $ \pi, rh => isYes $ pi `compat` rh
export %inline
expectModeU : EqMode -> Universe -> Universe -> m ()
expectModeU mode = expect (ClashU mode) $ ucmp mode
export %inline
expectEqualD : Dim d -> Dim d -> m ()
expectEqualD = expect ClashD (==)

View file

@ -31,6 +31,9 @@ modules =
Quox.Context,
Quox.Equal,
Quox.Name,
Quox.Typing.Context,
Quox.Typing.EqMode,
Quox.Typing.Error,
Quox.Typing,
Quox.Typechecker,
Quox.Parser.Lexer,