Refactored. Cleaner version, ala Martin version

This commit is contained in:
sebastianselander 2023-02-15 19:52:52 +01:00
parent b03df17e34
commit f1b77a7efa
4 changed files with 33 additions and 60 deletions

View file

@ -24,7 +24,6 @@ main = getArgs >>= \case
putStrLn " ----- PARSER ----- " putStrLn " ----- PARSER ----- "
putStrLn "" putStrLn ""
putStrLn . printTree $ prg putStrLn . printTree $ prg
putStrLn . show $ prg
case rename prg of case rename prg of
Left err -> do Left err -> do
putStrLn "FAILED RENAMING" putStrLn "FAILED RENAMING"

View file

@ -45,6 +45,7 @@ instance Print RBind where
[ prt 0 x [ prt 0 x
, doc (showString "=") , doc (showString "=")
, prt 0 e , prt 0 e
, doc (showString "\n")
] ]
instance Print RExp where instance Print RExp where
@ -55,4 +56,4 @@ instance Print RExp where
RConst n -> prPrec i 3 (concatD [prt 0 n]) RConst n -> prPrec i 3 (concatD [prt 0 n])
RApp e e1 -> prPrec i 2 (concatD [prt 2 e, prt 3 e1]) RApp e e1 -> prPrec i 2 (concatD [prt 2 e, prt 3 e1])
RAdd e e1 -> prPrec i 1 (concatD [prt 1 e, doc (showString "+"), prt 2 e1]) RAdd e e1 -> prPrec i 1 (concatD [prt 1 e, doc (showString "+"), prt 2 e1])
RAbs u id e -> prPrec i 0 (concatD [doc (showString "\\"), prt 0 ("var" ++ show u), doc (showString "."), prt 0 e]) RAbs u id e -> prPrec i 0 (concatD [doc (showString "λ"), prt 0 ("var" ++ show u), doc (showString "."), prt 0 e])

View file

@ -47,97 +47,60 @@ inferPrg (RProgram xs) = do
inferBind :: RBind -> Infer TBind inferBind :: RBind -> Infer TBind
inferBind (RBind name e) = do inferBind (RBind name e) = do
t <- inferExp e (t, e') <- inferExp e
e' <- toTExpr e
insertSigs name t insertSigs name t
return $ TBind name t e' return $ TBind name t e'
-- This needs to be fixed. Should not separate inference of type and creation of the new data type.
toTExpr :: RExp -> Infer TExp
toTExpr = \case
re@(RAnn e t) -> do inferExp :: RExp -> Infer (Type, TExp)
t <- inferExp re
e' <- toTExpr e
return $ TAnn e' t
re@(RBound num name) -> do
t <- inferExp re
return $ TBound num name t
re@(RFree name) -> do
t <- inferExp re
return $ TFree name t
re@(RConst con)-> do
t <- inferExp re
return $ TConst con t
re@(RApp e1 e2) -> do
t <- inferExp re
e1' <- toTExpr e1
e2' <- toTExpr e2
return $ TApp e1' e2' t
re@(RAdd e1 e2)-> do
t <- inferExp re
e1' <- toTExpr e1
e2' <- toTExpr e2
return $ TAdd e1' e2' t
re@(RAbs num name e) -> do
t <- inferExp re
e' <- toTExpr e
return $ TAbs num name e' t
inferExp :: RExp -> Infer Type
inferExp = \case inferExp = \case
RAnn expr typ -> do RAnn expr typ -> do
exprT <- inferExp expr (t,expr') <- inferExp expr
when (not (exprT == typ || isPoly exprT)) (throwError $ AnnotatedMismatch "inferExp, RAnn") when (not (t == typ || isPoly t)) (throwError $ AnnotatedMismatch "inferExp, RAnn")
return typ return (typ,expr')
-- Name is only here for proper error messages -- Name is only here for proper error messages
RBound num name -> RBound num name ->
M.lookup num <$> St.gets vars >>= \case M.lookup num <$> St.gets vars >>= \case
Nothing -> throwError $ UnboundVar "RBound" Nothing -> throwError $ UnboundVar "RBound"
Just t -> return t Just t -> return (t, TBound num name t)
RFree name -> do RFree name -> do
M.lookup name <$> St.gets sigs >>= \case M.lookup name <$> St.gets sigs >>= \case
Nothing -> throwError $ UnboundVar "RFree" Nothing -> throwError $ UnboundVar "RFree"
Just t -> return t Just t -> return (t, TFree name t)
RConst (CInt _) -> return $ TMono "Int" RConst (CInt i) -> return $ (TMono "Int", TConst (CInt i) (TMono "Int"))
RConst (CStr _) -> return $ TMono "Str" RConst (CStr str) -> return $ (TMono "Str", TConst (CStr str) (TMono "Str"))
-- Should do proper unification using union-find. Some nice libs exist -- Should do proper unification using union-find. Some nice libs exist
RApp expr1 expr2 -> do RApp expr1 expr2 -> do
typ1 <- inferExp expr1 (typ1, expr1') <- inferExp expr1
typ2 <- inferExp expr2 (typ2, expr2') <- inferExp expr2
cnt <- incCount cnt <- incCount
case typ1 of case typ1 of
(TPoly (Ident x)) -> do (TPoly (Ident x)) -> do
let newType = (TArrow (TPoly (Ident x)) (TPoly . Ident $ x ++ (show cnt))) let newType = (TArrow (TPoly (Ident x)) (TPoly . Ident $ x ++ (show cnt)))
specifyType expr1 newType specifyType expr1 newType
apply newType typ1 typ1' <- apply newType typ1
_ -> apply typ2 typ1 return $ (typ1', TApp expr1' expr2' typ1')
_ -> (\t -> (t, TApp expr1' expr2' t)) <$> apply typ2 typ1
RAdd expr1 expr2 -> do RAdd expr1 expr2 -> do
typ1 <- inferExp expr1 (typ1, expr1') <- inferExp expr1
typ2 <- inferExp expr2 (typ2, expr2') <- inferExp expr2
when (not $ (isInt typ1 || isPoly typ1) && (isInt typ2 || isPoly typ2)) (throwError $ TypeMismatch "inferExp, RAdd") when (not $ (isInt typ1 || isPoly typ1) && (isInt typ2 || isPoly typ2)) (throwError $ TypeMismatch "inferExp, RAdd")
specifyType expr1 (TMono "Int") specifyType expr1 (TMono "Int")
specifyType expr2 (TMono "Int") specifyType expr2 (TMono "Int")
return (TMono "Int") return (TMono "Int", TAdd expr1' expr2' (TMono "Int"))
RAbs num name expr -> do RAbs num name expr -> do
insertVars num (TPoly "a") insertVars num (TPoly "a")
typ <- inferExp expr (typ, expr') <- inferExp expr
newTyp <- lookupVars num newTyp <- lookupVars num
return $ TArrow newTyp typ return $ (TArrow newTyp typ, TAbs num name expr' typ)
-- Aux -- Aux
isInt :: Type -> Bool isInt :: Type -> Bool
@ -196,6 +159,8 @@ union = todo
find :: Type -> Type find :: Type -> Type
find = todo find = todo
-- Have to figure out the equivalence classes for types.
-- Currently this does not support more than exact matches.
apply :: Type -> Type -> Infer Type apply :: Type -> Type -> Infer Type
apply (TArrow t1 t2) t3 apply (TArrow t1 t2) t3
| t1 == t3 = return t2 | t1 == t3 = return t2
@ -222,4 +187,12 @@ lambda2 = RAbs 0 "x" (RAnn (RBound 0 "x") (TArrow (TMono "Int") (TMono "String")
fn_on_var = RAbs 0 (Ident "f") (RAbs 1 (Ident "x") (RApp (RBound 0 (Ident "f")) (RBound 1 (Ident "x")))) fn_on_var = RAbs 0 (Ident "f") (RAbs 1 (Ident "x") (RApp (RBound 0 (Ident "f")) (RBound 1 (Ident "x"))))
bind = RBind "test" fn_on_var
--add x = \y. x+y;
add = RAbs 0 "x" (RAbs 1 "y" (RAdd (RBound 0 "x") (RBound 1 "y")))
-- main = (\z. z+z) ((add 4) 6);
main = RApp (RAbs 0 "z" (RAdd (RBound 0 "z") (RBound 0 "z"))) applyAdd
four = RConst (CInt 4)
six = RConst (CInt 6)
applyAdd = (RApp (RApp add four) six)
partialAdd = RApp add four

View file

@ -62,7 +62,7 @@ instance Print TExp where
TAdd e e1 t -> prPrec i 1 $ concatD [ prt 1 e , doc (showString "+") , prt 2 e1 ] TAdd e e1 t -> prPrec i 1 $ concatD [ prt 1 e , doc (showString "+") , prt 2 e1 ]
TAbs _ u e t -> prPrec i 0 $ concatD TAbs _ u e t -> prPrec i 0 $ concatD
[ doc (showString "(") [ doc (showString "(")
, doc (showString "\\") , doc (showString "λ")
, prt 0 u , prt 0 u
, doc (showString ".") , doc (showString ".")
, prt 0 e , prt 0 e