Refactored. Cleaner version, ala Martin version
This commit is contained in:
parent
b03df17e34
commit
f1b77a7efa
4 changed files with 33 additions and 60 deletions
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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])
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue