- FunDecl p f args (Just ftype) newvds newstmts)
- Just t = restoreGamma gamma
- >>| pure (FunDecl p f args mt newvds newstmts)
+ FunDecl p f args (Just ftype) newvds newstmts)
+ Just t = restoreGamma gamma >>| updateFunType t returntype
+ >>= \tt-> pure (FunDecl p f args (Just tt) newvds newstmts)
+
+recoverType :: Type -> Env Type
+recoverType (IdType ident) = gets (\(st, r)->'Map'.get ident st)
+ >>= \mt->case mt of
+ Nothing = pure (IdType ident)
+ Just t = pure t
+recoverType (t1 ->> t2) = recoverType t1 >>= \t1`->recoverType t2
+ >>= \t2`->pure (t1` ->> t2`)
+recoverType t = pure t
+
+updateFunType :: Type Type -> Env Type
+updateFunType (t1 ->> t2) t3 = updateFunType t2 t3 >>= \t2`->pure $ t1 ->> t2`
+updateFunType t1 t2 = unify t1 t2
+
+inferReturnType :: [Stmt] -> Env Type
+inferReturnType [] = pure VoidType
+inferReturnType [ReturnStmt (Just t):rest] = typeExpr t
+ >>= \tx->inferReturnType rest >>= \ty->unify tx ty
+inferReturnType [ReturnStmt _:rest] =
+ inferReturnType rest >>= \tx-> unify VoidType tx
+inferReturnType [_:rest] = inferReturnType rest