progress on fixing bugs
This commit is contained in:
parent
3026a96eb7
commit
509de4415e
2 changed files with 49 additions and 29 deletions
|
|
@ -7,17 +7,16 @@ module TypeChecker.TypeChecker where
|
||||||
import Control.Monad.Except
|
import Control.Monad.Except
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
|
import Data.Bifunctor (second)
|
||||||
import Data.Foldable (traverse_)
|
import Data.Foldable (traverse_)
|
||||||
import Data.Function (on)
|
|
||||||
import Data.Functor.Identity (runIdentity)
|
import Data.Functor.Identity (runIdentity)
|
||||||
import Data.List (foldl')
|
import Data.List (foldl')
|
||||||
import Data.List.Extra (allSame)
|
import Data.List.Extra (unsnoc)
|
||||||
import Data.Map (Map)
|
import Data.Map (Map)
|
||||||
import Data.Map qualified as M
|
import Data.Map qualified as M
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
import Data.Set (Set)
|
import Data.Set (Set)
|
||||||
import Data.Set qualified as S
|
import Data.Set qualified as S
|
||||||
import Data.Tree (flatten)
|
|
||||||
import Debug.Trace (trace)
|
import Debug.Trace (trace)
|
||||||
import Grammar.Abs
|
import Grammar.Abs
|
||||||
import Grammar.Print (printTree)
|
import Grammar.Print (printTree)
|
||||||
|
|
@ -296,10 +295,13 @@ algoW = \case
|
||||||
-- probably by returning substitutions in the functions used in this body
|
-- probably by returning substitutions in the functions used in this body
|
||||||
ECase caseExpr injs -> do
|
ECase caseExpr injs -> do
|
||||||
(sub, t, e') <- algoW caseExpr
|
(sub, t, e') <- algoW caseExpr
|
||||||
(subst, t) <- checkCase t injs
|
(subst, inj_t, ret_t) <- checkCase t injs
|
||||||
let composition = subst `compose` sub
|
let composition = subst `compose` sub
|
||||||
let t' = apply composition t
|
let t' = apply composition t
|
||||||
return (composition, t', T.ECase t' e' (map (\(Inj i _) -> T.Inj (i, t') e') injs))
|
trace ("COMPOSITION: " ++ show composition) return ()
|
||||||
|
trace ("T: " ++ show t) return ()
|
||||||
|
trace ("T': " ++ show t') return ()
|
||||||
|
return (composition, t', T.ECase t' e' (map (\(Inj i _) -> T.Inj (i, inj_t) e') injs))
|
||||||
|
|
||||||
-- | Unify two types producing a new substitution
|
-- | Unify two types producing a new substitution
|
||||||
unify :: Type -> Type -> Infer Subst
|
unify :: Type -> Type -> Infer Subst
|
||||||
|
|
@ -462,6 +464,10 @@ fresh = do
|
||||||
withBinding :: (Monad m, MonadReader Ctx m) => Ident -> Poly -> m a -> m a
|
withBinding :: (Monad m, MonadReader Ctx m) => Ident -> Poly -> m a -> m a
|
||||||
withBinding i p = local (\st -> st{vars = M.insert i p (vars st)})
|
withBinding i p = local (\st -> st{vars = M.insert i p (vars st)})
|
||||||
|
|
||||||
|
-- | Run the monadic action with several additional bindings
|
||||||
|
withBindings :: (Monad m, MonadReader Ctx m) => [(Ident, Poly)] -> m a -> m a
|
||||||
|
withBindings xs = local (\st -> st{vars = foldl' (flip (uncurry M.insert)) (vars st) xs})
|
||||||
|
|
||||||
-- | Insert a function signature into the environment
|
-- | Insert a function signature into the environment
|
||||||
insertSig :: Ident -> Type -> Infer ()
|
insertSig :: Ident -> Type -> Infer ()
|
||||||
insertSig i t = modify (\st -> st{sigs = M.insert i t (sigs st)})
|
insertSig i t = modify (\st -> st{sigs = M.insert i t (sigs st)})
|
||||||
|
|
@ -473,34 +479,39 @@ insertConstr i t =
|
||||||
|
|
||||||
-------- PATTERN MATCHING ---------
|
-------- PATTERN MATCHING ---------
|
||||||
|
|
||||||
checkCase :: Type -> [Inj] -> Infer (Subst, Type)
|
checkCase :: Type -> [Inj] -> Infer (Subst, Type, Type)
|
||||||
checkCase expT injs = do
|
checkCase expT injs = do
|
||||||
(injs, returns) <- mapAndUnzipM checkInj injs
|
(injs, returns) <- mapAndUnzipM checkInj injs
|
||||||
(sub, _) <- foldM (\(sub, acc) x -> (\a -> (a `compose` sub, (a `apply` acc))) <$> unify x acc) (nullSubst, expT) injs
|
(sub, injs_type) <- foldM (\(sub, acc) x -> (\a -> (a `compose` sub, a `apply` acc)) <$> unify x acc) (nullSubst, expT) injs
|
||||||
t <- foldM (\acc x -> (`apply` acc) <$> unify x acc) (head returns) (tail returns)
|
(_, returns_type) <- foldM (\(sub, acc) x -> (\a -> (a `compose` sub, a `apply` acc)) <$> unify x acc) (nullSubst, head returns) (tail returns)
|
||||||
return (sub, t)
|
return (sub, injs_type, returns_type)
|
||||||
|
|
||||||
{- | fst = type of init
|
{- | fst = type of init
|
||||||
| snd = type of expr
|
| snd = type of expr
|
||||||
-}
|
-}
|
||||||
checkInj :: Inj -> Infer (Type, Type)
|
checkInj :: Inj -> Infer (Type, Type)
|
||||||
checkInj (Inj it expr) = do
|
checkInj (Inj it expr) = do
|
||||||
initT <- inferInit it
|
(initT, vars) <- inferInit it
|
||||||
(exprT, _) <- inferExp expr
|
let converted = map (second (Forall [])) vars
|
||||||
|
(exprT, _) <- withBindings converted (inferExp expr)
|
||||||
return (initT, exprT)
|
return (initT, exprT)
|
||||||
|
|
||||||
inferInit :: Init -> Infer Type
|
inferInit :: Init -> Infer (Type, [T.Id])
|
||||||
inferInit = \case
|
inferInit = \case
|
||||||
InitLit lit -> return $ litType lit
|
InitLit lit -> return (litType lit, mempty)
|
||||||
InitConstr fn vars -> do
|
InitConstr fn vars -> do
|
||||||
gets (M.lookup fn . constructors) >>= \case
|
gets (M.lookup fn . constructors) >>= \case
|
||||||
Nothing -> throwError $ "Constructor: " ++ printTree fn ++ " does not exist"
|
Nothing -> throwError $ "Constructor: " ++ printTree fn ++ " does not exist"
|
||||||
Just a -> do
|
Just a -> do
|
||||||
let ft = init $ flattenType a
|
case unsnoc $ flattenType a of
|
||||||
case compare (length vars) (length ft) of
|
Nothing -> throwError "Partial pattern match not allowed"
|
||||||
EQ -> return . last $ flattenType a
|
Just (vs, ret) ->
|
||||||
_ -> throwError "Partial pattern match not allowed"
|
case length vars `compare` length vs of
|
||||||
InitCatch -> fresh
|
EQ -> do
|
||||||
|
trace ("IDS AND TYPES: " ++ show (zip vars vs)) return ()
|
||||||
|
return (ret, zip vars vs)
|
||||||
|
_ -> throwError "Partial pattern match not allowed"
|
||||||
|
InitCatch -> (,mempty) <$> fresh
|
||||||
|
|
||||||
flattenType :: Type -> [Type]
|
flattenType :: Type -> [Type]
|
||||||
flattenType (TArr a b) = flattenType a ++ flattenType b
|
flattenType (TArr a b) = flattenType a ++ flattenType b
|
||||||
|
|
|
||||||
27
test_program
27
test_program
|
|
@ -1,15 +1,24 @@
|
||||||
data Bool () where {
|
-- data Bool () where {
|
||||||
True : Bool ()
|
-- True : Bool ()
|
||||||
False : Bool ()
|
-- False : Bool ()
|
||||||
};
|
-- };
|
||||||
|
|
||||||
data Maybe ('a) where {
|
data Maybe ('a) where {
|
||||||
Nothing : Maybe ('a)
|
Nothing : Maybe ('a)
|
||||||
Just : 'a -> Maybe ('a)
|
Just : 'a -> Maybe ('a)
|
||||||
};
|
};
|
||||||
|
|
||||||
main : Bool () -> Maybe (Bool ()) ;
|
-- main : Bool () -> Maybe (Bool ()) ;
|
||||||
main x = case x of {
|
-- main x =
|
||||||
True => Nothing;
|
-- case x of {
|
||||||
False => Just 0
|
-- True => Nothing;
|
||||||
}
|
-- False => Just True
|
||||||
|
-- };
|
||||||
|
|
||||||
|
fun : Maybe (_Int) -> _Int ;
|
||||||
|
fun a =
|
||||||
|
case a of {
|
||||||
|
Just b => b;
|
||||||
|
Nothing => 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue