more error messages and better unification

This commit is contained in:
sebastianselander 2023-03-24 18:21:07 +01:00
parent 867485be12
commit 56ccd793ac
6 changed files with 110 additions and 110 deletions

View file

@ -1,5 +1,8 @@
add : Int ; add : Int ;
add = 5; add = 4;
main : Int ; main : Int ;
main = add ; main = case add of {
5 => 0;
_ => 1;
};

View file

@ -14,10 +14,13 @@ import Control.Monad (when)
import Data.List.Extra (isSuffixOf) import Data.List.Extra (isSuffixOf)
import Renamer.Renamer (rename) import Renamer.Renamer (rename)
import System.Directory (createDirectory, doesPathExist, import System.Directory (
createDirectory,
doesPathExist,
getDirectoryContents, getDirectoryContents,
removeDirectoryRecursive, removeDirectoryRecursive,
setCurrentDirectory) setCurrentDirectory,
)
import System.Environment (getArgs) import System.Environment (getArgs)
import System.Exit (exitFailure, exitSuccess) import System.Exit (exitFailure, exitSuccess)
import System.IO (stderr) import System.IO (stderr)
@ -59,7 +62,7 @@ main' debug s = do
when check (removeDirectoryRecursive "output") when check (removeDirectoryRecursive "output")
createDirectory "output" createDirectory "output"
writeFile "output/llvm.ll" compiled writeFile "output/llvm.ll" compiled
if debug then debugDotViz else putStrLn compiled -- if debug then debugDotViz else putStrLn compiled
-- interpred <- fromInterpreterErr $ interpret lifted -- interpred <- fromInterpreterErr $ interpret lifted
-- putStrLn "\n-- interpret" -- putStrLn "\n-- interpret"

View file

@ -1,4 +1,5 @@
{-# LANGUAGE LambdaCase #-} {-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Monomorphizer.Monomorphizer (monomorphize) where module Monomorphizer.Monomorphizer (monomorphize) where
@ -6,9 +7,9 @@ import Data.Coerce (coerce)
import Grammar.Abs (Constructor (..), Ident (..)) import Grammar.Abs (Constructor (..), Ident (..))
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
import qualified Grammar.Abs as GA import Grammar.Abs qualified as GA
import qualified Monomorphizer.MonomorphizerIr as M import Monomorphizer.MonomorphizerIr qualified as M
import qualified TypeChecker.TypeCheckerIr as T import TypeChecker.TypeCheckerIr qualified as T
monomorphize :: T.Program -> M.Program monomorphize :: T.Program -> M.Program
monomorphize (T.Program ds) = M.Program $ monoDefs ds monomorphize (T.Program ds) = M.Program $ monoDefs ds
@ -35,7 +36,7 @@ monoExpr = \case
monoAbsType :: GA.Type -> M.Type monoAbsType :: GA.Type -> M.Type
monoAbsType (GA.TLit u) = M.TLit (coerce u) monoAbsType (GA.TLit u) = M.TLit (coerce u)
monoAbsType (GA.TVar _v) = error "NOT POLYMORHPIC TYPES" monoAbsType (GA.TVar _v) = M.TLit "Int"
monoAbsType (GA.TAll _v _t) = error "NOT ALL TYPES" monoAbsType (GA.TAll _v _t) = error "NOT ALL TYPES"
monoAbsType (GA.TEVar _v) = error "I DONT KNOW WHAT THIS IS" monoAbsType (GA.TEVar _v) = error "I DONT KNOW WHAT THIS IS"
monoAbsType (GA.TFun t1 t2) = M.TFun (monoAbsType t1) (monoAbsType t2) monoAbsType (GA.TFun t1 t2) = M.TFun (monoAbsType t1) (monoAbsType t2)
@ -43,7 +44,7 @@ monoAbsType (GA.TData _ _) = error "NOT INDEXED TYPES"
monoType :: T.Type -> M.Type monoType :: T.Type -> M.Type
monoType (T.TAll _ t) = monoType t monoType (T.TAll _ t) = monoType t
monoType (T.TVar (T.MkTVar i)) = error "NOT POLYMORPHIC TYPES" monoType (T.TVar (T.MkTVar i)) = M.TLit "Int"
monoType (T.TLit (T.Ident i)) = M.TLit (Ident i) monoType (T.TLit (T.Ident i)) = M.TLit (Ident i)
monoType (T.TFun t1 t2) = M.TFun (monoType t1) (monoType t2) monoType (T.TFun t1 t2) = M.TFun (monoType t1) (monoType t2)
monoType (T.TData _ _) = error "Not sure what this is" monoType (T.TData _ _) = error "Not sure what this is"

View file

@ -117,36 +117,22 @@ checkPrg (Program bs) = do
(DSig _) -> checkDef xs (DSig _) -> checkDef xs
checkBind :: Bind -> Infer T.Bind checkBind :: Bind -> Infer T.Bind
checkBind (Bind name args e) = do checkBind err@(Bind name args e) = do
let lambda = makeLambda e (reverse (coerce args)) let lambda = makeLambda e (reverse (coerce args))
(_, lambdaT) <- inferExp lambda (_, lambdaT) <- inferExp lambda
args <- zip args <$> mapM (const fresh) args args <- zip args <$> mapM (const fresh) args
withBindings (map coerce args) $ do withBindings (map coerce args) $ do
e@(_, _) <- inferExp e e@(_, _) <- inferExp e
s <- gets sigs s <- gets sigs
-- let fs = map (second Just) (getFunctionTypes s e)
-- mapM_ (uncurry insertSig) fs
case M.lookup (coerce name) s of case M.lookup (coerce name) s of
Just (Just t) -> do Just (Just t) -> do
sub <- unify t lambdaT sub <- bindErr (unify t lambdaT) err
let newT = apply sub t let newT = apply sub t
insertSig (coerce name) (Just newT) insertSig (coerce name) (Just newT)
return $ T.Bind (coerce name, newT) (map coerce args) e return $ T.Bind (coerce name, newT) (map coerce args) e
_ -> do _ -> do
insertSig (coerce name) (Just lambdaT) insertSig (coerce name) (Just lambdaT)
return (T.Bind (coerce name, lambdaT) (map coerce args) e) -- (apply s e) return (T.Bind (coerce name, lambdaT) (map coerce args) e) -- (apply s e)
-- where
-- getFunctionTypes :: Map T.Ident (Maybe T.Type) -> T.ExpT -> [(T.Ident, T.Type)]
-- getFunctionTypes s = \case
-- (T.EId b, t) -> case M.lookup b s of
-- Just Nothing -> return (b, t)
-- _ -> []
-- (T.ELit _, _) -> []
-- (T.ELet (T.Bind _ _ e1) e2, _) -> getFunctionTypes s e1 <> getFunctionTypes s e2
-- (T.EApp e1 e2, _) -> getFunctionTypes s e1 <> getFunctionTypes s e2
-- (T.EAdd e1 e2, _) -> getFunctionTypes s e1 <> getFunctionTypes s e2
-- (T.EAbs _ e, _) -> getFunctionTypes s e
-- (T.ECase e injs, _) -> getFunctionTypes s e <> concatMap (getFunctionTypes s . \(T.Inj _ e) -> e) injs
isMoreSpecificOrEq :: T.Type -> T.Type -> Bool isMoreSpecificOrEq :: T.Type -> T.Type -> Bool
isMoreSpecificOrEq _ (T.TAll _ _) = True isMoreSpecificOrEq _ (T.TAll _ _) = True
@ -292,9 +278,9 @@ algoW = \case
err@(EApp e0 e1) -> do err@(EApp e0 e1) -> do
fr <- fresh fr <- fresh
(s0, (e0', t0)) <- exprErr (algoW e0) err (s0, (e0', t0)) <- algoW e0
applySt s0 $ do applySt s0 $ do
(s1, (e1', t1)) <- exprErr (algoW e1) err (s1, (e1', t1)) <- algoW e1
s2 <- exprErr (unify (apply s1 t0) (T.TFun t1 fr)) err s2 <- exprErr (unify (apply s1 t0) (T.TFun t1 fr)) err
let t = apply s2 fr let t = apply s2 fr
let comp = s2 `compose` s1 `compose` s0 let comp = s2 `compose` s1 `compose` s0
@ -307,7 +293,7 @@ algoW = \case
-- The bar over S₀ and Γ means "generalize" -- The bar over S₀ and Γ means "generalize"
err@(ELet b@(Bind name args e) e1) -> do err@(ELet b@(Bind name args e) e1) -> do
(s1, (_, t0)) <- exprErr (algoW (makeLambda e (coerce args))) err (s1, (_, t0)) <- algoW (makeLambda e (coerce args))
bind' <- exprErr (checkBind b) err bind' <- exprErr (checkBind b) err
env <- asks vars env <- asks vars
let t' = generalize (apply s1 env) t0 let t' = generalize (apply s1 env) t0
@ -322,7 +308,7 @@ algoW = \case
(subst, injs, ret_t) <- checkCase t injs (subst, injs, ret_t) <- checkCase t injs
let comp = subst `compose` sub let comp = subst `compose` sub
let t' = apply comp ret_t let t' = apply comp ret_t
return (comp, (T.ECase (e', t) injs, t')) return (comp, apply comp (T.ECase (e', t) injs, t'))
makeLambda :: Exp -> [T.Ident] -> Exp makeLambda :: Exp -> [T.Ident] -> Exp
makeLambda = foldl (flip (EAbs . coerce)) makeLambda = foldl (flip (EAbs . coerce))
@ -424,13 +410,14 @@ compose m1 m2 = M.map (apply m1) m2 `M.union` m1
-- and one for applying substitutions -- and one for applying substitutions
-- | A class representing free variables functions -- | A class representing free variables functions
class SubstType t where
-- | Apply a substitution to t
apply :: Subst -> t -> t
class FreeVars t where class FreeVars t where
-- | Get all free variables from t -- | Get all free variables from t
free :: t -> Set T.Ident free :: t -> Set T.Ident
-- | Apply a substitution to t
apply :: Subst -> t -> t
instance FreeVars T.Type where instance FreeVars T.Type where
free :: T.Type -> Set T.Ident free :: T.Type -> Set T.Ident
free (T.TVar (T.MkTVar a)) = S.singleton a free (T.TVar (T.MkTVar a)) = S.singleton a
@ -441,6 +428,7 @@ instance FreeVars T.Type where
free (T.TData _ a) = free (T.TData _ a) =
foldl' (\acc x -> free x `S.union` acc) S.empty a foldl' (\acc x -> free x `S.union` acc) S.empty a
instance SubstType T.Type where
apply :: Subst -> T.Type -> T.Type apply :: Subst -> T.Type -> T.Type
apply sub t = do apply sub t = do
case t of case t of
@ -453,16 +441,15 @@ instance FreeVars T.Type where
Just _ -> apply sub t Just _ -> apply sub t
T.TFun a b -> T.TFun (apply sub a) (apply sub b) T.TFun a b -> T.TFun (apply sub a) (apply sub b)
T.TData name a -> T.TData name (map (apply sub) a) T.TData name a -> T.TData name (map (apply sub) a)
instance FreeVars (Map T.Ident T.Type) where instance FreeVars (Map T.Ident T.Type) where
free :: Map T.Ident T.Type -> Set T.Ident free :: Map T.Ident T.Type -> Set T.Ident
free m = foldl' S.union S.empty (map free $ M.elems m) free m = foldl' S.union S.empty (map free $ M.elems m)
instance SubstType (Map T.Ident T.Type) where
apply :: Subst -> Map T.Ident T.Type -> Map T.Ident T.Type apply :: Subst -> Map T.Ident T.Type -> Map T.Ident T.Type
apply s = M.map (apply s) apply s = M.map (apply s)
instance FreeVars T.ExpT where instance SubstType T.ExpT where
free :: T.ExpT -> Set T.Ident
free = error "free not implemented for T.Exp"
apply :: Subst -> T.ExpT -> T.ExpT apply :: Subst -> T.ExpT -> T.ExpT
apply s = \case apply s = \case
(T.EId i, outerT) -> (T.EId i, apply s outerT) (T.EId i, outerT) -> (T.EId i, apply s outerT)
@ -476,17 +463,22 @@ instance FreeVars T.ExpT where
(T.EApp e1 e2, t) -> (T.EApp (apply s e1) (apply s e2), apply s t) (T.EApp e1 e2, t) -> (T.EApp (apply s e1) (apply s e2), apply s t)
(T.EAdd e1 e2, t) -> (T.EAdd (apply s e1) (apply s e2), apply s t) (T.EAdd e1 e2, t) -> (T.EAdd (apply s e1) (apply s e2), apply s t)
(T.EAbs ident e, t1) -> (T.EAbs ident (apply s e), apply s t1) (T.EAbs ident e, t1) -> (T.EAbs ident (apply s e), apply s t1)
(T.ECase e injs, t) -> (T.ECase (apply s e) (apply s injs), apply s t) (T.ECase e brnch, t) -> (T.ECase (apply s e) (apply s brnch), apply s t)
instance FreeVars T.Branch where instance SubstType T.Branch where
free :: T.Branch -> Set T.Ident
free = undefined
apply :: Subst -> T.Branch -> T.Branch apply :: Subst -> T.Branch -> T.Branch
apply s (T.Branch (i, t) e) = T.Branch (i, apply s t) (apply s e) apply s (T.Branch (i, t) e) = T.Branch (apply s i, apply s t) (apply s e)
instance FreeVars [T.Branch] where instance SubstType T.Pattern where
free :: [T.Branch] -> Set T.Ident apply :: Subst -> T.Pattern -> T.Pattern
free = foldl' (\acc x -> free x `S.union` acc) mempty apply s = \case
T.PVar (iden, t) -> T.PVar (iden, apply s t)
T.PLit (lit, t) -> T.PLit (lit, apply s t)
T.PInj i ps -> T.PInj i $ apply s ps
T.PCatch -> T.PCatch
T.PEnum i -> T.PEnum i
instance SubstType a => SubstType [a] where
apply s = map (apply s) apply s = map (apply s)
-- | Apply substitutions to the environment. -- | Apply substitutions to the environment.
@ -552,8 +544,6 @@ inferBranch (Branch pat expr) = do
newExp@(_, exprT) <- withPattern pat (inferExp expr) newExp@(_, exprT) <- withPattern pat (inferExp expr)
return (branchT, T.Branch newPat newExp, exprT) return (branchT, T.Branch newPat newExp, exprT)
-- return (initT, T.Branch (it, initT) (e, exprT), exprT)
withPattern :: T.Pattern -> Infer a -> Infer a withPattern :: T.Pattern -> Infer a -> Infer a
withPattern p ma = case p of withPattern p ma = case p of
T.PVar (x, t) -> withBinding x t ma T.PVar (x, t) -> withBinding x t ma
@ -608,3 +598,7 @@ partitionType = go []
exprErr :: Infer a -> Exp -> Infer a exprErr :: Infer a -> Exp -> Infer a
exprErr ma exp = exprErr ma exp =
catchError ma (\x -> throwError $ x <> " on expression: " <> printTree exp) catchError ma (\x -> throwError $ x <> " on expression: " <> printTree exp)
bindErr :: Infer a -> Bind -> Infer a
bindErr ma exp =
catchError ma (\x -> throwError $ x <> " on expression: " <> printTree exp)

View file

@ -214,6 +214,7 @@ instance Print Pattern where
PLit (lit, typ) -> prPrec i 0 (concatD [doc $ showString "(", prt 0 lit, doc $ showString ",", prt 0 typ, doc $ showString ")"]) PLit (lit, typ) -> prPrec i 0 (concatD [doc $ showString "(", prt 0 lit, doc $ showString ",", prt 0 typ, doc $ showString ")"])
PInj uident patterns -> prPrec i 0 (concatD [prt 0 uident, prt 0 patterns]) PInj uident patterns -> prPrec i 0 (concatD [prt 0 uident, prt 0 patterns])
PCatch -> prPrec i 0 (concatD [doc (showString "_")]) PCatch -> prPrec i 0 (concatD [doc (showString "_")])
PEnum p -> prt i p
instance Print [Branch] where instance Print [Branch] where
prt _ [] = concatD [] prt _ [] = concatD []

View file

@ -3,41 +3,39 @@ data List (a) where {
Cons : a -> List (a) -> List (a) Cons : a -> List (a) -> List (a)
}; };
data Bool () where { -- data Bool () where {
True : Bool () -- True : Bool ()
False : Bool () -- False : Bool ()
-- };
-- hello_world = Cons 'h' (Cons 'e' (Cons 'l' (Cons 'l' (Cons 'o' (Cons ' ' (Cons 'w' (Cons 'o' (Cons 'r' (Cons 'l' (Cons 'd' Nil)))))))))) ;
-- length : List (a) -> Int ;
-- length xs = case xs of {
-- Nil => 0;
-- Cons x xs => length xs;
-- };
-- head : List (a) -> a ;
-- head xs = case xs of {
-- Cons x xs => x;
-- };
-- firstIsOne : List (Int) -> Bool () ;
-- firstIsOne xs = case xs of {
-- Cons x xs => case x of {
-- 0 => True;
-- _ => case xs of {
-- Cons x xs => False;
-- _ => False;
-- };
-- };
-- _ => False;
-- };
-- main = firstIsOne (Cons 1 Nil);
test xs = case xs of {
1 => 0;
lol => 1;
}; };
hello_world = Cons 'h' (Cons 'e' (Cons 'l' (Cons 'l' (Cons 'o' (Cons ' ' (Cons 'w' (Cons 'o' (Cons 'r' (Cons 'l' (Cons 'd' Nil)))))))))) ;
length : List (a) -> Int ;
length xs = case xs of {
Nil => 0;
Cons x xs => length xs;
};
head : List (a) -> a ;
head xs = case xs of {
Cons x xs => x;
};
firstIsOne : List (Int) -> Bool () ;
firstIsOne xs = case xs of {
Cons x xs => case x of {
0 => True;
_ => case xs of {
Cons x xs => False;
_ => False;
};
};
_ => False;
};
main = firstIsOne (Cons 1 Nil);
deepPat xs = case xs of {
Cons (Nil) _ => True;
_ => False;
};